3 Terms in a sum are combined if they are identical modulo rational
6 For example, A + 2A becomes 3A.
8 However, the sum A + sqrt(2) A is not modified.
10 Combining terms can lead to second-order effects.
12 For example, consider the case of
14 1/sqrt(2) A + 3/sqrt(2) A + sqrt(2) A
16 The first two terms are combined to yield 2 sqrt(2) A.
18 This result can now be combined with the third term to yield
43 /* Add n terms, returns one expression on the stack. */
55 /* ensure no infinite loop, use "for" */
57 for (i
= 0; i
< 10; i
++) {
64 qsort(s
, n
, sizeof (U
*), cmp_terms
);
69 n
= combine_terms(s
, n
);
90 /* Compare terms for order, clobbers p1 and p2. */
93 cmp_terms(const void *q1
, const void *q2
)
100 /* numbers can be combined */
102 if (isnum(p1
) && isnum(p2
)) {
107 /* congruent tensors can be combined */
109 if (istensor(p1
) && istensor(p2
)) {
110 if (p1
->u
.tensor
->ndim
< p2
->u
.tensor
->ndim
)
112 if (p1
->u
.tensor
->ndim
> p2
->u
.tensor
->ndim
)
114 for (i
= 0; i
< p1
->u
.tensor
->ndim
; i
++) {
115 if (p1
->u
.tensor
->dim
[i
] < p2
->u
.tensor
->dim
[i
])
117 if (p1
->u
.tensor
->dim
[i
] > p2
->u
.tensor
->dim
[i
])
124 if (car(p1
) == symbol(MULTIPLY
)) {
126 if (isnum(car(p1
))) {
128 if (cdr(p1
) == symbol(NIL
))
133 if (car(p2
) == symbol(MULTIPLY
)) {
135 if (isnum(car(p2
))) {
137 if (cdr(p2
) == symbol(NIL
))
142 t
= cmp_expr(p1
, p2
);
150 /* Compare adjacent terms in s[] and combine if possible.
152 Returns the number of terms remaining in s[].
154 n number of terms in s[] initially
158 combine_terms(U
**s
, int n
)
162 for (i
= 0; i
< n
- 1; i
++) {
168 if (istensor(p3
) && istensor(p4
)) {
171 tensor_plus_tensor();
173 if (p1
!= symbol(NIL
)) {
175 for (j
= i
+ 1; j
< n
- 1; j
++)
183 if (istensor(p3
) || istensor(p4
))
186 if (isnum(p3
) && isnum(p4
)) {
192 for (j
= i
; j
< n
- 2; j
++)
197 for (j
= i
+ 1; j
< n
- 1; j
++)
205 if (isnum(p3
) || isnum(p4
))
213 if (car(p3
) == symbol(MULTIPLY
)) {
215 t
= 1; /* p3 is now denormal */
216 if (isnum(car(p3
))) {
219 if (cdr(p3
) == symbol(NIL
)) {
226 if (car(p4
) == symbol(MULTIPLY
)) {
228 if (isnum(car(p4
))) {
231 if (cdr(p4
) == symbol(NIL
))
246 for (j
= i
; j
< n
- 2; j
++)
256 push(symbol(MULTIPLY
));
266 for (j
= i
+ 1; j
< n
- 1; j
++)
279 if (car(p
) == symbol(ADD
)) {
285 } else if (!iszero(p
))
289 /* add two expressions */
313 for (i
= 0; i
< k
; i
++)