MATLAB實現一元三次方程求解/盛金公式

MATLAB實現一元三次方程求解/盛金公式

一元三次方程求解中,1945年卡爾丹諾把馮塔納的三次方程求根公式發表出來,但該公式形式比較複雜,直觀性也較差。1989年範盛金對一元三次方程求解進行了深入的研究和探索,提出了更加簡潔實用的求解公式-盛金公式。這裏對盛金公式進行簡要的介紹,並給出MATLAB實現的具體代碼和部分算例。參考資料:百度百科-卡爾丹公式;百度百科-盛金公式

一元三次方程求解–盛金公式

一元三次方程 ax3+bx2+cx+d=0ax^3 +bx^2+cx+d=0 重根判別式A=b23acA=b^2-3acB=bc9adB=bc-9adC=c23bdC=c^2-3bd總判別式Δ=B24AC\Delta=B^2-4AC

下面給出盛金判別法的結論

條件1A=B=0A=B=0時:x1=x2=x3=b3a=cb=3dcx1=x2=x3= \frac{-b}{3a}= \frac{-c}{b}= \frac{-3d}{c}
條件2Δ=B24AC>0\Delta=B^2-4AC>0時:x1=b(Y13+Y23)3ax1= \frac{-b-(\sqrt[3]{Y1}+\sqrt[3]{Y2})}{3a} x2=b+0.5(Y13+Y23)+0.53(Y13Y23)i3ax2=\frac{-b+0.5(\sqrt[3]{Y1}+\sqrt[3]{Y2})+ 0.5{\sqrt{3}} (\sqrt[3]{Y1}-\sqrt[3]{Y2})i}{3a} x3=b+0.5(Y13+Y23)0.53(Y13Y23)i3ax3=\frac{-b+0.5(\sqrt[3]{Y1}+\sqrt[3]{Y2})- 0.5{\sqrt{3}} (\sqrt[3]{Y1}-\sqrt[3]{Y2})i}{3a}其中,Y1=Ab+1.5a(B+B24AC)Y1=Ab+1.5a({-B+\sqrt{B^2-4AC}})Y2=Ab+1.5a(BB24AC)Y2=Ab+1.5a({-B-\sqrt{B^2-4AC}})
條件3Δ=B24AC=0\Delta=B^2-4AC=0時:x1=BAbax1= \frac{B}{A}- \frac{b}{a} x2=x3=B2Ax2= x3= -\frac{B}{2A}
條件4Δ=B24AC<0\Delta=B^2-4AC<0時:x1=b2Acosθ33ax1= \frac{-b-2\sqrt{A}cos{\frac{\theta}{3}}}{3a} x2=b+A(cosθ3+3sinθ3)3ax2= \frac{-b+\sqrt{A}(cos{\frac{\theta}{3}}+\sqrt{3}sin{\frac{\theta}{3}}) }{3a} x3=b+A(cosθ33sinθ3)3ax3= \frac{-b+\sqrt{A}(cos{\frac{\theta}{3}}-\sqrt{3}sin{\frac{\theta}{3}}) }{3a} 其中,θ=arccosT\theta=\arccos{T}T=2Ab3aB2AAT=\frac{2Ab-3aB}{2A\sqrt{A}}
此外,推導得到的盛金定理表明任意實係數的一元三次方程都可以運用盛金公式解算
通過上述4個條件即可求得一元三次方程的所有根(實根和虛根)。

MATLAB代碼-盛金公式

function x = Solve3Polynomial(a, b, c, d)
% 範盛金. 一元三次方程的新求根公式與新判別法[J]. 海南師範學院學報,1989,2(2):91-98.
A = b*b - 3*a*c;   if abs(A) < 1e-14;    A = 0;  end
B = b*c - 9*a*d;   if abs(B) < 1e-14;    B = 0;  end
C = c*c - 3*b*d;   if abs(C) < 1e-14;    C = 0;  end  
DET = B*B - 4*A*C; if abs(DET) < 1e-14;  DET = 0;  end  
if (A == 0) && (B == 0)
    x1 = -c/b;      x2 = x1 ;    x3 = x1;
end
if DET > 0
    Y1 = A*b + 1.5*a*(-B + sqrt(DET));
    Y2 = A*b + 1.5*a*(-B - sqrt(DET));
    y1 = nthroot(Y1,3);  y2 = nthroot(Y2,3);
    x1 = (-b-y1-y2)/(3*a);
    vec1 = (-b + 0.5*(y1 + y2))/(3*a);  
    vec2 = 0.5*sqrt(3)*(y1 - y2)/(3*a);
    x2 = complex(vec1, vec2);
    x3 = complex(vec1, -vec2);
    clear Y1 Y2 y1 y2 vec1 vec2;
end
if DET == 0 && (A ~= 0) && (B ~= 0)
    K = (b*c-9*a*d)/(b*b - 3*a*c); K = round(K,14);
    x1 = -b/a + K;   x2 = -0.5*K;   x3 = x2;
end
if DET < 0
    sqA = sqrt(A);
    T = (A*b - 1.5*a*B)/(A*sqA);
    theta = acos(T);
    csth  = cos(theta/3);
    sn3th = sqrt(3)*sin(theta/3);
    x1 = (-b - 2*sqA*csth)/(3*a);
    x2 = (-b + sqA*(csth + sn3th))/(3*a);
    x3 = (-b + sqA*(csth - sn3th))/(3*a);
    clear sqA T theta csth sn3th;
end
x = [x1;  x2;  x3];
end

值得說明的是:當得到的3個解中至少存在一個複數根時,matlab會將實數結果顯示爲a+0.0000000ia+0.0000000i的形式。

算例驗證

算例1: x3+5.4x2+9.72x+5.832=0x^3+5.4x^2+9.72x+5.832=0

參考值:x1=x2=x3=1.8x1=x2=x3=1.8
算例1的結果

算例2: 2x3+11x2+182x+255=02x^3+11x^2+182x+255=0

參考值:x1=1.5x2=2+9ix3=29ix1=-1.5; x2=-2+9i;x3=-2-9i
算例2的結果

算例3: x3+5.5x2+9.92x+5.888=0x^3+5.5x^2+9.92x+5.888=0

參考值:x1=2.3x2=x3=1.6x1=-2.3; x2=x3=-1.6
算例3的結果

算例4: 100x3420x2+467x105=0100x^3-420x^2+467x-105=0

參考值:x1=0.3x2=2.5x3=1.4x1=0.3; x2=2.5; x3=1.4
算例4的結果

上述4個算例可以看出,MATLAB實現過程中基本無誤。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章