algebrite
Version:
Computer Algebra System in Coffeescript
618 lines (510 loc) • 9.9 kB
text/coffeescript
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 = ->
polycoeff = tos
push(p1)
push(p2)
k = coeff()
imaginaryCoefficients = false
h = tos
for i in [k...0] by -1
if iscomplexnumber(stack[tos-i])
imaginaryCoefficients = true
break
tos -= k
return imaginaryCoefficients
roots = ->
h = 0
i = 0
n = 0
h = tos - 2
roots2()
n = tos - h
if (n == 0)
stop("roots: the polynomial is not factorable, try nroots")
if (n == 1)
return
sort_stack(n)
save()
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]
tos = h
push(p1)
restore()
roots2 = ->
save()
p2 = pop()
p1 = pop()
push(p1)
push(p2)
if !hasImaginaryCoeff()
factorpoly()
p1 = pop()
else
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)
mini_solve()
else if (ispoly(p1, p2))
push(p1)
push(p2)
mini_solve()
restore()
mini_solve = ->
n = 0
save()
p2 = pop()
p1 = pop()
push(p1)
push(p2)
n = coeff()
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(p4)
multiply()
push_integer(4)
push(p3)
multiply()
push(p5)
multiply()
subtract()
push_rational(1, 2)
power()
p6 = pop()
push(p6);
push(p4)
subtract()
push(p3)
divide()
push_rational(1, 2)
multiply()
push(p6);
push(p4)
add()
negate()
push(p3)
divide()
push_rational(1, 2)
multiply()
restore()
return
if (n == 4)
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)
push_integer(-4)
multiply()
multiply()
R_m4_b3_d = pop()
push(R_b3)
push_integer(2)
multiply()
R_2_b3 = pop()
push_integer(3)
push(p3)
multiply()
R_3_a = pop()
push(R_3_a)
push_integer(9)
multiply()
push(p3)
multiply()
push(p6)
multiply()
R_27_a2_d = pop()
push(R_27_a2_d)
push(p6)
multiply()
negate()
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_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_m9_a_b_c)
push(p6)
push_integer(-2)
multiply()
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(R_DELTA0)
push_integer(3)
power()
push_integer(4)
multiply()
R_4_DELTA03 = pop()
push(R_DELTA0)
simplify()
Eval()
yyfloat()
Eval();
absval()
R_DELTA0_toBeCheckedIfZero = pop()
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()
Eval()
yyfloat()
Eval();
absval()
R_determinant = pop()
push(R_2_b3)
push(R_m9_a_b_c)
push(R_27_a2_d)
add()
add()
R_DELTA1 = pop()
push(R_DELTA1)
push_integer(2)
power()
push(R_4_DELTA03)
subtract()
push_rational(1, 2)
power()
R_Q = pop()
push(p4)
negate()
push(R_3_a)
divide()
R_m_b_over_3a = pop()
if iszero(R_determinant)
if iszero(R_DELTA0_toBeCheckedIfZero)
#console.log " *********************************** DETERMINANT IS ZERO and delta0 is zero"
push(R_m_b_over_3a) # just same solution three times
restore()
return
else
#console.log " *********************************** 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()
R_C = pop()
push(R_C)
simplify()
Eval()
yyfloat()
Eval();
absval()
R_C_simplified_toCheckIfZero = pop()
if iszero(R_C_simplified_toCheckIfZero)
#console.log " *********************************** 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
tos -= n
restore()