检查立方方程的根是否复杂?
我使用 >实现。
我有方程式#1:
x³ -2 x² -5 x + 6 = 0
它给了我3个复杂的根({真实,虚构}):
{-2, 7.4014868308343765E-17}
{1 , -2.9605947323337506E-16}
{3 , 2.9605947323337506E-16}
但是实际上,正确的结果应为3个非复杂根:-2、1、3。
在这种情况下,我可以通过:将3个复杂的根应用于方程式,它返回非零结果(失败);在方程式上应用3个非复合根,它返回零结果(通过)。
但是在某些情况下,我同时将3个复合根和3-non-complex根应用于等式(例如47x³+7x²-52 x + 0 = 0
),它返回非 - 零(失败)。
我认为导致此问题的原因是因为此代码:
/// <summary>
/// Evaluate all cubic roots of this <c>Complex</c>.
/// </summary>
public static (Complex, Complex, Complex) CubicRoots(this Complex complex)
{
var r = Math.Pow(complex.Magnitude, 1d/3d);
var theta = complex.Phase/3;
const double shift = Constants.Pi2/3;
return (Complex.FromPolarCoordinates(r, theta),
Complex.FromPolarCoordinates(r, theta + shift),
Complex.FromPolarCoordinates(r, theta - shift));
}
我知道在计算时浮点值可能会失去精度(〜1E-15),但问题是想象中的部分需要确定天气为零或非零是否复杂。
我无法告诉用户我的应用程序:“嘿,用户,如果您看到虚构零件足够接近0,则可以自己决定根不是一个复杂的数字”。
目前,我使用此方法检查:
const int TOLERATE = 15;
bool isRemoveImaginary = System.Math.Round(root.Imaginary, TOLERATE) == 0; //Remove imaginary if it's too close to zero
但是我不知道此方法是否合适,如果toteration = 15是不够的。还是解决此问题的正确方法?
所以我想问,有什么更好的方法可以说明根是否复杂?
I use this Cubic root implementation.
I have equation #1:
x³ -2 x² -5 x + 6 = 0
It gives me 3 complex roots ({real, imaginary}):
{-2, 7.4014868308343765E-17}
{1 , -2.9605947323337506E-16}
{3 , 2.9605947323337506E-16}
But in fact, the right result should be 3 non-complex roots: -2, 1, 3.
With this case, I can test by: apply 3 complex roots to the equation, it returns non-zero result (failed); apply 3 non-complex roots to the equation, it returns zero result (passed).
But there is the case where I apply both 3-complex roots and 3-non-complex roots to the equation (e.g. 47 x³ +7 x² -52 x + 0 = 0
), it return non-zero (failed).
I think what causes this issue is because of this code:
/// <summary>
/// Evaluate all cubic roots of this <c>Complex</c>.
/// </summary>
public static (Complex, Complex, Complex) CubicRoots(this Complex complex)
{
var r = Math.Pow(complex.Magnitude, 1d/3d);
var theta = complex.Phase/3;
const double shift = Constants.Pi2/3;
return (Complex.FromPolarCoordinates(r, theta),
Complex.FromPolarCoordinates(r, theta + shift),
Complex.FromPolarCoordinates(r, theta - shift));
}
I know that floating point value can lose precision when calculating (~1E-15), but the problem is the imaginary part needs to decide weather it's zero or non-zero to tell if it's complex number or not.
I can't tell the user of my app: "hey user, if you see the imaginary part is close enough to 0, you can decide for yourself that the root's not a complex number".
Currently, I use this method to check:
const int TOLERATE = 15;
bool isRemoveImaginary = System.Math.Round(root.Imaginary, TOLERATE) == 0; //Remove imaginary if it's too close to zero
But I don't know if this method is appropriate, what if the TOLERATE = 15 is not enough. Or is it the right method to solve this problem?
So I want to ask, is there any better way to tell the root is complex or not?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
谢谢 Mark Dickinson 。
因此,根据 wikipedia :
The delta
d =(b*b -4*a*a*a)/(-27*a*a)
我的理想是:
delta&gt; 0:删除所有3个根的虚构数字。
delta&lt; 0:找到真实的根,然后删除其虚构部分,如果有的话
(确保它是真实的)。留下其他两个根部未触及的根。现在我
有 2个想法找到真正的根源:
理想#1
从理论上讲,真正的根应具有虚构= 0,但由于浮点精度,假想可以从0偏离0一点(例如,想象= 1E-15而不是0)。因此,想法是:3根根部之间的1个真正的根应具有最接近0的想象的。
代码:
上面的代码可能是错误的,如果有3个根({real,sighinary}),则可能是这样的:
也许是如果这种情况确实发生在现实生活中,我将提出一种更好的方法来选择真正的根源。
想法#2
请看一下计算出的3根根:
3根具有表格(通过测试知道这一点,而不是通过数学证明):
使用数学知识证明三个根中的哪一个是真实的。
试验#1:也许根
X1 = FromPolarCoordinates(R,Theta)
总是真实的? (失败)不真实,因为以下情况证明了猜测是错误的:-53x³ + 6x² + 14 x -54 = 0
(感谢 markDickinson喜欢:
delta&lt; 0
:如果b&lt; 0
x3是真实的,否则x1是真实的?因此,直到我得到更好的想法,我将只使用IDEA#1。
Thank you Mark Dickinson.
So according to Wikipedia:
The delta
D = (B*B - 4*A*A*A)/(-27*a*a)
My ideal is:
delta > 0: remove all imaginary numbers of 3 roots.
delta < 0: find the real root then remove its imaginary part if any
(to make sure it's real). Leave the other 2 roots untouched. Now I
have 2 ideas to find the real root:
Ideal #1
In theory, the real root should have imaginary = 0, but due to floating point precision, imaginary can deviate from 0 a little (e.g. imaginary = 1E-15 instead of 0). So the idea is: the 1 real root among 3 roots should have the imaginary whose value is closest to 0.
Code:
The code above can be wrong if there are 3 roots ({real, imaginary}) like this:
Maybe if that case does happen in real life, I will come up with a better way to pick the real root.
Idea #2
Take a look at how the 3 roots calculated:
3 roots have the form (know this by tests, not proven by math):
Use math knowledge to prove which one among the 3 roots is the real one.
Trial #1: Maybe the root
x1 = FromPolarCoordinates(r, theta)
is always real? (failed) untrue because the following case proved that guess is wrong:-53 x³ + 6 x² + 14 x - 54 = 0
(Thank Mark Dickinson again)I don't know if math can prove something like: while
delta < 0
: ifB < 0
then x3 is real, else x1 is real?So until I get better idea, I'll just use idea #1.