【问题标题】:How to properly compare results between matlab/octave and C++如何正确比较 matlab/octave 和 C++ 之间的结果
【发布时间】:2014-07-16 05:30:28
【问题描述】:

我正在将一些在 Matlab/Octave 中可用的代码写入 C++ 代码。我只有八度,所以从现在开始我只会说八度。 我想正确比较八度音程代码和 C++ 代码之间的结果。我正在编写的算法将 2D 矩阵作为输入,并输出另一个 2D 矩阵。

为了比较结果,我使用函数save A.mat A 从八度音阶写入输入矩阵A,并带有默认选项。这将创建一个 ascii 文件 A.mat,其开头类似于

# Created by Octave 3.8.1, Tue May 27 12:12:53 2014 CEST <remi@desktop>
# name: values
# type: matrix
# rows: 25
# columns: 5 
43.0656 6.752420000000001 68.39323 35.75617 98.85446
...

我使用 octave 运行算法,并同样保存输出矩阵 B

在我的 C++ 代码中,我使用以下代码加载矩阵 A 和 B:

// I opened the file A.mat with std::ifstream infile(filename);
// and read the first lines starting by # and loaded the matrix dimensions
std::string buffer;
double* matBuffer = new double[rows*cols];
while (std::getline(infile, buffer)) {
  std::istringstream iss(buffer);
  while (iss >> *matBuffer) {
    matBuffer++;
  }
}

然后我使用从 A.mat 读取的值运行 C++ 代码,并通过计算 B 读取与 B 计算的系数上的 mean squared error(MSE) 将结果与从 B.mat 读取的值进行比较。

但是,通过这样的设计,我可以期望 MSE 在 C++ 和 octave 代码之间为 0 吗?当然,我用同一台机器在 octave 和 C++ 上进行计算。但是由于在文件中写入/读取矩阵而导致的精度损失呢?另外,我假设倍频程矩阵的系数默认以双精度存储,这是正确的吗?

【问题讨论】:

  • 你对文件中的丢失是正确的(如果你不把它写成二进制,这在任何语言中都是微不足道的)。您还会有称为“舍入误差”的微小差异:基本上,浮点数学的方式,如果您不以完全相同的顺序执行操作,答案将略有不同。您应该检查双打是否足够接近以至于没有真正的不同(我选择 1e-6 分数差,尽管双打的 episilon 是 2^-52)

标签: c++ matlab comparison octave


【解决方案1】:

我可以期望 C++ 和 octave 代码之间的 MSE 为 0 吗?

我不这么认为,因为转换的层次很多,精度损失是很难避免的。

另外,我假设倍频程矩阵的系数默认存储为双精度,这样对吗?

Octave 使用 double 精度来表示值的内部表示,但在以 ASCII 格式存储值时,精度可能会有所损失。

我建议您尝试使用二进制格式来存储值,这将排除任何精度问题。您可以使用 HDF5 格式使用

save -hdf5 A.mat A

然后您可以使用HDF5 API 读取您的 CPP 应用程序中的值。

【讨论】:

  • 我没有使用带有八度音阶的二进制格式,因为我找不到在 C++ 中读回它的正确方法。 HDF5 很清楚,感谢您指出该解决方案:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-15
  • 2014-03-20
  • 1970-01-01
  • 2012-10-30
  • 1970-01-01
  • 2012-04-26
相关资源
最近更新 更多