1 // Partial fraction expansion
5 // expand(1/(x^3+x^2),x)
8 // ---- - --- + -------
29 if (p2
== symbol(NIL
))
60 // if sum of terms then sum over the expansion of each term
62 if (car(F
) == symbol(ADD
)) {
88 remove_negative_exponents();
98 // remainder B = B - A * Q
107 // if the remainder is zero then we're done
154 for (i
= 0; i
< F
->u
.tensor
->nelem
; i
++) {
155 push(F
->u
.tensor
->elem
[i
]);
158 F
->u
.tensor
->elem
[i
] = pop();
164 remove_negative_exponents(void)
173 // find the smallest exponent
176 for (i
= 0; i
< n
; i
++) {
178 if (car(p1
) != symbol(POWER
))
184 if (k
== (int) 0x80000000)
214 // Returns the expansion coefficient matrix C.
226 // --- = ---- + ---- + -------
230 // Our task is to solve for the unknowns Y1, Y2, and Y3.
232 // Multiplying both sides by A yields
235 // B = ----- + ----- + -------
242 // W1 = ---- W2 = --- W3 = -------
246 // Then the coefficient matrix C is
248 // coeff(W1,x,0) coeff(W2,x,0) coeff(W3,x,0)
250 // C = coeff(W1,x,1) coeff(W2,x,1) coeff(W3,x,1)
252 // coeff(W1,x,2) coeff(W2,x,2) coeff(W3,x,2)
258 // coeff(B,x,1) = C Y2
266 // Y2 = C coeff(B,x,1)
276 if (car(A
) == symbol(MULTIPLY
)) {
292 C
= alloc_tensor(n
* n
);
293 C
->u
.tensor
->ndim
= 2;
294 C
->u
.tensor
->dim
[0] = n
;
295 C
->u
.tensor
->dim
[1] = n
;
297 for (i
= 0; i
< n
; i
++) {
298 for (j
= 0; j
< n
; j
++) {
306 C
->u
.tensor
->elem
[n
* i
+ j
] = pop();
312 // The following table shows the push order for simple roots, repeated roots,
313 // and inrreducible factors.
315 // Factor F Push 1st Push 2nd Push 3rd Push 4th
335 // (x + 1) ---------- -------
341 // x + x + 1 ------------ ------------
343 // x + x + 1 x + x + 1
347 // (x + x + 1) --------------- --------------- ------------ ------------
349 // (x + x + 1) (x + x + 1) x + x + 1 x + x + 1
352 // For T = A/F and F = P^N we have
355 // Factor F Push 1st Push 2nd Push 3rd Push 4th
372 // (x + x + 1) T TX TP TPX
375 // Hence we want to push in the order
377 // T * (P ^ i) * (X ^ j)
379 // for all i, j such that
381 // i = 0, 1, ..., N - 1
383 // j = 0, 1, ..., deg(P) - 1
385 // where index j runs first.
393 if (car(F
) == symbol(POWER
)) {
405 for (i
= 0; i
< n
; i
++) {
406 for (j
= 0; j
< d
; j
++) {
420 // Returns T = A/F where F is a factor of A.
426 if (car(A
) == symbol(MULTIPLY
)) {
430 if (!equal(car(p0
), F
)) {
432 eval(); // force expansion of (x+1)^2, f.e.
436 multiply_all(tos
- h
);
442 // Returns the expansion coefficient vector B.
450 n
= C
->u
.tensor
->dim
[0];
452 T
->u
.tensor
->ndim
= 1;
453 T
->u
.tensor
->dim
[0] = n
;
454 for (i
= 0; i
< n
; i
++) {
462 T
->u
.tensor
->elem
[i
] = pop();
467 // Returns the expansion fractions in A.
480 if (car(A
) == symbol(MULTIPLY
)) {
493 T
->u
.tensor
->ndim
= 1;
494 T
->u
.tensor
->dim
[0] = n
;
495 for (i
= 0; i
< n
; i
++)
496 T
->u
.tensor
->elem
[i
] = stack
[h
+ i
];
503 { int d
, i
, j
, n
= 1;
506 if (car(F
) == symbol(POWER
)) {
515 for (i
= n
; i
> 0; i
--) {
516 for (j
= 0; j
< d
; j
++) {
535 "expand(1/(x+1)/(x+2))",
538 "expand((2x^3-x+2)/(x^2-2x+1))",
539 "4+2*x+5/(x-1)+3/(x^2-2*x+1)",
541 "expand(1/x^2/(x-1))",
542 "-1/(x^2)-1/x+1/(x-1)",
551 "-3/(s+1)+3/(s+2)+8/(s^2+4*s+4)",
553 // ensure denominators are expanded (result seems preferable that way)
559 "1/(x^3-6*x^2+12*x-8)+1/(x-2)-1/(x-1)-1/(x^2-4*x+4)",
563 "expand(1/(x+1/2)/(x+1/3))",
564 "-12/(2*x+1)+18/(3*x+1)",
574 "expand(((f,f),(f,f)))-((g,g),(g,g))",
577 // denominator normalized?
587 "expand(1/x^2/(x+1))",
588 "x^(-2)-1/x+1/(x+1)",
590 // other corner cases
598 "expand(1/(x^2-4x+4))",
605 test(__FILE__
, s
, sizeof s
/ sizeof (char *));