# Program to calculate the real roots # of a cubic equation # # It based on # A new approach to solving the cubic Cardan's # solution revealed # R.W.D. Nickalls # The mathematical gazette, 1993, vol 77, pp. 354-359 # # Fraga 6 Jun, 2010 # Fraga 8 Jun, 2015 program in python! :-) # Fraga 23 Oct, 2020. In python 3.7 import sys import math def cubic_root( v ) : signo = 1 if v < 0.0 : signo = -1 v = v * -1 val = signo* math.exp( math.log(v)/3.0 ) return( val ) n = len( sys.argv ) if n != 5 : print( "Args: a b c d" ) sys.exit(1) a = float(sys.argv[1]) b = float(sys.argv[2]) c = float(sys.argv[3]) d = float(sys.argv[4]) xN = -b/(3.0*a) yN = xN*( xN*(a*xN + b) + c ) + d yN2 = yN*yN delta2 = (b*b - 3.0*a*c)/(9.0*a*a) h2 = 4.0*a*a*delta2*delta2*delta2 print( "yN^2=", yN2, "h^2=", h2 ) if math.fabs(yN2 - h2) < 1e-8 : if math.fabs( yN2 ) < 1e-8 : print("Tres raices reales iguales en ", xN) else : print("Dos reales iguales y la tercera distinta") val = cubic_root( yN/(2.0*a) ) r1 = xN + val r3 = xN - 2.0*val print("Dos raices en ", r1) print("Una raiz en ", r3) elif yN2 > h2 : print("Una raiz real") v = math.sqrt( yN2 - h2 ); v1 = cubic_root( (-yN + v)/(2*a) ) v2 = cubic_root( (-yN - v)/(2*a) ) r1 = xN + v1 + v2; print( "Raiz en ", r1 ) else : print( "Tres raices reales distintas" ) delta = math.sqrt( delta2 ) c = -yN/(2.0*a*delta2*delta) theta = math.acos( c )/3.0 print( "Theta = ", theta ) delta *= 2.0; r1 = xN + delta*math.cos( theta ) r2 = xN + delta*math.cos( theta + 2.09439510266 ) r3 = xN + delta*math.cos( theta + 4.18879020533 ) print( "Raices: ", r1, r2, r3 )