这似乎有效:
import numpy as np
def compl_div(A,B):
A,B = np.asarray(A),np.asarray(B)
Ba = np.abs(B)[...,None]
A = (A[...,None].view(float)/Ba).view(complex)[...,0]
B = (B.conj()[...,None].view(float)/Ba).view(complex)[...,0]
return A*B
a = np.random.randn(10000)
b = np.random.randn(10000)
A = a.astype(complex)
B = b.astype(complex)
print((compl_div(A,B)==a/b).all())
print((np.sqrt(b*b)==np.abs(b)).all())
ac = a.view(complex)
bc = b.view(complex)
print(np.allclose(compl_div(ac,bc),ac/bc))
示例运行:
True # complex without imag exactly equal float
True # reason it works
True # for nonzeron imag part do we actually get complex division
解释:
让我们写/// for complex by float 除法(x+iy)///r = x/r + iy/r
numpy 似乎将复杂的除法 A/B 实现为 A*(1/B)(1/B 可以计算为 B.conj()///(B.conj()*B)),实际上 A/B 似乎总是等于 a*(1/b)
我们将 (A///abs(B)) * (B.conj()///abs(B)) 改为 abs(B)^2 = B*B.conj(),这在数学上是等价的,但不是数字上的。
现在,如果我们有 abs(B) == abs(b) 然后是 A///abs(B) = a/abs(b) 和 B///abs(B) = sign(b),我们可以看到 compl_div(A,B) 确实返回了 a/b。
作为abs(x+iy) = sqrt(x^2+y^2),我们需要显示sqrt(b*b) = abs(b)。这是provably true,除非方格中有上溢或下溢,或者方格不正常,或者实现不符合 IEEE。