在函数中减去double的意外结果

时间:2015-09-30 09:14:01

标签: c++ function arguments double subtraction

我试图在C ++中实现特征脸算法。我已经创建了数据库创建部分,现在我正在设置识别部分。

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

我是python程序员,所以我知道这对C ++用户来说可能是愚蠢的,但是我的代码中找不到错误(可能没有很好地优化并且充满了冗余btw )。我在代码后发布了"prova.txt"的链接。

Uomega是矩阵,我将其线性化,以便能够将它们作为函数的输入参数传递。

#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;
}

Link to "prova.txt" (it's 13 megabytes)

预期结果:

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
  [...]

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

0 个答案:

没有答案