-
Notifications
You must be signed in to change notification settings - Fork 0
/
IndexTensor.m
68 lines (53 loc) · 1.84 KB
/
IndexTensor.m
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
(* ::Package:: *)
Begin["IndexNotation`Private`"];
With[
{
IT = IndexNotation`IndexTensor,
TI = IndexNotation`TensorIndex,
ScT = IndexNotation`Scope`Transform,
indexfunc = IndexNotation`DummyIndex
},
(** IndexTensor
*
* IndexTensor[x, TensorIndex[..., {j, 3}, {i, 3}]]
* IndexTensor[IndexTensor[x, TensorIndex[..., {j, 3}]], TensorIndex[{i, 3}]]
*
* - It's not recommanded to write IndexTensor[x, TensorIndex[__List]] directly.
* Write IndexTensor[x, __List] instead to enable scope checking.
* - Allow using IT[x, {i,3}, {j,3}] to build index notation tensor
* - Reverse the order of vrs to makes {j,3} inner-most item / first item to contract,
* compatible with mathematica's "Table" function.
* - Derivation on x adds item on the side of {j,3}, compatible with tensorial calculus.
* - Syntax highlight in Mathematica front-end is supported.
*)
SetAttributes[IT, {NHoldRest}];
SetAttributes[TI, {}];
IT[ x_, TI[] ] := x;
IT[x_] := x;
(* Enable direct unpacking assignment *)
IT /: ( IT[x1_, vrs1_] = IT[x2_, vrs2_, opt2___] ) := (
x1 = x2;
vrs1 = vrs2;
);
IT /: ( IT[x1_, vrs1_] = x2_ ) := (
x1 = x2;
vrs1 = TI[];
);
IT /: ( IT[x1_, vrs1_, opt1_] = IT[x2_, vrs2_, opt2___] ) := (
x1 = x2;
vrs1 = vrs2;
opt1 = opt2;
);
(* grammar sugar *)
t : IT[x_, vrl__List] := If[
DuplicateFreeQ[ {vrl}[[All, 1]] ],
ScT[indexfunc] @ Fold[ IT[#1, TI[#2]]&, x, Reverse @ {vrl} ],
Hold[t]
];
Options[IT] = {Type -> "Normal"}; (* Options[] must be placed before SyntaxInformation[] *)
SyntaxInformation[IT] = {
"LocalVariables" -> { "Table", {0, Infinity} },
"ArgumentsPattern" -> { __, OptionsPattern[] }
};
]
End[];