c++ 为什么log(inf + inf j)等于(inf + 0.785398 j)?

ldxq2e6h  于 2022-12-15  发布在  其他
关注(0)|答案(2)|浏览(172)

我发现了Clog函数的一个奇怪行为,并且对log函数处理复数无穷数的行为感到困惑。具体来说,当我期望(inf + nan * 1j)时,log(inf + inf * 1j)等于(inf + 0.785398j)
取复数的对数时,真实的部是输入绝对值的对数,虚部是输入的相位。返回0.785398作为log(inf + inf * 1j)的虚部意味着它假设实部和虚部中的inf具有相同的长度。这个假设似乎与其他计算不一致,例如,inf - inf == naninf / inf == nan(假设2 × inf)不必具有相同的值。
为什么log(inf + inf * 1j)的假设不同?
复制C
代码:

#include <complex>
#include <limits>
#include <iostream>
int main() {
    double inf = std::numeric_limits<double>::infinity();
    std::complex<double> b(inf, inf);
    std::complex<double> c = std::log(b);
    std::cout << c << "\n";
}

复制Python代码(numpy):

import numpy as np

a = complex(float('inf'), float('inf'))
print(np.log(a))
sh7euo9m

sh7euo9m1#

free final draft of the C99 specification在第491页上说
clog(+∞,+i∞)返回+∞ + iπ/4。
currently仍然是这种情况。C++ specification使用注解解释了相同的规则
此函数的语义旨在与C函数clog保持一致。
我同意这种行为从数学的Angular 看是令人困惑的,并且可以说与其他inf语义不一致,正如你指出的,但是实际上,它是C标准的一部分,这使得它成为C++标准的一部分,并且由于NumPy通常依赖于C行为(即使在令人困惑的情况下),这在Python示例中是继承的。
标准库cmath.log()函数具有相同的行为(if you test it right...):

>>> import cmath

>>> cmath.log(complex(float('inf'), float('inf')))
(inf+0.7853981633974483j)

我没有办法研究C标准的基本原理,我假设这里有实用的选择,可能是在考虑这些复杂的函数如何相互作用时。

q8l4jmvw

q8l4jmvw2#

值0.785398(实际上是pi/4)至少与 * 一些 * 其他函数一致:正如你所说,复数的对数的虚部等于该数的相角。2这可以转化为一个问题:inf + j * inf的相位角是多少?
我们可以通过atan2(Im(z), Re(z))计算复数z的相位角,对于给定的数字,这可以归结为计算atan2(inf, inf),对于Numpy和C/C++,atan2(inf, inf)也是0.785398(或pi/4),所以现在可以问一个类似的问题:为什么是atan2(inf, inf) = 0.785398
对于后者,我没有答案(除了“C/C++规范是这么说的”,其他人已经回答了),我只有一个猜测:如atan2(y, x) == atan(y / x)x > 0,可能有人在此上下文中决定不将inf / inf解释为“未定义”,而是解释为“一个非常大的数除以同一个非常大的数”。此比率的结果将是1,并且根据atan的数学定义,atan(1) == pi/4atan
也许这不是一个令人满意的答案,但至少我可以有希望地表明,给定边缘情况下的log定义与相关函数定义的类似边缘情况并非完全不一致。

编辑:正如我所说,与 * 一些 * 其他函数一致:例如,它也与np.angle(complex(np.inf, np.inf)) == 0.785398一致。

相关问题