我正在寻找一种在excel-vba中的一组复数中查找实数的方法。更具体地说,我有一组三个结果,其中一个已知是真实的,两个已知是复杂的,但是,我不知道哪个结果是真实的。由于中间计算步骤中的舍入误差,经常会导致实数的虚部不能抵消到正好为0的事实,这使问题变得更加复杂。
我目前正在考虑使用的方法包括以下步骤:
确定三个组件中每个组件的Real组件的值
结果。
确定每个虚部的绝对值
这三个结果。
确定这三个结果的最小值。
比较每个绝对虚构分量的最小值。什么时候
这些匹配,以相应的实部为最终
结果。
代码如下所示:
Z1 = Application.WorksheetFunction.ImReal ( Application.WorksheetFunction.ImSum (xi1, x1i2, x1i3) )
Z2 = Application.WorksheetFunction.ImReal ( Application.WorksheetFunction.ImSum (xi1, x2i2, x2i3) )
Z3 = Application.WorksheetFunction.ImReal ( Application.WorksheetFunction.ImSum (xi1, x3i2, x3i3) )
ZIm1 = Abs ( Application.WorksheetFunction.Imaginary ( Application.WorksheetFunction.ImSum (xi1, x1i2, x1i3) ) )
ZIm2 = Abs ( Application.WorksheetFunction.Imaginary ( Application.WorksheetFunction.ImSum (xi1, x2i2, x2i3) ) )
ZIm3 = Abs ( Application.WorksheetFunction.Imaginary ( Application.WorksheetFunction.ImSum (xi1, x3i2, x3i3) ) )
ZImMin = Min (ZIm1, ZIm2, ZIm3)
If Zim1 = ZImMin Then
ZImID = Z1
ElseIf Zim2 = ZImMin Then
ZImID = Z2
Else ZImID = Z3
EndIf
我认为这应该可行,但是,我还没有尝试运行它。谁能建议一种更好的方法来找到Real解决方案?
此问题是根据this method查找三次方程的解的一部分:
谢谢!
最佳答案
我不仅会考虑虚部最接近零,而且会考虑实部与虚部之间的关系。例:
z1 = 2,35 + 0,25i
z2 = 14 + 1,3i
实际上z2更接近于实数对此的度量是实部和复杂部分之间的角度。 IMARGUMENT(z)返回该角度。
例:
Public Function realIndex(rng As Range) As Long
' returns the row index into a column of complex values closest to a real number
Dim values() As Variant
Dim angle As Double, minangle As Double, i As Long, idx As Long
values = rng ' complex numbers in values(i,1)
minangle = 100#
For i = LBound(values, 1) To UBound(values, 1)
angle = Application.WorksheetFunction.ImArgument(values(i, 1))
If angle < minangle Then
minangle = angle
idx = i
End If
Next i
realIndex = idx
End Function
根据评论进行编辑:
取abs(sin(angle))可以减小-pi周围的负角的歧义。但是,由于ImArgument本质上是arctan(Im(x)/ Re(x)),并且sin(arctan(x))等效,因此我们可以使用以下代码:
Public Function MostReal(rng As Range) As Double
' returns from a column of complex values the one closest to a real number
Dim values() As Variant
Dim val As Double, minval As Double, absSize As Double, imSize As Double
Dim i As Long, idx As Long
values = rng ' complex numbers in rows = values(i, 1)
For i = 1 To UBound(values, 1)
With Application.WorksheetFunction
absSize = Abs(.Imaginary(values(i, 1)))
imSize = .ImAbs(values(i, 1))
val = IIf(imSize > 0#, absSize / imSize, 0#)
End With
If i = 1 Or val < minval Then
minval = val
idx = i
If minval = 0# Then Exit For ' it doesn't get any better than this
End If
Next i
realIndex = values(idx, 1)
End Function
准则是虚部与复数的绝对值之比-接近零,接近实数。第二个代码返回该值(而不是值列中的索引),并且它以更安全的方式选择初始最小值。