1 |
|
2 |
|
3 | Eval_rationalize = ->
|
4 | push(cadr(p1))
|
5 | Eval()
|
6 | rationalize()
|
7 |
|
8 | rationalize = ->
|
9 | x = expanding
|
10 | save()
|
11 | yyrationalize()
|
12 | restore()
|
13 | expanding = x
|
14 |
|
15 | yyrationalize = ->
|
16 | p1 = pop()
|
17 |
|
18 | if (istensor(p1))
|
19 | __rationalize_tensor()
|
20 | return
|
21 |
|
22 | expanding = 0
|
23 |
|
24 | if (car(p1) != symbol(ADD))
|
25 | push(p1)
|
26 | return
|
27 |
|
28 | if DEBUG
|
29 | printf("rationalize: this is the input expr:\n")
|
30 | printline(p1)
|
31 |
|
32 |
|
33 |
|
34 | push(one)
|
35 | multiply_denominators(p1)
|
36 | p2 = pop()
|
37 |
|
38 | if DEBUG
|
39 | printf("rationalize: this is the common denominator:\n")
|
40 | printline(p2)
|
41 |
|
42 |
|
43 |
|
44 | push(zero)
|
45 | p3 = cdr(p1)
|
46 | while (iscons(p3))
|
47 | push(p2)
|
48 | push(car(p3))
|
49 | multiply()
|
50 | add()
|
51 | p3 = cdr(p3)
|
52 |
|
53 | if DEBUG
|
54 | printf("rationalize: original expr times common denominator:\n")
|
55 | printline(stack[tos - 1])
|
56 |
|
57 |
|
58 |
|
59 | Condense()
|
60 |
|
61 | if DEBUG
|
62 | printf("rationalize: after factoring:\n")
|
63 | printline(stack[tos - 1])
|
64 |
|
65 |
|
66 |
|
67 | push(p2)
|
68 | divide()
|
69 |
|
70 | if DEBUG
|
71 | printf("rationalize: after dividing by common denom. (and we're done):\n")
|
72 | printline(stack[tos - 1])
|
73 |
|
74 | multiply_denominators = (p) ->
|
75 | if (car(p) == symbol(ADD))
|
76 | p = cdr(p)
|
77 | while (iscons(p))
|
78 | multiply_denominators_term(car(p))
|
79 | p = cdr(p)
|
80 | else
|
81 | multiply_denominators_term(p)
|
82 |
|
83 | multiply_denominators_term = (p) ->
|
84 | if (car(p) == symbol(MULTIPLY))
|
85 | p = cdr(p)
|
86 | while (iscons(p))
|
87 | multiply_denominators_factor(car(p))
|
88 | p = cdr(p)
|
89 | else
|
90 | multiply_denominators_factor(p)
|
91 |
|
92 | multiply_denominators_factor = (p) ->
|
93 | if (car(p) != symbol(POWER))
|
94 | return
|
95 |
|
96 | push(p)
|
97 |
|
98 | p = caddr(p)
|
99 |
|
100 |
|
101 |
|
102 | if (isnegativenumber(p))
|
103 | inverse()
|
104 | __lcm()
|
105 | return
|
106 |
|
107 |
|
108 |
|
109 | if (car(p) == symbol(MULTIPLY) && isnegativenumber(cadr(p)))
|
110 | inverse()
|
111 | __lcm()
|
112 | return
|
113 |
|
114 |
|
115 |
|
116 | pop()
|
117 |
|
118 | __rationalize_tensor = ->
|
119 |
|
120 | i = 0
|
121 | push(p1)
|
122 |
|
123 | Eval();
|
124 |
|
125 | p1 = pop()
|
126 |
|
127 | if (!istensor(p1))
|
128 | push(p1)
|
129 | return
|
130 |
|
131 | n = p1.tensor.nelem
|
132 |
|
133 | for i in [0...n]
|
134 | push(p1.tensor.elem[i])
|
135 | rationalize()
|
136 | p1.tensor.elem[i] = pop()
|
137 |
|
138 | check_tensor_dimensions p1
|
139 |
|
140 |
|
141 | push(p1)
|
142 |
|
143 |
|
144 |
|
145 | __lcm = ->
|
146 | save()
|
147 |
|
148 | p1 = pop()
|
149 | p2 = pop()
|
150 |
|
151 | push(p1)
|
152 | push(p2)
|
153 | multiply()
|
154 | push(p1)
|
155 | push(p2)
|
156 | gcd()
|
157 | divide()
|
158 |
|
159 | restore()
|