[数学] Cardano メソッドを使用して単項 3 次方程式を解き、Python で実装する

【参考】

【問題の説明】

1 つの変数で 3 次方程式を解く

1 つの変数で 3 次方程式を解きます:
ax 3 + bx 2 + cx + d = 0 ax^3+bx^2+cx+d=0× _3+bx _2+cx _+d=0

これを解決するには多くの方法がありますが、Cardano メソッドによって得られる解決策は次のとおりです。
ここに画像の説明を挿入

単項 3 次多項式: y = f ( x ) = ax 3 + bx 2 + cx + dy=f(x)=ax^3+bx^2+cx+dy=f ( x )=× _3+bx _2+cx _+d =>ax 3 + bx 2 + cx + d − y = 0 ax^3+bx^2+cx+dy=0× _3+bx _2+cx _+dy=0

【コード】

既製のパッケージ Cardano_method

  • Python パッケージを使用できます: install cardano_method[ここを参照]
    pip install cardano_method
    
    このパッケージの使用法:CubicEquation最初のパラメーター リストに対応する関数は次のとおりです。[a, b, c, d]これは、方程式の係数を解くことです。
    from cardano_method.cubic import CubicEquation
    a = CubicEquation([1, 3, 4, 4])
    print(a.answers)  # j表示虚部后缀
    # [(-2+0j), (-0.5+1.322875j), (-0.5-1.322875j)]
    print(a.answers[0].real)  # 获取第一个解的实部
    print(a.answers[0].imag)  # 获取第一个解的虚部
    
    しかし、問題が見つかりました。方程式x 3 + 1 = 0 x^3+1=0を解きます。バツ3+1=0の場合、エラー レポートの分母は 0: ですZeroDivisionError
    a = CubicEquation([1, 0, 0, 1])
    
    ここに画像の説明を挿入
    しかし実際には、x 3 + 1 = 0 x^3+1=0バツ3+1=0の解は次のとおりです:x 1 = − 1 x_1=-1バツ1=1 ,x 2 = 1 2 + 3 2 i x_2=\frac{1}{2}+\frac{\sqrt{3}}{2}iバツ2=21+23 i ,x 3 = 1 2 − 3 2 i x_3=\frac{1}{2}-\frac{\sqrt{3}}{2}iバツ3=2123 i(这里 i i iは虚数を表します。)パッケージのバグを解決する方法を詳しく知りたいですか?

計算式に従って解決策のコードを書きます

  1. 解関数は、解に対応する式に従って記述できます。 [注: 浮動小数点計算について質問がありますか?

    def cardano_solution_v0(a, b, c, d):
        ab = -b/float(3*a)
        q = (3*a*c-(b**2)) / (9*(a**2))
        r = (9*a*b*c-27*(a**2)*d-2*(b**3)) / (54*(a**3))
        delta_sqrt = (q**3+r**2)**(1.0/2)
        
        s = (r+delta_sqrt)**(1.0/3)
        t = (r-delta_sqrt)**(1.0/3)
        imag = complex(0, (s-t)*(3**(1.0/3))/2)
        x1 = s+t+ab
        x2 = -(s+t)/2+ab+imag
        x3 = -(s+t)/2+ab-imag
        return x1, x2, x3
    

    テストの変更では浮動小数点が保持されていますが、まだ問題があります。cardano_methodパッケージの結果と一致していますか? ? ? [注:どちらにcardano_solution_v0cardano_solution_v1問題がありますが、正しい解決策については、次の関数を参照してください。cardano_solution

    def round_ri(xo, n=4):
        xr, xi = round(xo.real, n), round(xo.imag, n)
        if xi == 0:
            return xr
        else:
            return complex(xr, xi)
    
    def cardano_solution_v1(a, b, c, d):
        ab = -b/float(3*a)
        q = (3*a*c-(b**2)) / (9*(a**2))
        r = (9*a*b*c-27*(a**2)*d-2*(b**3)) / (54*(a**3))
        delta_sqrt = round((q**3+r**2)**(1.0/2), 4)
        
        # print("r, delta_sqrt:", r, delta_sqrt, round(r-delta_sqrt, 4))
        s = round((r+delta_sqrt)**(1.0/3), 8)
        t = round(r-delta_sqrt, 4)**(1.0/3)
        print("st,ab:", s, t, ab)
        imag = complex(0, (s-t)*(3**(1.0/3))/2)
        x1 = s+t+ab
        x2 = -(s+t)/2+ab+imag
        x3 = -(s+t)/2+ab-imag
        return round_ri(x1), round_ri(x2), round_ri(x3)
    

    式そのものが間違っているのでしょうか?それとも浮動小数点/基数の問題でしょうか? もう一度確認する必要があります。

  2. 他の数式をテストする: Baidu Encyclopedia - 単項 3 次方程式の根を求める公式

    これは、1 次元 3 次方程式の係数が複素数の場合、カルダノの公式に問題があり (何が問題なのか?)、次の一般的な根を求める公式が使用されることを意味します。
    ここに画像の説明を挿入ここに画像の説明を挿入

    def cardano_solution(a, b, c, d):
        #u = round((9*a*b*c-27*(a**2)*d-2*(b**3)) / (54*(a**3)), 4)
        #v = round(3*(4*a*c**3 - b**2*c**2-18*a*b*c*d+27*a**2*d**2+4*b**3*d) / (18**2*a**4), 4) ** (1.0/2)
        u = (9*a*b*c-27*(a**2)*d-2*(b**3)) / (54*(a**3))
        v = (3*(4*a*c**3 - b**2*c**2-18*a*b*c*d+27*a**2*d**2+4*b**3*d) / (18**2*a**4)) ** (1.0/2)
        if abs(u+v) >= abs(u-v):
            m = (u+v) ** (1.0/3)
        else:
            m = (u-v) ** (1.0/3)
        if m == 0: 
            n == 0
        else:
            n = (b**2-3*a*c) / (9*a**2*m)
        # w = complex(0, -0.5+(3/4)**(1.0/2))
        # w2 = complex(0, -0.5-(3/4)**(1.0/2))
        w = -0.5+(-3/4)**(1.0/2)
        w2 = -0.5-(-3/4)**(1.0/2)
        ab = -b/float(3*a)
        x1 = m+n+ab
        x2 = w*m+w2*n+ab
        x3 = w2*m+w*n+ab
        # return x1, x2, x3
        return round_ri(x1), round_ri(x2), round_ri(x3)
    

    テスト結果cardano_solutioncardano_methodパッケージを照合し、x 3 + 1 = 0 x^3+1=0を解くことができます。バツ3+1=0問題ありません:

    print(cardano_solution(1,3,4,4))
    print(cardano_solution(1,0,0,-1))
    print(cardano_solution(1,0,0,1))
    # ((-0.5+1.3229j), -2.0, (-0.5-1.3229j))
    # (1.0, (-0.5+0.866j), (-0.5-0.866j))
    # ((0.5+0.866j), -1.0, (0.5-0.866j))
    
    print(CubicEquation([1,3,4,4]).answers)
    print(CubicEquation([1,0,0,-1]).answers)
    print(CubicEquation([1,0,0,1]).answers)  # 报错
    # [(-2+0j), (-0.5+1.322875j), (-0.5-1.322875j)]
    # [(1+0j), (-0.5+0.866025j), (-0.5-0.866025j)]
    # ZeroDivisionError ...
    

【まとめ】

  • 公式に従って自分で書いた関数はcardano_solution単項三次方程式を解くことができます。
  • ダウンロードしたパッケージcardano_methodと、Cardano 式を使用して直接記述された関数に問題があります。なぜなら?

P.S. Python は複素数の実数部と虚数部を取得します。接尾辞を使用してj虚数を表します。たとえばa+bj、middleaは実数部であり、b虚数部は Python でcomplex(a,b)複素数を生成するために使用されます。

x = 2+1.5j
print(x.real)  # 打印实部:2
print(x.imag)  # 打印虚部:2
x1 = complex(2,1.5)  # 使用`complex`生成复数 2+1.5j

おすすめ

転載: blog.csdn.net/sinat_32872729/article/details/128015139
おすすめ