函数中双精度差的意外结果 我尝试用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的错误,然后一切都是随机的,因此,这些元素应该足以检查。)您是否尝试在调试器中运行代码并跟踪值,以查看是否计算了错误的值?这样计算总和往往非常不准确,因为在最后,您将一个非常小的数字添加到一个非常大的数字中。我建议只使用thandouble
。计算值是错误的,还是略有不同?数据类型double
是一种定价类型,使用不同的语言或硬件可能会产生稍有不同的结果。某些数字即使在最重要的数字上也是错误的。您是否尝试在调试器中运行代码并跟踪值,以查看何时计算错误的值?以这种方式计算总和往往非常困难不准确,因为在接近结尾时,您将在一个大得多的数字上添加一个非常小的数字。我建议只使用thandouble
。计算值是错误的,还是略有不同?数据类型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
[...]