[matemáticas] Usar el método de Cardano para resolver la ecuación cúbica unaria e implementarla en python

【referencia】

【Descripción del problema】

Resolver una ecuación cúbica en una variable

Resolver una ecuación cúbica en una variable:
ax 3 + bx 2 + cx + d = 0 ax^3+bx^2+cx+d=0una x3+b x2+c x+d=0

Hay muchas formas de resolverlo, entre las cuales la solución obtenida por el método de Cardano es:
inserte la descripción de la imagen aquí

Polinomio cúbico unario: y = f ( x ) = ax 3 + bx 2 + cx + dy=f(x)=ax^3+bx^2+cx+dy=f ( x )=una x3+b x2+c x+d =>ax 3 + bx 2 + cx + d − y = 0 ax^3+bx^2+cx+dy=0una x3+b x2+c x+dy=0

【Código】

Paquete listo cardano_method

  • Puede usar el paquete python: instalar cardano_method[ consulte aquí ]
    pip install cardano_method
    
    El uso de este paquete: CubicEquationla función correspondiente a la primera lista de parámetros es: [a, b, c, d], que es resolver los coeficientes de la ecuación.
    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)  # 获取第一个解的虚部
    
    Pero encontré un problema: resuelve la ecuación x 3 + 1 = 0 x^3+1=0X3+1=Cuando 0 , el denominador del informe de error es 0:ZeroDivisionError.
    a = CubicEquation([1, 0, 0, 1])
    
    inserte la descripción de la imagen aquí
    Pero en realidad, x 3 + 1 = 0 x^3+1=0X3+1=La solución de 0 corresponde a:x 1 = − 1 x_1=-1X1=1 ,x 2 = 1 2 + 3 2 i x_2=\frac{1}{2}+\frac{\sqrt{3}}{2}iX2=21+23 yo ,x 3 = 1 2 − 3 2 yo x_3=\frac{1}{2}-\frac{\sqrt{3}}{2}iX3=2123 yo __i representa un número imaginario). ¿Necesita ver cómo resolver el error en el paquete en detalle?

Escriba el código de la solución según la fórmula.

  1. La función de solución se puede escribir de acuerdo con la fórmula correspondiente a la solución: [Nota: ¿Tiene alguna pregunta sobre los cálculos de punto flotante?

    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
    

    La modificación de prueba conserva el punto flotante, pero todavía hay un problema, ¿ cardano_methodcoincide con el resultado del paquete? ? ? [Nota: cardano_solution_v0y cardano_solution_v1ambos tienen problemas,Consulte la siguiente función para obtener la solución correcta: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)
    

    ¿La fórmula en sí es incorrecta? ¿O es un problema de punto flotante/radix? Necesidad de comprobar de nuevo. . .

  2. Pruebe otras fórmulas: Enciclopedia de Baidu - Fórmula de búsqueda de raíz de ecuación cúbica unaria

    Esto quiere decir que cuando el coeficiente de la ecuación cúbica unidimensional es un número complejo, hay un problema con la fórmula de Cardano (¿cuál es el problema?), y se usa la siguiente fórmula general para encontrar raíces:
    inserte la descripción de la imagen aquíinserte la descripción de la imagen aquí

    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)
    

    Los resultados de la prueba cardano_solutiony cardano_methodlos paquetes se pueden combinar y resolver x 3 + 1 = 0 x ^ 3 + 1 = 0X3+1=0 sin problema:

    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 ...
    

【Resumir】

  • La función escrita por uno mismo según la fórmula cardano_solutionpuede resolver la ecuación cúbica unaria.
  • Hay un problema con el paquete descargado cardano_methody la función escrita directamente usando la fórmula de Cardano. ¿Porque?

P.S. python obtiene partes reales e imaginarias de números complejos. Use jsufijos para representar números imaginarios, como a+bjel medio, aque es la parte real y bla parte imaginaria, que se usa en Python complex(a,b)para generar un número complejo.

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

Supongo que te gusta

Origin blog.csdn.net/sinat_32872729/article/details/128015139
Recomendado
Clasificación