【问题标题】:std::exp giving different result than MATLAB exp for complex number对于复数,std::exp 给出的结果与 MATLAB exp 不同
【发布时间】:2014-04-30 15:50:29
【问题描述】:

我正在将一个脚本从 matlab 复制到一个 c++ 函数中。但是,对于 exp 函数,我不断得到不同的结果。比如下面sn-p:

std::complex<double> final_b = std::exp(std::complex<double>(0, 1 * pi));

应该相当于MATLAB代码

final_b = exp(1i * pi);

但事实并非如此。对于 MATLAB,我得到 -1 + 0i(这是正确的),对于 c++,我得到 -1 + -2.068231e-013*i。

现在我一开始以为这只是某种舍入误差,但对于我正在使用的实际脚本,它具有更大的复指数,我得到的数字完全不同。这是什么原因?我该如何解决这个问题?

编辑:我已经手动尝试使用欧拉公式计算指数

exp(x+iy) = exp(x) * (cos(y) + i*sin(y)) 

在 c++ 中得到同样的奇怪结果

【问题讨论】:

  • 你熟悉浮点精度这个术语吗?
  • @40two 从问题的内容来看,我认为答案是肯定的。
  • 只是一个想法,你检查了 pi 的精度吗?
  • 不能保证 MatLab 和 C++ 以相同的方式计算 exp。因此,可以容忍小的舍入误差。请记住,在后台计算 cossin 等三角函数涉及像 Newton-Raphson 等迭代过程。请说明您遇到的错误量,以便我们更清楚地了解您的问题. P.S 还说明您如何打印这些值。
  • 事实证明你是对的 40two。我一直在读错结果......每当 MATLAB 输出 0 时,C++ 输出的东西非常接近 0。抱歉造成混淆。

标签: c++ matlab complex-numbers exp


【解决方案1】:

这就是所谓的浮点逼近(或不精确):

如果您包含标题cfloat,则有一些定义。特别是DBL_EPSILON,它是1.0 + DBL_EPSILON != 1.0(通常是1e-9)的最小数字(而-2.068231e-013比它小很多。如果您执行以下代码,您可以检查它是否为零:

// The complete formula is std::abs(a - b), but since b is zero, I am ommiting it
if (std::abs(number.imag()) < DBL_EPSILON) {
    // The number is either zero or very close to zero
}

例如,您可以在此处查看工作代码:http://ideone.com/2OzNZm

【讨论】:

  • 只是一个细节的注释:我的 float.h 中的 DBL_EPSILON 是 2.2204460492503131e-016。 Matlab 中的同上...也许您对 FLT_EPSILON 感到困惑,通常约为 1.192092896e-07。除了这个微小的细节,这是一个很好的解释。
  • 只检查数字是否小于 DBL_EPSILON 然后四舍五入到零就足够了吗?
  • @Bentoy13 正确,该值取决于 libc 实现并且可能(我不确定)取决于编译器标志。
  • @BananaCode 其实这是正确的做法。让我修复代码。
  • 嗯,DBL_EPSILON 是与1.0 相加的最小值产生不同的值(即它是double 粒度的度量),它与结果的精度有什么关系三角函数/指数函数?
猜你喜欢
  • 1970-01-01
  • 2018-09-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-18
相关资源
最近更新 更多