void eval_nroots(void) { volatile int h, i, k, n; push(cadr(p1)); eval(); push(caddr(p1)); eval(); p2 = pop(); if (p2 == symbol(NIL)) guess(); else push(p2); p2 = pop(); p1 = pop(); if (!ispoly(p1, p2)) stop("nroots: polynomial?"); // mark the stack h = tos; // get the coefficients push(p1); push(p2); n = coeff(); if (n > YMAX) stop("nroots: degree?"); // convert the coefficients to real and imaginary doubles for (i = 0; i < n; i++) { push(stack[h + i]); real(); yyfloat(); eval(); p1 = pop(); push(stack[h + i]); imag(); yyfloat(); eval(); p2 = pop(); if (!isdouble(p1) || !isdouble(p2)) stop("nroots: coefficients?"); c[i].r = p1->u.d; c[i].i = p2->u.d; } // pop the coefficients tos = h; // n is the number of coefficients, n = deg(p) + 1 monic(n); for (k = n; k > 1; k--) { findroot(k); if (fabs(a.r) < DELTA) a.r = 0.0; if (fabs(a.i) < DELTA) a.i = 0.0; push_double(a.r); push_double(a.i); push(imaginaryunit); multiply(); add(); divpoly(k); } // now make n equal to the number of roots n = tos - h; if (n > 1) { sort_stack(n); p1 = alloc_tensor(n); p1->u.tensor->ndim = 1; p1->u.tensor->dim[0] = n; for (i = 0; i < n; i++) p1->u.tensor->elem[i] = stack[h + i]; tos = h; push(p1); } }
void expand(void) { save(); X = pop(); F = pop(); if (istensor(F)) { expand_tensor(); restore(); return; } // if sum of terms then sum over the expansion of each term if (car(F) == symbol(ADD)) { push_integer(0); p1 = cdr(F); while (iscons(p1)) { push(car(p1)); push(X); expand(); add(); p1 = cdr(p1); } restore(); return; } // B = numerator push(F); numerator(); B = pop(); // A = denominator push(F); denominator(); A = pop(); remove_negative_exponents(); // Q = quotient push(B); push(A); push(X); divpoly(); Q = pop(); // remainder B = B - A * Q push(B); push(A); push(Q); multiply(); subtract(); B = pop(); // if the remainder is zero then we're done if (iszero(B)) { push(Q); restore(); return; } // A = factor(A) push(A); push(X); factorpoly(); A = pop(); expand_get_C(); expand_get_B(); expand_get_A(); if (istensor(C)) { push(C); inv(); push(B); inner(); push(A); inner(); } else { push(B); push(C); divide(); push(A); multiply(); } push(Q); add(); restore(); }