-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcondense.cpp
109 lines (82 loc) · 1.65 KB
/
condense.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
// Condense an expression by factoring common terms.
#include "stdafx.h"
#include "defs.h"
void
eval_condense(void)
{
push(cadr(p1));
eval();
Condense();
}
void
Condense(void)
{
int tmp;
tmp = expanding;
save();
yycondense();
restore();
expanding = tmp;
}
void
yycondense(void)
{
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();
push(zero);
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).
yyexpand();
// multiply result by gcd
push(p2);
divide();
}
#if SELFTEST
static const char *s[] = {
"condense(a/(a+b)+b/(a+b))",
"1",
"psi(n) = exp(-r/n) laguerre(2r/n,n-1,1)",
"",
"psi(3)",
"3*exp(-1/3*r)-2*r*exp(-1/3*r)+2/9*r^2*exp(-1/3*r)",
"condense(last)",
"exp(-1/3*r)*(3-2*r+2/9*r^2)",
"psi()=psi",
"",
// test case H
"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)",
"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 *));
}
#endif