eigenmath/condense.cpp

110 lines
1.6 KiB
C++
Raw Permalink Normal View History

2006-01-04 22:26:50 +01:00
// Condense an expression by factoring common terms.
2004-03-03 21:24:06 +01:00
2006-01-04 22:26:50 +01:00
#include "stdafx.h"
2004-03-03 21:24:06 +01:00
#include "defs.h"
void
eval_condense(void)
{
push(cadr(p1));
eval();
2006-01-15 00:55:11 +01:00
Condense();
2004-03-03 21:24:06 +01:00
}
void
2006-01-15 00:55:11 +01:00
Condense(void)
2004-03-03 21:24:06 +01:00
{
int tmp;
tmp = expanding;
save();
2006-01-04 22:26:50 +01:00
yycondense();
2004-03-03 21:24:06 +01:00
restore();
expanding = tmp;
}
2006-01-04 22:26:50 +01:00
void
yycondense(void)
2004-03-03 21:24:06 +01:00
{
expanding = 0;
p1 = pop();
if (car(p1) != symbol(ADD)) {
push(p1);
return;
}
// get gcd of all terms
p3 = cdr(p1);
push(car(p3));
p3 = cdr(p3);
while (iscons(p3)) {
push(car(p3));
gcd();
p3 = cdr(p3);
}
//printf("condense: this is the gcd of all the terms:\n");
//print(stdout, stack[tos - 1]);
// divide each term by gcd
inverse();
p2 = pop();
2004-06-25 22:45:15 +02:00
push(zero);
2004-03-03 21:24:06 +01:00
p3 = cdr(p1);
while (iscons(p3)) {
push(p2);
push(car(p3));
multiply();
add();
p3 = cdr(p3);
}
// We multiplied above w/o expanding so sum factors cancelled.
// Now we expand which which normalizes the result and, in some cases,
// simplifies it too (see test case H).
2008-04-12 05:28:17 +02:00
yyexpand();
2004-03-03 21:24:06 +01:00
// multiply result by gcd
push(p2);
divide();
}
2007-05-08 16:57:30 +02:00
#if SELFTEST
2004-03-03 21:24:06 +01:00
static char *s[] = {
"condense(a/(a+b)+b/(a+b))",
"1",
"psi(n) = exp(-r/n) laguerre(2r/n,n-1,1)",
"",
"psi(3)",
2006-08-23 01:37:52 +02:00
"3*exp(-1/3*r)-2*r*exp(-1/3*r)+2/9*r^2*exp(-1/3*r)",
2004-03-03 21:24:06 +01:00
"condense(last)",
"exp(-1/3*r)*(3-2*r+2/9*r^2)",
"psi()=psi",
"",
// test case H
2008-06-21 06:31:30 +02:00
"condense(-3 exp(-1/3 r + i phi) cos(theta) - 6 exp(-1/3 r + i phi) cos(theta) sin(theta)^2 + 12 exp(-1/3 r + i phi) cos(theta)^3)",
2004-03-03 21:24:06 +01:00
"3*exp(-1/3*r+i*phi)*(-1+4*cos(theta)^2-2*sin(theta)^2)*cos(theta)",
};
void
test_condense(void)
{
test(__FILE__, s, sizeof s / sizeof (char *));
}
2007-05-08 16:57:30 +02:00
#endif