函数中双精度差的意外结果 我尝试用C++实现特征脸算法。我已经做了数据库创建部分,现在我正在设置识别部分

函数中双精度差的意外结果 我尝试用C++实现特征脸算法。我已经做了数据库创建部分,现在我正在设置识别部分,c++,function,arguments,double,subtraction,C++,Function,Arguments,Double,Subtraction,唯一的问题是,即使所有变量都正确地从文件“prova.txt”中读取,一旦它们被传递给函数,就会发生一些奇怪的事情:整个imd数组包含与预期值不同的值(我在Matlab中运行相同的算法以供参考) 我是Python程序员,所以我知道这可能是一个愚蠢的C++用户,但我找不到代码中的错误(可能不是很好的优化,并充满冗余BTW)。我在代码后面贴了一个链接到“prova.txt” U和omega是矩阵,我对它们进行了线性化,以便能够将它们作为函数的输入参数传递 #include <iostream&

唯一的问题是,即使所有变量都正确地从文件
“prova.txt”
中读取,一旦它们被传递给函数,就会发生一些奇怪的事情:整个
imd
数组包含与预期值不同的值(我在Matlab中运行相同的算法以供参考)

我是Python程序员,所以我知道这可能是一个愚蠢的C++用户,但我找不到代码中的错误(可能不是很好的优化,并充满冗余BTW)。我在代码后面贴了一个链接到

“prova.txt”

U
omega
是矩阵,我对它们进行了线性化,以便能够将它们作为函数的输入参数传递

#include <iostream>
#include <cmath>
#include <fstream.h>
#include <cstdlib>

using namespace std;

int confrontodb(double*, double, double, double*, double*, double*);

int confrontodb(double* test, double H, double M, double* m, double* U,
                double* omega) {
  int Urows = M;
  int Ulines = H;
  double om[Urows];
  double imd[Ulines];
  double d[Urows][Urows];
  double dist[Urows];
  double accum;
  double minimo;
  int ind = 0;

  // subtract average "med" from test sample "test"
  for (int i = 0; i < Ulines; i++) {
    imd[i] = test[i] - m[i];
  }
  // Project "imd" on the U eigenspace (om = U'*imd)
  for (int i = 0; i < Urows; i++) {
    for (int j = 0; j < Ulines; j++) {
      om[i] += U[Urows * j + i] * imd[j];
    };
  };

  // Generate a matrix in which each column is a copy of om
  for (int i = 0; i < Urows; i++) {
    for (int j = 0; j < Urows; j++) {
      d[i][j] = om[i];
    };
  };

  // subtract omega from d
  for (int i = 0; i < Urows; i++) {
    for (int j = 0; j < Urows; j++) {
      d[i][j] = d[i][j] - omega[i * Urows + j];
    };
  };

  // norm each column of d
  for (int i = 0; i < Urows; i++) {
    accum = 0;
    for (int j = 0; j < Urows; j++) {
      accum += d[i][j] * d[i][j];
    };
    dist[i] = sqrt(accum);
  };

  // look for minimum and maximum distance
  minimo = dist[0];
  double massimo = dist[0];
  for (int i = 0; i < Urows; i++) {
    if (dist[i] < minimo) {
      ind = i;
      minimo = dist[i];
    } else if (dist[i] > massimo) {
      massimo = dist[i];
    };
  };

  cout << "minimo " << minimo << endl;
  cout << "massimo " << massimo << endl;
  return ind;
}

int main(int argc, char* argv[]) {
  ifstream f;
  f.open("prova.txt");
  double* omega;
  omega = (double*)calloc(198 * 198, sizeof(double));
  for (int i = 0; i < 198 * 198; i++) {
    f >> omega[i];
  };
  for (int i = 0; i < 198; i++) {
    for (int j = 0; j < 198; j++) {
      cout << "   " << omega[i * 198 + j];
    }
    cout << endl;
  }

  double* U;
  U = (double*)calloc(4001 * 198, sizeof(double));
  // float U[4001*198];

  for (int i = 0; i < 4001 * 198; i++) {
    f >> U[i];
  };

  double* med;
  med = (double*)calloc(4001, sizeof(double));
  for (int i = 0; i < 4001; i++) {
    f >> med[i];
  };

  double* test;
  test = (double*)calloc(4001, sizeof(double));
  for (int i = 0; i < 4001; i++) {
    f >> test[i];
  };

  f.close();
  cout << "etichetta riconosciuta "
       << confrontodb(test, 4001, 198, med, U, omega) << endl;
  free(med);
  free(test);
  free(U);
  free(omega);
  return 0;
}

对于实际代码,第一个
imd
元素是正确的,第二个元素有1/1000的错误,然后一切都是随机的,因此,这些元素应该足以检查。)

您是否尝试在调试器中运行代码并跟踪值,以查看是否计算了错误的值?这样计算总和往往非常不准确,因为在最后,您将一个非常小的数字添加到一个非常大的数字中。我建议只使用than
double
。计算值是错误的,还是略有不同?数据类型
double
是一种定价类型,使用不同的语言或硬件可能会产生稍有不同的结果。某些数字即使在最重要的数字上也是错误的。您是否尝试在调试器中运行代码并跟踪值,以查看何时计算错误的值?以这种方式计算总和往往非常困难不准确,因为在接近结尾时,您将在一个大得多的数字上添加一个非常小的数字。我建议只使用than
double
。计算值是错误的,还是略有不同?数据类型
double
是一种价格类型,使用不同的语言或硬件可能会产生稍有不同的结果。有些数字甚至在最高有效位上也是错误的
imdmatlab = 
  -2.5252525e-01
  -1.3080808e+00
  -1.8080808e+00
  -2.7676768e+00
  -4.1161616e+00
  -3.1969697e+00
  -2.5707071e+00
  -2.6616162e+00
  -3.1616162e+00
  -2.3181818e+00
  -2.1767677e+00
  [...]