【问题标题】:How to know if two methods do the same thing on different representations of the same data如何知道两种方法是否对相同数据的不同表示做同样的事情
【发布时间】:2014-06-28 18:50:12
【问题描述】:

我有两种不同的矩阵表示。

矩阵保存为数组 float*:

| 1.0   2.0   3.0   4.0   5.0   6.0  7.0   8.0   9.0 |

作为数组的数组 float**

| 1.0  2.0  3.0 |
| 4.0  5.0  6.0 |
| 7.0  8.0  9.0 |

我有这种方法可以将矩阵用作数组:

float a(float* x, float* b, int m, int n) {
    int i, j;
    float e = 0, de, yp;

    for (i = 0; i < m; i++) {
        yp = 0;
        for (j = 0; j < n; j++)
            yp += x[i*(n+1)+j] * b[j];
        de = fabs(x[i*(n+1)+n]-yp);
        e += (de*de);
    }
    return e;
}

在我看来,这个应该做同样的事情:

float a(float **x, float **b, int m, int n) {
    int i, j;
    float e = 0, de, yp;

    for (i = 0; i < m; i++) {
        yp = 0;
        for (j = 0; j < n; j++)
            yp += x[i][j] * b[j][0];
        de = fabs(x[i][j]-yp);
        e += (de*de);
    }
    return e;
}

有没有一种聪明的方法来比较这两种方法,而无需尝试编写相同输入的两种不同表示并检查两者的输出是否相同?

注意: fis 方法中的de = fabs(x[i*(n+1)+n]-yp); 行似乎是一个错误,因为我看不到这条线应该做什么......我不是该方法的单维版本的作者,所以我不知道真实的作者的意图,我正在尝试调整代码以处理多维矩阵,因此我将此行解释为de = fabs(x[i*(n+1)+j]-yp);,但我不确定。

【问题讨论】:

  • "没有尝试编写相同输入的 2 个不同表示并检查两者的输出是否相同?" - 为什么你需要任何其他方式?这就是测试功能的方式;给定输入x,输出y 是什么。给他们提供两组数据并比较结果有什么难的?
  • 我相信你很小心你是如何分配内存来让**x按照你想要的方式工作的……你必须创建一个指向二维矩阵每一行中第一个值的指针数组.如果您不知道我在说什么,那么我怀疑您的第二个代码将无法按您的预期工作。您能否展示为x 分配内存的代码,以及如何调用第二个函数?
  • 问题是我必须在至少 10 种方法上多次执行相同的操作。了解如何查看第一个表示中的迭代作为数组数组可以为我节省很多时间。
  • @Floris 分配正确,方法编译并返回我对迭代有疑问的值。 (第一个来自另一个程序,两个例程都在随机值上工作,因为如果我找不到更好的方法来比较两者,我必须多次正确地重写输入)

标签: c arrays matrix


【解决方案1】:

即使您已正确分配内存,您也没有按照您想要的方式索引第一个数组。看看这些行:

for (i = 0; i < m; i++) {
    yp = 0;
    for (j = 0; j < n; j++)
        yp += x[i*(n+1)+j] * b[j];

你希望这是一样的

  for (i = 0; i < m; i++) {
    yp = 0;
    for (j = 0; j < n-1; j++)
        yp += x[i][j] * b[j][0];

但是当你有一个一维数组时,如果每行有 n 个元素,则相当于索引一个二维数组 x[i][j] 是用

 yp += x[i*n + j];

没有+1...

【讨论】:

  • 操作,分心,你是对的......但我的主要疑问是在这一行 de = fabs(x[i*(n+1)+n]-yp); 你认为我的 2D 转换在这里正确吗?
  • 不,我不这么认为。更重要的是 - 一个 j 循环只到 &lt;n-1,另一个到 &lt;n。在一种情况下,您在循环之后使用j 的值,而在另一种情况下,您使用n。那只是自找麻烦。
  • de = fabs(x[i*(n+1)+n]-yp); 行似乎是一个错误,因为我看不到该行应该做什么......(请注意,我不是该方法的单维版本的作者,所以我不知道作者的真正意图,我正在尝试调整代码以使用多维矩阵)。因此我将其解释为de = fabs(x[i*(n+1)+j]-yp);
  • 代码看起来像是一个向量和一个矩阵的乘积 - 但随后做​​了一些奇怪的减法,坦率地说它应该溢出矩阵的末尾(取决于 @987654334 的值@ 和 n 调用第一个代码时)。但我很确定第二个代码与第一个代码不一样。只需在第二次中打印出 ij 的值,每次通过内部循环,并打印一维情况下的索引值 - 你会看到你甚至没有迭代相同的次数。
  • 请注意,您担心的行发生在 j 循环完成后,因此您依赖于循环结束后 j 的值。如果您将j 视为一个真正的局部变量(使用for(int j=0; j&lt;n-1; j++) {,那么当您到达该行时,它甚至不会存在。真的 - 您需要了解代码在做什么你正在适应或者你正在为难以理解的错误设置自己。我真的担心原始代码可能是“错误的”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-05
相关资源
最近更新 更多