124 |
type dim = int |
type dim = int |
125 |
type shape = dim list |
type shape = dim list |
126 |
type ids = int list |
type ids = int list |
127 |
val subst_flag = false |
|
128 |
|
(* controls whether tensor operations should be *) |
129 |
|
val canSubst = true |
130 |
|
|
131 |
|
(* A constructor function for tensor variables that (by default) can be substituted for; |
132 |
|
* this behavior is controlled by the canSubst flag. |
133 |
|
*) |
134 |
|
fun mkTEN alpha = E.TEN(canSubst, alpha) |
135 |
|
|
136 |
|
(* a constructor function for tensor parameters that should never be substituted for. *) |
137 |
|
fun mkNoSubstTEN alpha = E.TEN(false, alpha) |
138 |
|
|
139 |
fun specialize (alpha, inc) = List.mapi (fn (i, _) => E.V(i + inc)) alpha |
fun specialize (alpha, inc) = List.mapi (fn (i, _) => E.V(i + inc)) alpha |
140 |
|
|
141 |
fun sumIds (n, inc, alpha) = let |
fun sumIds (n, inc, alpha) = let |
153 |
val expindex = specialize(alpha, 0) |
val expindex = specialize(alpha, 0) |
154 |
in |
in |
155 |
E.EIN{ |
E.EIN{ |
156 |
params = [E.TEN(subst_flag, alpha), E.TEN(subst_flag, alpha)], |
params = [mkTEN alpha, mkTEN alpha], |
157 |
index = alpha, |
index = alpha, |
158 |
body = E.Opn(E.Add, [E.Tensor(0, expindex), E.Tensor(1, expindex)]) |
body = E.Opn(E.Add, [E.Tensor(0, expindex), E.Tensor(1, expindex)]) |
159 |
} |
} |
166 |
val expindex = specialize(shape, 0) |
val expindex = specialize(shape, 0) |
167 |
in |
in |
168 |
E.EIN{ |
E.EIN{ |
169 |
params = [E.TEN(subst_flag, shape), E.FLD dim], |
params = [mkTEN shape, E.FLD dim], |
170 |
index = shape, |
index = shape, |
171 |
body = E.Opn(E.Add, [E.Lift(E.Tensor(0, expindex)), E.Field(1, expindex)]) |
body = E.Opn(E.Add, [E.Lift(E.Tensor(0, expindex)), E.Field(1, expindex)]) |
172 |
} |
} |
189 |
val expindex = specialize(alpha, 0) |
val expindex = specialize(alpha, 0) |
190 |
in |
in |
191 |
E.EIN{ |
E.EIN{ |
192 |
params = [E.TEN(subst_flag, alpha), E.TEN(subst_flag, alpha)], |
params = [mkTEN alpha, mkTEN alpha], |
193 |
index = alpha, |
index = alpha, |
194 |
body = E.Op2(E.Sub, E.Tensor(0, expindex), E.Tensor(1, expindex)) |
body = E.Op2(E.Sub, E.Tensor(0, expindex), E.Tensor(1, expindex)) |
195 |
} |
} |
201 |
val expindex = specialize(shape, 0) |
val expindex = specialize(shape, 0) |
202 |
in |
in |
203 |
E.EIN{ |
E.EIN{ |
204 |
params = [E.TEN(subst_flag, shape), E.FLD dim], |
params = [mkTEN shape, E.FLD dim], |
205 |
index = shape, |
index = shape, |
206 |
body = E.Opn(E.Add, |
body = E.Opn(E.Add, |
207 |
[E.Lift(E.Tensor(0, expindex)), E.Op1(E.Neg, E.Field(1, expindex))]) |
[E.Lift(E.Tensor(0, expindex)), E.Op1(E.Neg, E.Field(1, expindex))]) |
212 |
val expindex = specialize(shape, 0) |
val expindex = specialize(shape, 0) |
213 |
in |
in |
214 |
E.EIN{ |
E.EIN{ |
215 |
params = [E.TEN(subst_flag, shape), E.FLD dim], |
params = [mkTEN shape, E.FLD dim], |
216 |
index = shape, |
index = shape, |
217 |
body = E.Op2(E.Sub, E.Field(1, expindex), E.Lift(E.Tensor(0, expindex))) |
body = E.Op2(E.Sub, E.Field(1, expindex), E.Lift(E.Tensor(0, expindex))) |
218 |
} |
} |
235 |
val expindex = specialize(alpha, 0) |
val expindex = specialize(alpha, 0) |
236 |
in |
in |
237 |
E.EIN{ |
E.EIN{ |
238 |
params = [E.TEN(subst_flag, []), E.TEN(subst_flag,alpha)], |
params = [mkTEN [], mkTEN alpha], |
239 |
index = alpha, |
index = alpha, |
240 |
body = E.Opn(E.Prod, [E.Tensor(0, []), E.Tensor(1, expindex)]) |
body = E.Opn(E.Prod, [E.Tensor(0, []), E.Tensor(1, expindex)]) |
241 |
} |
} |
247 |
val expindex = specialize(shape, 0) |
val expindex = specialize(shape, 0) |
248 |
in |
in |
249 |
E.EIN{ |
E.EIN{ |
250 |
params = [E.TEN(subst_flag, []), E.FLD dim], |
params = [mkTEN [], E.FLD dim], |
251 |
index = shape, |
index = shape, |
252 |
body = E.Opn(E.Prod, [E.Lift( E.Tensor(0, [])), E.Field(1,expindex)]) |
body = E.Opn(E.Prod, [E.Lift( E.Tensor(0, [])), E.Field(1,expindex)]) |
253 |
} |
} |
257 |
val expindex = specialize(shape, 0) |
val expindex = specialize(shape, 0) |
258 |
in |
in |
259 |
E.EIN{ |
E.EIN{ |
260 |
params = [E.TEN(subst_flag,shape), E.FLD dim], |
params = [mkTEN shape, E.FLD dim], |
261 |
index = shape, |
index = shape, |
262 |
body = E.Opn(E.Prod, [E.Lift( E.Tensor(0,expindex)), E.Field(1, [])]) |
body = E.Opn(E.Prod, [E.Lift( E.Tensor(0,expindex)), E.Field(1, [])]) |
263 |
} |
} |
284 |
val expindex = specialize(alpha, 0) |
val expindex = specialize(alpha, 0) |
285 |
in |
in |
286 |
E.EIN{ |
E.EIN{ |
287 |
params = [E.TEN(subst_flag, alpha), E.TEN(subst_flag, [])], |
params = [mkTEN alpha, mkTEN []], |
288 |
index = alpha, |
index = alpha, |
289 |
body = E.Op2(E.Div, E.Tensor(0, expindex), E.Tensor(1, [])) |
body = E.Op2(E.Div, E.Tensor(0, expindex), E.Tensor(1, [])) |
290 |
} |
} |
296 |
val expindex = specialize(shape, 0) |
val expindex = specialize(shape, 0) |
297 |
in |
in |
298 |
E.EIN{ |
E.EIN{ |
299 |
params = [E.FLD dim, E.TEN(subst_flag, [])], |
params = [E.FLD dim, mkTEN []], |
300 |
index = shape, |
index = shape, |
301 |
body = E.Op2(E.Div, E.Field(0, expindex), E.Lift(E.Tensor(1, []))) |
body = E.Op2(E.Div, E.Field(0, expindex), E.Lift(E.Tensor(1, []))) |
302 |
} |
} |
325 |
(*changed tensor lift variable here *) |
(*changed tensor lift variable here *) |
326 |
in |
in |
327 |
E.EIN { |
E.EIN { |
328 |
params = [E.TEN(subst_flag, alpha)], index = alpha, |
params = [mkTEN alpha], index = alpha, |
329 |
body = E.Op1(E.Neg, E.Tensor(0, expindex)) |
body = E.Op1(E.Neg, E.Tensor(0, expindex)) |
330 |
} |
} |
331 |
end |
end |
343 |
|
|
344 |
(* 2-d cross product Eps_{ij}U_i V_j *) |
(* 2-d cross product Eps_{ij}U_i V_j *) |
345 |
val cross2TT = E.EIN{ |
val cross2TT = E.EIN{ |
346 |
params = [E.TEN(subst_flag, [2]), E.TEN(subst_flag, [2])], |
params = [mkTEN [2], mkTEN [2]], |
347 |
index = [], |
index = [], |
348 |
body = E.Sum([(E. V 0, 0, 1), (E.V 1, 0, 1)], |
body = E.Sum([(E. V 0, 0, 1), (E.V 1, 0, 1)], |
349 |
E.Opn(E.Prod, [E.Eps2(0, 1), E.Tensor(0, [E.V 0]), E.Tensor(1, [E.V 1])])) |
E.Opn(E.Prod, [E.Eps2(0, 1), E.Tensor(0, [E.V 0]), E.Tensor(1, [E.V 1])])) |
351 |
|
|
352 |
(* crossProduct is on 3D vectors ..vec3 t8=t0 × t1; *) |
(* crossProduct is on 3D vectors ..vec3 t8=t0 × t1; *) |
353 |
val cross3TT = E.EIN{ |
val cross3TT = E.EIN{ |
354 |
params = [E.TEN(subst_flag, [3]), E.TEN(subst_flag, [3])], |
params = [mkTEN [3], mkTEN [3]], |
355 |
index = [3], |
index = [3], |
356 |
body = E.Sum([(E.V 1, 0, 2), (E.V 2, 0, 2)], |
body = E.Sum([(E.V 1, 0, 2), (E.V 2, 0, 2)], |
357 |
E.Opn(E.Prod, [ |
E.Opn(E.Prod, [ |
383 |
val expIdxB = specialize (beta, length alpha) |
val expIdxB = specialize (beta, length alpha) |
384 |
in |
in |
385 |
E.EIN{ |
E.EIN{ |
386 |
params = [E.TEN(subst_flag, alpha), E.TEN(subst_flag, beta)], |
params = [mkTEN alpha, mkTEN beta], |
387 |
index = alpha@beta, |
index = alpha@beta, |
388 |
body = E.Opn(E.Prod, [E.Tensor(0, expIdxA), E.Tensor(1, expIdxB)]) |
body = E.Opn(E.Prod, [E.Tensor(0, expIdxA), E.Tensor(1, expIdxB)]) |
389 |
} |
} |
406 |
val expIdxB = specialize (beta, length alpha) |
val expIdxB = specialize (beta, length alpha) |
407 |
in |
in |
408 |
E.EIN{ |
E.EIN{ |
409 |
params = [E.TEN(subst_flag ,alpha), E.FLD dim], |
params = [mkTEN alpha, E.FLD dim], |
410 |
index = alpha@beta, |
index = alpha@beta, |
411 |
body = E.Opn(E.Prod, [E.Lift(E.Tensor(0, expIdxA)), E.Field(1, expIdxB)]) |
body = E.Opn(E.Prod, [E.Lift(E.Tensor(0, expIdxA)), E.Field(1, expIdxB)]) |
412 |
} |
} |
417 |
val expIdxB = specialize(beta, length alpha) |
val expIdxB = specialize(beta, length alpha) |
418 |
in |
in |
419 |
E.EIN{ |
E.EIN{ |
420 |
params = [E.FLD dim, E.TEN(subst_flag,alpha)], |
params = [E.FLD dim, mkTEN alpha], |
421 |
index = alpha@beta, |
index = alpha@beta, |
422 |
body = E.Opn(E.Prod, [E.Field(0, expIdxA), E.Lift(E.Tensor(1, expIdxB))]) |
body = E.Opn(E.Prod, [E.Field(0, expIdxA), E.Lift(E.Tensor(1, expIdxB))]) |
423 |
} |
} |
433 |
val s'' = [(s', 0, i-1)] |
val s'' = [(s', 0, i-1)] |
434 |
in |
in |
435 |
E.EIN{ |
E.EIN{ |
436 |
params = [E.TEN(subst_flag, shape1), E.TEN(subst_flag, i::beta)], |
params = [mkTEN shape1, mkTEN i::beta], |
437 |
index = alpha@beta, |
index = alpha@beta, |
438 |
body = E.Sum(s'', E.Opn(E.Prod, [ |
body = E.Sum(s'', E.Opn(E.Prod, [ |
439 |
E.Tensor(0, expindexA@[s']), (* T_{\alpha i} *) |
E.Tensor(0, expindexA@[s']), (* T_{\alpha i} *) |
469 |
val sid = E.V(length alpha + length beta) |
val sid = E.V(length alpha + length beta) |
470 |
in |
in |
471 |
E.EIN{ |
E.EIN{ |
472 |
params = [E.FLD dim, E.TEN(subst_flag, i::beta)], |
params = [E.FLD dim, mkTEN i::beta], |
473 |
index = alpha@beta, |
index = alpha@beta, |
474 |
body = E.Sum([(sid, 0, i-1)], |
body = E.Sum([(sid, 0, i-1)], |
475 |
E.Opn(E.Prod, [ |
E.Opn(E.Prod, [ |
487 |
val sid = E.V(length(alpha) + length beta) |
val sid = E.V(length(alpha) + length beta) |
488 |
in |
in |
489 |
E.EIN{ |
E.EIN{ |
490 |
params = [E.TEN(subst_flag,shape1), E.FLD dim],index = alpha@beta, |
params = [mkTEN shape1, E.FLD dim], index = alpha@beta, |
491 |
body = E.Sum([(sid, 0, i-1)], |
body = E.Sum([(sid, 0, i-1)], |
492 |
E.Opn(E.Prod, [ |
E.Opn(E.Prod, [ |
493 |
E.Lift(E.Tensor(0, expindexA@[sid])), (* F_{\alpha i} *) |
E.Lift(E.Tensor(0, expindexA@[sid])), (* F_{\alpha i} *) |
510 |
val sx = [(E.V sumi, 0, i-1), (E.V(sumi+1), 0, j-1)] |
val sx = [(E.V sumi, 0, i-1), (E.V(sumi+1), 0, j-1)] |
511 |
in |
in |
512 |
E.EIN{ |
E.EIN{ |
513 |
params = [E.TEN(subst_flag, shape1), E.TEN(subst_flag, i::j::beta)], |
params = [mkTEN shape1, mkTEN i::j::beta], |
514 |
index = alpha@beta, |
index = alpha@beta, |
515 |
body = E.Sum(sx, |
body = E.Sum(sx, |
516 |
E.Opn(E.Prod, [E.Tensor(0, expindexA@s'), E.Tensor(1, s'@expindexB)])) |
E.Opn(E.Prod, [E.Tensor(0, expindexA@s'), E.Tensor(1, s'@expindexB)])) |
547 |
val sx = [(E.V sumi, 0, i-1), (E.V(sumi+1), 0, j-1)] |
val sx = [(E.V sumi, 0, i-1), (E.V(sumi+1), 0, j-1)] |
548 |
in |
in |
549 |
E.EIN{ |
E.EIN{ |
550 |
params = [E.FLD dim, E.TEN(subst_flag,shape1)], |
params = [E.FLD dim, mkTEN shape1], |
551 |
index = alpha@beta, |
index = alpha@beta, |
552 |
body = E.Sum(sx, |
body = E.Sum(sx, |
553 |
E.Opn(E.Prod, [E.Field(0, expindexA@s'), E.Lift(E.Tensor(1, s'@expindexB))])) |
E.Opn(E.Prod, [E.Field(0, expindexA@s'), E.Lift(E.Tensor(1, s'@expindexB))])) |
565 |
val sx = [(E.V sumi, 0, i-1), (E.V(sumi+1), 0, j-1)] |
val sx = [(E.V sumi, 0, i-1), (E.V(sumi+1), 0, j-1)] |
566 |
in |
in |
567 |
E.EIN{ |
E.EIN{ |
568 |
params = [E.TEN(subst_flag, i::j::beta), E.FLD dim], |
params = [mkTEN i::j::beta, E.FLD dim], |
569 |
index = alpha@beta, |
index = alpha@beta, |
570 |
body = E.Sum(sx, |
body = E.Sum(sx, |
571 |
E.Opn(E.Prod, [E.Lift(E.Tensor(0, expindexA@s')), E.Field(1, s'@expindexB)])) |
E.Opn(E.Prod, [E.Lift(E.Tensor(0, expindexA@s')), E.Field(1, s'@expindexB)])) |
579 |
val sx = sumIds(length alpha, 0, alpha) |
val sx = sumIds(length alpha, 0, alpha) |
580 |
in |
in |
581 |
E.EIN{ |
E.EIN{ |
582 |
params = [E.TEN(subst_flag, alpha)], |
params = [mkTEN alpha], |
583 |
index = [], |
index = [], |
584 |
body = E.Op1(E.Sqrt, |
body = E.Op1(E.Sqrt, |
585 |
E.Sum(sx, E.Opn(E.Prod, [E.Tensor(0, expIdx), E.Tensor(0, expIdx)]))) |
E.Sum(sx, E.Opn(E.Prod, [E.Tensor(0, expIdx), E.Tensor(0, expIdx)]))) |
607 |
val g = E.Tensor(1, expindexDot) |
val g = E.Tensor(1, expindexDot) |
608 |
in |
in |
609 |
E.EIN{ |
E.EIN{ |
610 |
params = [E.TEN(subst_flag, alpha), E.TEN(subst_flag, alpha)], |
params = [mkTEN alpha, mkTEN alpha], |
611 |
index = alpha, |
index = alpha, |
612 |
body = E.Opn(E.Prod, [ |
body = E.Opn(E.Prod, [ |
613 |
f, E.Op2(E.Div, E.Const 1, E.Op1(E.Sqrt, E.Sum(sx, E.Opn(E.Prod, [g, g])))) |
f, E.Op2(E.Div, E.Const 1, E.Op1(E.Sqrt, E.Sum(sx, E.Opn(E.Prod, [g, g])))) |
636 |
|
|
637 |
(* Trace: <M_{i, i}> This one Sx represents both i's*) |
(* Trace: <M_{i, i}> This one Sx represents both i's*) |
638 |
fun traceT dim = E.EIN{ |
fun traceT dim = E.EIN{ |
639 |
params = [E.TEN(subst_flag, [dim, dim])], index = [], |
params = [mkTEN [dim, dim]], index = [], |
640 |
body = E.Sum([(E.V 0, 0, dim-1)], E.Tensor(0, [E.V 0, E.V 0])) |
body = E.Sum([(E.V 0, 0, dim-1)], E.Tensor(0, [E.V 0, E.V 0])) |
641 |
} |
} |
642 |
|
|
655 |
(************************* tranpose *************************) |
(************************* tranpose *************************) |
656 |
|
|
657 |
fun transposeT alpha = E.EIN{ |
fun transposeT alpha = E.EIN{ |
658 |
params = [E.TEN(subst_flag, alpha)], |
params = [mkTEN alpha], |
659 |
index = List.rev alpha, |
index = List.rev alpha, |
660 |
body = E.Tensor(0, [E.V 1, E.V 0]) |
body = E.Tensor(0, [E.V 1, E.V 0]) |
661 |
} |
} |
670 |
(************************* determinant *************************) |
(************************* determinant *************************) |
671 |
|
|
672 |
val det2T = E.EIN{ |
val det2T = E.EIN{ |
673 |
params = [E.TEN(false, [2, 2])], |
params = [mkNoSubstTEN [2, 2]], |
674 |
index = [], |
index = [], |
675 |
body = E.Op2(E.Sub, |
body = E.Op2(E.Sub, |
676 |
E.Opn(E.Prod, [E.Tensor(0, [E.C 0, E.C 0]), E.Tensor(0, [E.C 1, E.C 1])]), |
E.Opn(E.Prod, [E.Tensor(0, [E.C 0, E.C 0]), E.Tensor(0, [E.C 1, E.C 1])]), |
689 |
val i = E.Tensor(0, [E.C 2, E.C 2]) |
val i = E.Tensor(0, [E.C 2, E.C 2]) |
690 |
in |
in |
691 |
E.EIN{ |
E.EIN{ |
692 |
params = [E.TEN(false, [3, 3])], |
params = [mkNoSubstTEN [3, 3]], |
693 |
index = [], |
index = [], |
694 |
body = E.Op2(E.Sub, |
body = E.Op2(E.Sub, |
695 |
E.Opn(E.Add, [ |
E.Opn(E.Add, [ |
762 |
|
|
763 |
(************************* Exponential **************************) |
(************************* Exponential **************************) |
764 |
fun expF dim = E.EIN{params = [E.FLD dim], index = [], body = E.Op1(E.Exp, E.Field(0, []))} |
fun expF dim = E.EIN{params = [E.FLD dim], index = [], body = E.Op1(E.Exp, E.Field(0, []))} |
765 |
val expT = E.EIN{params = [E.TEN(false, [])], index = [], body = E.Op1(E.Exp, E.Tensor(0, []))} |
val expT = E.EIN{params = [mkNoSubstTEN []], index = [], body = E.Op1(E.Exp, E.Tensor(0, []))} |
766 |
|
|
767 |
(************************* Lifted single-argument math functions *************************) |
(************************* Lifted single-argument math functions *************************) |
768 |
local |
local |
769 |
fun tensorFn rator = E.EIN{ |
fun tensorFn rator = E.EIN{ |
770 |
params = [E.TEN(false, [])], |
params = [mkNoSubstTEN []], |
771 |
index = [], |
index = [], |
772 |
body = E.Op1(rator, E.Field(0, [])) |
body = E.Op1(rator, E.Field(0, [])) |
773 |
} |
} |
799 |
|
|
800 |
(************************* other tensor ops *************************) |
(************************* other tensor ops *************************) |
801 |
fun modulate dim = E.EIN{ |
fun modulate dim = E.EIN{ |
802 |
params = [E.TEN(subst_flag, [dim]), E.TEN(subst_flag, [dim])], |
params = [mkTEN [dim], mkTEN [dim]], |
803 |
index = [dim], |
index = [dim], |
804 |
body = E.Opn(E.Prod, [E.Tensor(0, [E.V 0]), E.Tensor(1, [E.V 0])]) |
body = E.Opn(E.Prod, [E.Tensor(0, [E.V 0]), E.Tensor(1, [E.V 0])]) |
805 |
} |
} |
823 |
val ix = iter(mask, const, 0) |
val ix = iter(mask, const, 0) |
824 |
in |
in |
825 |
E.EIN{ |
E.EIN{ |
826 |
params = [E.TEN(subst_flag, argTy)], |
params = [mkTEN argTy], |
827 |
index = rstTy, |
index = rstTy, |
828 |
body = E.Tensor(0, ix) |
body = E.Tensor(0, ix) |
829 |
} |
} |
847 |
val expindex = specialize(alpha, 0) |
val expindex = specialize(alpha, 0) |
848 |
in |
in |
849 |
E.EIN{ |
E.EIN{ |
850 |
params = [E.FLD dim, E.TEN(false, [])], index = alpha, |
params = [E.FLD dim, mkNoSubstTEN []], index = alpha, |
851 |
body = E.Probe(E.Field(0, expindex), E.Tensor(1, [])) |
body = E.Probe(E.Field(0, expindex), E.Tensor(1, [])) |
852 |
} |
} |
853 |
end |
end |
866 |
} |
} |
867 |
|
|
868 |
val curl3d = E.EIN{ |
val curl3d = E.EIN{ |
869 |
params = [E.TEN(subst_flag, [3])], |
params = [mkTEN [3]], |
870 |
index = [3], |
index = [3], |
871 |
body = E.Sum([(E.V 1, 0, 2), (E.V 2, 0, 2)], |
body = E.Sum([(E.V 1, 0, 2), (E.V 2, 0, 2)], |
872 |
E.Opn(E.Prod, [ |
E.Opn(E.Prod, [ |