Little fix after the last commit (mostly a git fail)
[eigenmath-fx.git] / outer.cpp
blob67caf9cfcd54528a93d3173b1fd3f7afe9d9f2e2
1 // Outer product of tensors
3 #include "stdafx.h"
4 #include "defs.h"
6 void
7 eval_outer(void)
9 p1 = cdr(p1);
10 push(car(p1));
11 eval();
12 p1 = cdr(p1);
13 while (iscons(p1)) {
14 push(car(p1));
15 eval();
16 outer();
17 p1 = cdr(p1);
21 void
22 outer(void)
24 save();
25 p2 = pop();
26 p1 = pop();
27 if (istensor(p1) && istensor(p2))
28 yyouter();
29 else {
30 push(p1);
31 push(p2);
32 if (istensor(p1))
33 tensor_times_scalar();
34 else if (istensor(p2))
35 scalar_times_tensor();
36 else
37 multiply();
39 restore();
42 void
43 yyouter(void)
45 int i, j, k, ndim, nelem;
47 ndim = p1->u.tensor->ndim + p2->u.tensor->ndim;
49 if (ndim > MAXDIM)
50 stop("outer: rank of result exceeds maximum");
52 nelem = p1->u.tensor->nelem * p2->u.tensor->nelem;
54 p3 = alloc_tensor(nelem);
56 p3->u.tensor->ndim = ndim;
58 for (i = 0; i < p1->u.tensor->ndim; i++)
59 p3->u.tensor->dim[i] = p1->u.tensor->dim[i];
61 j = i;
63 for (i = 0; i < p2->u.tensor->ndim; i++)
64 p3->u.tensor->dim[j + i] = p2->u.tensor->dim[i];
66 k = 0;
68 for (i = 0; i < p1->u.tensor->nelem; i++)
69 for (j = 0; j < p2->u.tensor->nelem; j++) {
70 push(p1->u.tensor->elem[i]);
71 push(p2->u.tensor->elem[j]);
72 multiply();
73 p3->u.tensor->elem[k++] = pop();
76 push(p3);
79 #if SELFTEST
81 static char *s[] = {
83 "outer(a,b)",
84 "a*b",
86 "outer(a,(b1,b2))",
87 "(a*b1,a*b2)",
89 "outer((a1,a2),b)",
90 "(a1*b,a2*b)",
92 "H33=hilbert(3)",
93 "",
95 "H44=hilbert(4)",
96 "",
98 "H55=hilbert(5)",
99 "",
101 "H3344=outer(H33,H44)",
104 "H4455=outer(H44,H55)",
107 "H33444455=outer(H33,H44,H44,H55)",
110 "simplify(inner(H3344,H4455)-contract(H33444455,4,5))",
111 "0",
114 void
115 test_outer(void)
117 test(__FILE__, s, sizeof s / sizeof (char *));
120 #endif