algebrite
Version:
Computer Algebra System in Coffeescript
1,833 lines (1,476 loc) • 32.3 kB
text/coffeescript
show_power_debug = false
performing_roots = false
Eval_roots = ->
p2 = cadr(p1)
if (car(p2) == symbol(SETQ) || car(p2) == symbol(TESTEQ))
push(cadr(p2))
Eval()
push(caddr(p2))
Eval()
subtract()
else
push(p2)
Eval()
p2 = pop()
if (car(p2) == symbol(SETQ) || car(p2) == symbol(TESTEQ))
push(cadr(p2))
Eval()
push(caddr(p2))
Eval()
subtract()
else
push(p2)
push(caddr(p1))
Eval()
p2 = pop()
if (p2 == symbol(NIL))
guess()
else
push(p2)
p2 = pop()
p1 = pop()
if (!ispoly(p1, p2))
stop("roots: 1st argument is not a polynomial")
push(p1)
push(p2)
roots()
hasImaginaryCoeff = (k) ->
imaginaryCoefficients = false
h = tos
for i in [k...0] by -1
if iscomplexnumber(stack[tos-i])
imaginaryCoefficients = true
break
return imaginaryCoefficients
isSimpleRoot = (k) ->
if k > 2
isSimpleRootPolynomial = true
h = tos
if iszero(stack[tos-k])
isSimpleRootPolynomial = false
for i in [(k-1)...1] by -1
if !iszero(stack[tos-i])
isSimpleRootPolynomial = false
break
else
isSimpleRootPolynomial = false
return isSimpleRootPolynomial
normalisedCoeff = ->
k = coeff()
divideBy = stack[tos-1]
miniStack = []
for i in [1..k]
miniStack.push(pop())
for i in [(k-1)..0]
push(miniStack[i])
push(divideBy)
divide()
return k
roots = ->
h = 0
i = 0
n = 0
save()
if recursionLevelNestedRadicalsRemoval > 1
pop()
pop()
push(symbol(NIL))
restore()
return
performing_roots = true
h = tos - 2
if DEBUG then console.log("checking if " + stack[tos-1].toString() + " is a case of simple roots")
p2 = pop()
p1 = pop()
push(p1)
push(p2)
push(p1)
push(p2)
k = normalisedCoeff()
if isSimpleRoot(k)
if DEBUG then console.log("yes, " + stack[tos-1].toString() + " is a case of simple roots")
lastCoeff = stack[tos-k]
leadingCoeff = stack[tos-1]
moveTos tos - k
pop()
pop()
getSimpleRoots(k, leadingCoeff, lastCoeff)
else
moveTos tos - k
roots2()
n = tos - h
if (n == 0)
stop("roots: the polynomial is not factorable, try nroots")
if (n == 1)
performing_roots = false
restore()
return
sort_stack(n)
p1 = alloc_tensor(n)
p1.tensor.ndim = 1
p1.tensor.dim[0] = n
for i in [0...n]
p1.tensor.elem[i] = stack[h + i]
moveTos h
push(p1)
restore()
performing_roots = false
getSimpleRoots = (n, leadingCoeff, lastCoeff) ->
if DEBUG then console.log("getSimpleRoots")
save()
n = n-1
push(lastCoeff)
push_rational(1,n)
power()
push(leadingCoeff)
push_rational(1,n)
power()
divide()
commonPart = pop()
if n % 2 == 0
for rootsOfOne in [1..n] by 2
push(commonPart)
push_integer(-1)
push_rational(rootsOfOne,n)
power()
multiply()
aSol = pop()
push(aSol)
push(aSol)
negate()
else
for rootsOfOne in [1..n]
push(commonPart)
push_integer(-1)
push_rational(rootsOfOne,n)
power()
multiply()
if rootsOfOne % 2 == 0
negate()
restore()
roots2 = ->
save()
p2 = pop()
p1 = pop()
push(p1)
push(p2)
push(p1)
push(p2)
k = normalisedCoeff()
if !hasImaginaryCoeff(k)
moveTos tos - k
factorpoly()
p1 = pop()
else
moveTos tos - k
pop()
pop()
if (car(p1) == symbol(MULTIPLY))
p1 = cdr(p1)
while (iscons(p1))
push(car(p1))
push(p2)
roots3()
p1 = cdr(p1)
else
push(p1)
push(p2)
roots3()
restore()
roots3 = ->
save()
p2 = pop()
p1 = pop()
if (car(p1) == symbol(POWER) && ispoly(cadr(p1), p2) && isposint(caddr(p1)))
push(cadr(p1))
push(p2)
n = normalisedCoeff()
mini_solve(n)
else if (ispoly(p1, p2))
push(p1)
push(p2)
n = normalisedCoeff()
mini_solve(n)
restore()
mini_solve = (n) ->
save()
if (n == 2)
p3 = pop()
p4 = pop()
push(p4)
push(p3)
divide()
negate()
restore()
return
if (n == 3)
p3 = pop()
p4 = pop()
p5 = pop()
push(p4)
push_integer(2)
power()
push_integer(4)
push(p3)
multiply()
push(p5)
multiply()
subtract()
push_rational(1, 2)
power()
p6 = pop()
push(p6);
push(p4)
subtract()
push(p3)
push_integer(2)
multiply()
divide()
push(p6);
push(p4)
add()
negate()
push(p3)
divide()
push_rational(1, 2)
multiply()
restore()
return
if (n == 4 or n == 5)
p3 = pop()
p4 = pop()
p5 = pop()
p6 = pop()
push(p5)
push(p5)
multiply()
R_c2 = pop()
push(R_c2)
push(p5)
multiply()
R_c3 = pop()
push(p4)
push(p4)
multiply()
R_b2 = pop()
push(R_b2)
push(p4)
multiply()
R_b3 = pop()
push(R_b3)
push(p6)
multiply()
R_b3_d = pop()
push(R_b3_d)
push_integer(-4)
multiply()
R_m4_b3_d = pop()
push(R_b3)
push_integer(2)
multiply()
R_2_b3 = pop()
push(p3)
push(p3)
multiply()
R_a2 = pop()
push(R_a2)
push(p3)
multiply()
R_a3 = pop()
push_integer(3)
push(p3)
multiply()
R_3_a = pop()
push(R_a2)
push(p6)
multiply()
R_a2_d = pop()
push(R_a2_d)
push(p6)
multiply()
R_a2_d2 = pop()
push(R_a2_d)
push_integer(27)
multiply()
R_27_a2_d = pop()
push(R_a2_d2)
push_integer(-27)
multiply()
R_m27_a2_d2 = pop()
push(R_3_a)
push_integer(2)
multiply()
R_6_a = pop()
push(p3)
push(p5)
multiply()
R_a_c = pop()
push(R_a_c)
push(p4)
multiply()
R_a_b_c = pop()
push(R_a_b_c)
push(p6)
multiply()
R_a_b_c_d = pop()
push(R_a_c)
push_integer(3)
multiply()
R_3_a_c = pop()
push_integer(-4)
push(p3)
push(R_c3)
multiply()
multiply()
R_m4_a_c3 = pop()
push(R_a_b_c)
push_integer(9)
multiply()
negate()
R_m9_a_b_c = pop()
push(R_a_b_c_d)
push_integer(18)
multiply()
R_18_a_b_c_d = pop()
push(R_b2)
push(R_3_a_c)
subtract()
R_DELTA0 = pop()
push(R_b2)
push(R_c2)
multiply()
R_b2_c2 = pop()
push(p4)
negate()
push(R_3_a)
divide()
R_m_b_over_3a = pop()
if (n == 4)
if DEBUG then console.log ">>>>>>>>>>>>>>>> actually using cubic formula <<<<<<<<<<<<<<< "
if DEBUG then console.log "cubic: D0: " + R_DELTA0.toString()
push(R_DELTA0)
push_integer(3)
power()
push_integer(4)
multiply()
R_4_DELTA03 = pop()
push(R_DELTA0)
simplify()
absValFloat()
R_DELTA0_toBeCheckedIfZero = pop()
if DEBUG then console.log "cubic: D0 as float: " + R_DELTA0_toBeCheckedIfZero.toString()
push(R_18_a_b_c_d)
push(R_m4_b3_d)
push(R_b2_c2)
push(R_m4_a_c3)
push(R_m27_a2_d2)
add()
add()
add()
add()
simplify()
absValFloat()
R_determinant = pop()
if DEBUG then console.log "cubic: DETERMINANT: " + R_determinant.toString()
push(R_2_b3)
push(R_m9_a_b_c)
push(R_27_a2_d)
add()
add()
R_DELTA1 = pop()
if DEBUG then console.log "cubic: D1: " + R_DELTA1.toString()
push(R_DELTA1)
push_integer(2)
power()
push(R_4_DELTA03)
subtract()
push_rational(1, 2)
power()
simplify()
R_Q = pop()
if iszero(R_determinant)
if iszero(R_DELTA0_toBeCheckedIfZero)
if DEBUG then console.log " cubic: DETERMINANT IS ZERO and delta0 is zero"
push(R_m_b_over_3a) # just same solution three times
restore()
return
else
if DEBUG then console.log " cubic: DETERMINANT IS ZERO and delta0 is not zero"
push(p3)
push(p6)
push_integer(9)
multiply()
multiply()
push(p4)
push(p5)
multiply()
subtract()
push(R_DELTA0)
push_integer(2)
multiply()
divide() # first solution
root_solution = pop()
push(root_solution)
push(root_solution)
push(R_a_b_c)
push_integer(4)
multiply()
push(p3)
push(p3)
push(p6)
push_integer(9)
multiply()
multiply()
multiply()
negate()
push(R_b3)
negate()
add()
add()
push(p3)
push(R_DELTA0)
multiply()
divide()
restore()
return
C_CHECKED_AS_NOT_ZERO = false
flipSignOFQSoCIsNotZero = false
while !C_CHECKED_AS_NOT_ZERO
push(R_Q)
if flipSignOFQSoCIsNotZero
negate()
push(R_DELTA1)
add()
push_rational(1, 2)
multiply()
push_rational(1, 3)
power()
simplify()
R_C = pop()
if DEBUG then console.log "cubic: C: " + R_C.toString()
push(R_C)
simplify()
absValFloat()
R_C_simplified_toCheckIfZero = pop()
if DEBUG then console.log "cubic: C as absval and float: " + R_C_simplified_toCheckIfZero.toString()
if iszero(R_C_simplified_toCheckIfZero)
if DEBUG then console.log " cubic: C IS ZERO flipping the sign"
flipSignOFQSoCIsNotZero = true
else
C_CHECKED_AS_NOT_ZERO = true
push(R_C)
push(R_3_a)
multiply()
R_3_a_C = pop()
push(R_3_a_C)
push_integer(2)
multiply()
R_6_a_C = pop()
push(imaginaryunit)
push_integer(3)
push_rational(1, 2)
power()
multiply()
i_sqrt3 = pop()
push_integer(1)
push(i_sqrt3)
add()
one_plus_i_sqrt3 = pop()
push_integer(1)
push(i_sqrt3)
subtract()
one_minus_i_sqrt3 = pop()
push(R_C)
push(R_3_a)
divide()
R_C_over_3a = pop()
push(R_m_b_over_3a)
push(R_C_over_3a)
negate()
push(R_DELTA0)
push(R_3_a_C)
divide()
negate()
add()
add()
simplify()
push(R_m_b_over_3a)
push(R_C_over_3a)
push(one_plus_i_sqrt3)
multiply()
push_integer(2)
divide()
push(one_minus_i_sqrt3)
push(R_DELTA0)
multiply()
push(R_6_a_C)
divide()
add()
add()
simplify()
push(R_m_b_over_3a)
push(R_C_over_3a)
push(one_minus_i_sqrt3)
multiply()
push_integer(2)
divide()
push(one_plus_i_sqrt3)
push(R_DELTA0)
multiply()
push(R_6_a_C)
divide()
add()
add()
simplify()
restore()
return
if (n == 5)
if DEBUG then console.log ">>>>>>>>>>>>>>>> actually using quartic formula <<<<<<<<<<<<<<< "
p7 = pop()
if iszero(p4) and iszero(p6) and !iszero(p5) and !iszero(p7)
if DEBUG then console.log("biquadratic case")
push(p3)
push(symbol(SECRETX))
push_integer(2)
power()
multiply()
push(p5)
push(symbol(SECRETX))
multiply()
push(p7)
add()
add()
push(symbol(SECRETX))
roots()
biquadraticSolutions = pop()
for eachSolution in biquadraticSolutions.tensor.elem
push(eachSolution)
push_rational(1,2)
power()
simplify()
push(eachSolution)
push_rational(1,2)
power()
negate()
simplify()
restore()
return
# D - only related calculations
push(p6)
push(p6)
multiply()
R_d2 = pop()
push(p7)
push(p7)
multiply()
R_e2 = pop()
push(R_e2)
push(p7)
multiply()
R_e3 = pop()
push_integer(256)
push(R_a3)
push(R_e3)
multiply()
multiply()
push_integer(-192)
push(R_a2_d)
push(R_e2)
push(p4)
multiply()
multiply()
multiply()
push_integer(-128)
push(R_a2)
push(R_c2)
push(R_e2)
multiply()
multiply()
multiply()
push_integer(144)
push(R_a2_d2)
push(p5)
push(p7)
multiply()
multiply()
multiply()
push(R_m27_a2_d2)
push(R_d2)
multiply()
push_integer(144)
push(R_a_b_c)
push(p4)
push(R_e2)
multiply()
multiply()
multiply()
push_integer(-6)
push(p3)
push(R_b2)
push(R_d2)
push(p7)
multiply()
multiply()
multiply()
multiply()
push_integer(-80)
push(R_a_b_c_d)
push(p5)
push(p7)
multiply()
multiply()
multiply()
push_integer(18)
push(R_a_b_c_d)
push(R_d2)
multiply()
multiply()
push_integer(16)
push(R_a_c)
push(R_c3)
push(p7)
multiply()
multiply()
multiply()
push_integer(-4)
push(R_a_c)
push(R_c2)
push(R_d2)
multiply()
multiply()
multiply()
push_integer(-27)
push(R_b3)
push(p4)
push(R_e2)
multiply()
multiply()
multiply()
push_integer(18)
push(R_b3_d)
push(p5)
push(p7)
multiply()
multiply()
multiply()
push(R_m4_b3_d)
push(R_d2)
multiply()
push_integer(-4)
push(R_b2_c2)
push(p5)
push(p7)
multiply()
multiply()
multiply()
push(R_b2_c2)
push(R_d2)
multiply()
add()
add()
add()
add()
add()
add()
add()
add()
add()
add()
add()
add()
add()
add()
add()
R_determinant = pop()
if DEBUG then console.log("R_determinant: " + R_determinant.toString())
push(R_c2)
push_integer(-3)
push(p4)
push(p6)
multiply()
multiply()
push_integer(12)
push(p3)
push(p7)
multiply()
multiply()
add()
add()
R_DELTA0 = pop()
if DEBUG then console.log("R_DELTA0: " + R_DELTA0.toString())
push_integer(2)
push(R_c3)
multiply()
push_integer(-9)
push(p4)
push(p5)
push(p6)
multiply()
multiply()
multiply()
push_integer(27)
push(R_b2)
push(p7)
multiply()
multiply()
push_integer(27)
push(p3)
push(R_d2)
multiply()
multiply()
push_integer(-72)
push(R_a_c)
push(p7)
multiply()
multiply()
add()
add()
add()
add()
R_DELTA1 = pop()
if DEBUG then console.log("R_DELTA1: " + R_DELTA1.toString())
push_integer(8)
push(R_a_c)
multiply()
push_integer(-3)
push(R_b2)
multiply()
add()
push_integer(8)
push(R_a2)
multiply()
divide()
R_p = pop()
if DEBUG then console.log("p: " + R_p.toString())
push(R_b3)
push_integer(-4)
push(R_a_b_c)
multiply()
push_integer(8)
push(R_a2_d)
multiply()
add()
add()
push_integer(8)
push(R_a3)
multiply()
divide()
R_q = pop()
if DEBUG then console.log("q: " + R_q.toString())
if DEBUG then console.log("tos 1 " + tos)
if !iszero(p4)
if DEBUG then console.log("tos 2 " + tos)
push_integer(8)
push(p5)
push(p3)
multiply()
multiply()
push_integer(-3)
push(p4)
push_integer(2)
power()
multiply()
add()
push_integer(8)
push(p3)
push_integer(2)
power()
multiply()
divide()
R_p = pop()
if DEBUG then console.log("p for depressed quartic: " + R_p.toString())
push(p4)
push_integer(3)
power()
push_integer(-4)
push(p3)
push(p4)
push(p5)
multiply()
multiply()
multiply()
push_integer(8)
push(p6)
push(p3)
push_integer(2)
power()
multiply()
multiply()
add()
add()
push_integer(8)
push(p3)
push_integer(3)
power()
multiply()
divide()
R_q = pop()
if DEBUG then console.log("q for depressed quartic: " + R_q.toString())
push(p4)
push_integer(4)
power()
push_integer(-3)
multiply()
push_integer(256)
push(R_a3)
push(p7)
multiply()
multiply()
push_integer(-64)
push(R_a2_d)
push(p4)
multiply()
multiply()
push_integer(16)
push(R_b2)
push(p3)
push(p5)
multiply()
multiply()
multiply()
add()
add()
add()
push_integer(256)
push(p3)
push_integer(4)
power()
multiply()
divide()
R_r = pop()
if DEBUG then console.log("r for depressed quartic: " + R_r.toString())
if DEBUG then console.log("tos 4 " + tos)
push(symbol(SECRETX))
push_integer(4)
power()
if DEBUG then console.log("4 * x^4: " + stack[tos-1].toString())
push(R_p)
push(symbol(SECRETX))
push_integer(2)
power()
multiply()
if DEBUG then console.log("R_p * x^2: " + stack[tos-1].toString())
push(R_q)
push(symbol(SECRETX))
multiply()
if DEBUG then console.log("R_q * x: " + stack[tos-1].toString())
push(R_r)
if DEBUG then console.log("R_r: " + stack[tos-1].toString())
add()
add()
add()
simplify()
if DEBUG then console.log("solving depressed quartic: " + stack[tos-1].toString())
push(symbol(SECRETX))
roots()
depressedSolutions = pop()
if DEBUG then console.log("depressedSolutions: " + depressedSolutions)
for eachSolution in depressedSolutions.tensor.elem
push(eachSolution)
push(p4)
push_integer(4)
push(p3)
multiply()
divide()
subtract()
simplify()
if DEBUG then console.log("solution from depressed: " + stack[tos-1].toString())
restore()
return
else
R_p = p5
R_q = p6
R_r = p7
push_integer(2)
push(R_p)
multiply()
coeff2 = pop()
push_integer(-4)
push(R_p)
push_integer(2)
power()
multiply()
push(R_r)
multiply()
coeff3 = pop()
push(R_q)
push_integer(2)
power()
negate()
coeff4 = pop()
push(symbol(SECRETX))
push_integer(3)
power()
push(coeff2)
push(symbol(SECRETX))
push_integer(2)
power()
multiply()
push(coeff3)
push(symbol(SECRETX))
multiply()
push(coeff4)
add()
add()
add()
console.log("Descarte's resolventCubic: " + stack[tos-1].toString())
push(symbol(SECRETX))
roots()
resolventCubicSolutions = pop()
console.log("Descarte's resolventCubic solutions: " + resolventCubicSolutions)
console.log("tos: " + tos)
R_u = null
for eachSolution in resolventCubicSolutions.tensor.elem
console.log("examining solution: " + eachSolution)
push(eachSolution)
push_integer(2)
multiply()
push(R_p)
add()
absValFloat()
toBeCheckedIFZero = pop()
console.log("abs value is: " + eachSolution)
if !iszero(toBeCheckedIFZero)
R_u = eachSolution
break
console.log("chosen solution: " + R_u)
push(R_u)
negate()
R_s = pop()
push(R_p)
push(R_u)
push_integer(2)
power()
push(R_q)
push(R_u)
divide()
add()
add()
push_integer(2)
divide()
R_t = pop()
push(R_p)
push(R_u)
push_integer(2)
power()
push(R_q)
push(R_u)
divide()
subtract()
add()
push_integer(2)
divide()
R_v = pop()
push(symbol(SECRETX))
push_integer(2)
power()
push(R_s)
push(symbol(SECRETX))
multiply()
push(R_t)
add()
add()
console.log("factored quartic 1: " + stack[tos-1].toString())
push(symbol(SECRETX))
push_integer(2)
power()
push(R_u)
push(symbol(SECRETX))
multiply()
push(R_v)
add()
add()
console.log("factored quartic 2: " + stack[tos-1].toString())
pop()
restore()
return
push_rational(5,2)
push(R_p)
multiply()
coeff2 = pop()
push_integer(2)
push(R_p)
push_integer(2)
power()
multiply()
push(R_r)
subtract()
coeff3 = pop()
push(R_p)
push_integer(3)
power()
push_integer(2)
divide()
push_rational(-1,2)
push(R_p)
push(R_r)
multiply()
multiply()
push_rational(-1,8)
push(R_q)
push_integer(2)
power()
multiply()
add()
add()
coeff4 = pop()
push(symbol(SECRETX))
push_integer(3)
power()
push(coeff2)
push(symbol(SECRETX))
push_integer(2)
power()
multiply()
push(coeff3)
push(symbol(SECRETX))
multiply()
push(coeff4)
add()
add()
add()
if DEBUG then console.log("resolventCubic: " + stack[tos-1].toString())
push(symbol(SECRETX))
roots()
resolventCubicSolutions = pop()
if DEBUG then console.log("resolventCubicSolutions: " + resolventCubicSolutions)
R_m = null
for eachSolution in resolventCubicSolutions.tensor.elem
if DEBUG then console.log("examining solution: " + eachSolution)
push(eachSolution)
push_integer(2)
multiply()
push(R_p)
add()
absValFloat()
toBeCheckedIFZero = pop()
if DEBUG then console.log("abs value is: " + eachSolution)
if !iszero(toBeCheckedIFZero)
R_m = eachSolution
break
if DEBUG then console.log("chosen solution: " + R_m)
push(R_m)
push_integer(2)
multiply()
push(R_p)
add()
push_rational(1,2)
power()
simplify()
sqrtPPlus2M = pop()
push(R_q)
push_integer(2)
multiply()
push(sqrtPPlus2M)
divide()
simplify()
TwoQOversqrtPPlus2M = pop()
push(R_p)
push_integer(3)
multiply()
push(R_m)
push_integer(2)
multiply()
add()
ThreePPlus2M = pop()
push(sqrtPPlus2M)
push(ThreePPlus2M)
push(TwoQOversqrtPPlus2M)
add()
negate()
push_rational(1,2)
power()
simplify()
add()
push_integer(2)
divide()
push(sqrtPPlus2M)
push(ThreePPlus2M)
push(TwoQOversqrtPPlus2M)
add()
negate()
push_rational(1,2)
power()
simplify()
subtract()
push_integer(2)
divide()
push(sqrtPPlus2M)
negate()
push(ThreePPlus2M)
push(TwoQOversqrtPPlus2M)
subtract()
negate()
push_rational(1,2)
power()
simplify()
add()
push_integer(2)
divide()
push(sqrtPPlus2M)
negate()
push(ThreePPlus2M)
push(TwoQOversqrtPPlus2M)
subtract()
negate()
push_rational(1,2)
power()
simplify()
subtract()
push_integer(2)
divide()
restore()
return
push(R_determinant)
simplify()
absValFloat()
R_determinant_simplified_toCheckIfZero = pop()
push(R_DELTA0)
simplify()
absValFloat()
R_DELTA0_simplified_toCheckIfZero = pop()
S_CHECKED_AS_NOT_ZERO = false
choiceOfRadicalInQSoSIsNotZero = 0
while !S_CHECKED_AS_NOT_ZERO
Q_CHECKED_AS_NOT_ZERO = false
flipSignOFRadicalSoQIsNotZero = false
while !Q_CHECKED_AS_NOT_ZERO
push(R_DELTA1)
push(R_DELTA1)
push_integer(2)
power()
push_integer(-4)
push(R_DELTA0)
push_integer(3)
power()
multiply()
add()
push_rational(1,2)
power()
if flipSignOFRadicalSoQIsNotZero
negate()
# the addition under the outer radical
add()
# content of outer radical divided by two
push_integer(2)
divide()
if DEBUG then console.log("content of cubic root: " + stack[tos-1].toString())
# outer radical calculation: cubic root
# now we actually have to find all the roots
# because we have to pick the one that makes S != 0
push_rational(1,3)
power()
simplify()
R_principalCubicRoot = pop()
if DEBUG then console.log("principal cubic root: " + R_principalCubicRoot.toString())
if DEBUG then console.log("tos : " + tos)
if choiceOfRadicalInQSoSIsNotZero == 0
if DEBUG then console.log("chosing principal cubic root")
push(R_principalCubicRoot)
else if choiceOfRadicalInQSoSIsNotZero == 1
if DEBUG then console.log("chosing cubic root beyond principal")
push(R_principalCubicRoot)
push_rational(-1,2)
multiply()
push_integer(3)
push_rational(1,2)
power()
push(imaginaryunit)
multiply()
push_rational(-1,2)
multiply()
push(R_principalCubicRoot)
multiply()
add()
else if choiceOfRadicalInQSoSIsNotZero == 1
if DEBUG then console.log("chosing cubic root beyond beyond principal")
push(R_principalCubicRoot)
push_rational(-1,2)
multiply()
push_integer(3)
push_rational(1,2)
power()
push(imaginaryunit)
multiply()
push_rational(1,2)
multiply()
push(R_principalCubicRoot)
multiply()
add()
simplify()
R_Q = pop()
if DEBUG then console.log "Q " + R_Q.toString()
if DEBUG then console.log("tos: " + tos)
push(R_Q)
simplify()
absValFloat()
R_Q_simplified_toCheckIfZero = pop()
if DEBUG then console.log "Q simplified and abs" + R_Q_simplified_toCheckIfZero.toString()
if iszero(R_Q_simplified_toCheckIfZero) and (!iszero(R_determinant_simplified_toCheckIfZero) and iszero(R_DELTA0_simplified_toCheckIfZero))
if DEBUG then console.log " *********************************** Q IS ZERO and it matters, flipping the sign"
flipSignOFRadicalSoQIsNotZero = true
else
Q_CHECKED_AS_NOT_ZERO = true
if DEBUG then console.log("tos: " + tos)
push_rational(-2,3)
push(R_p)
multiply()
push(R_Q)
push(R_DELTA0)
push(R_Q)
divide()
add()
push(R_3_a)
divide()
add()
push_rational(1,2)
power()
push_integer(2)
divide()
show_power_debug = true
simplify()
R_S = pop()
if DEBUG then console.log "S " + R_S.toString()
push(R_S)
simplify()
absValFloat()
R_S_simplified_toCheckIfZero = pop()
if DEBUG then console.log "S " + R_S_simplified_toCheckIfZero.toString()
if iszero(R_S_simplified_toCheckIfZero)
if DEBUG then console.log " *********************************** S IS ZERO chosing another cubic root"
choiceOfRadicalInQSoSIsNotZero++
else
S_CHECKED_AS_NOT_ZERO = true
if DEBUG then console.log("tos: " + tos)
if DEBUG then console.log("tos: " + tos)
push(p4)
negate()
push(p3)
push_integer(4)
multiply()
divide()
R_minus_b_over_4a = pop()
push_integer(-4)
push(R_S)
push_integer(2)
power()
multiply()
push_integer(2)
push(R_p)
multiply()
subtract()
R_minus_4S2_minus_2p = pop()
push(R_q)
push(R_S)
divide()
R_q_over_S = pop()
if DEBUG then console.log("tos before putting together the 4 solutions: " + tos)
push(R_minus_b_over_4a)
push(R_S)
subtract()
push(R_minus_4S2_minus_2p)
push(R_q_over_S)
add()
push_rational(1,2)
power()
push_integer(2)
divide()
add()
simplify()
push(R_minus_b_over_4a)
push(R_S)
subtract()
push(R_minus_4S2_minus_2p)
push(R_q_over_S)
add()
push_rational(1,2)
power()
push_integer(2)
divide()
subtract()
simplify()
push(R_minus_b_over_4a)
push(R_S)
add()
push(R_minus_4S2_minus_2p)
push(R_q_over_S)
subtract()
push_rational(1,2)
power()
push_integer(2)
divide()
add()
simplify()
push(R_minus_b_over_4a)
push(R_S)
add()
push(R_minus_4S2_minus_2p)
push(R_q_over_S)
subtract()
push_rational(1,2)
power()
push_integer(2)
divide()
subtract()
simplify()
restore()
return
moveTos tos - n
restore()