egison-5.1.0: test/lib/math/tensor.egi
--
-- Originally auto-generated by egison-translator; modernized for the
-- typed CAS: free index symbols are introduced with withSymbols (the
-- bare names warned as unbound), and one case that predates the typed
-- syntax is deliberately absent:
-- * "append indices with ..." used a let-bound %-parameter
-- (f %B := B..._j), which no longer parses at let level; the "..."
-- index feature itself is covered by
-- sample/math/geometry/hodge-laplacian-polar.egi.
-- The function-expr case is back below with the canonical positional
-- derivative index (design/function-symbol.md, decided 2026-07-07).
--
declare symbol x, y, z
assertEqual
"bare tensor signature keeps anonymous order"
(tensorSignature [|1, 2|], dfOrder [|1, 2|])
(([2], []), 1)
withSymbols [i]
(assertEqual
"tensor signature exposes a subscript"
(tensorSignature [|1, 2|]_i, dfOrder [|1, 2|]_i)
(([2], [SubIndex i]), 0))
withSymbols [i]
(assertEqual
"tensor signature exposes a superscript"
(tensorSignature [|1, 2|]~i, dfOrder [|1, 2|]~i)
(([2], [SupIndex i]), 0))
withSymbols [i, j]
(assertEqual
"tensor variance names are available to downstream runtimes"
(tensorVariances [| [|1, 2|], [|3, 4|] |]~i_j)
["up", "down"])
withSymbols [i]
(assertEqual
"tensor signature exposes a diagonal product index"
(tensorSignature ([|1, 2|]~i * [|3, 4|]_i),
dfOrder ([|1, 2|]~i * [|3, 4|]_i))
(([2], [DiagIndex i]), 0))
def traceWithDynamicRefs X :=
withSymbols [i]
sum (contract (subrefs (suprefs X [i]) [i]))
assertEqual
"dynamic tensor refs preserve indices on a function parameter"
(traceWithDynamicRefs [| [|11, 12|], [|21, 22|] |])
33
def matrixOperatorInput : Matrix MathValue :=
[| [|1, 2|], [|3, 4|] |]
assertEqual "matrix trace" (trace matrixOperatorInput) 5
assertEqual
"symmetric matrix part"
(sym matrixOperatorInput)
[| [|1, 5 / 2|], [|5 / 2, 4|] |]
assertEqual
"antisymmetric matrix part"
(antisym matrixOperatorInput)
[| [|0, -1 / 2|], [|1 / 2, 0|] |]
assertEqual
"symmetric and antisymmetric parts reconstruct a matrix"
(sym matrixOperatorInput + antisym matrixOperatorInput)
matrixOperatorInput
withSymbols [i, j]
(assertEqual
"matrix operators preserve all ordinary variance sequences"
(map
(\A ->
(tensorIndices (sym A), dfOrder (sym A),
tensorIndices (antisym A), dfOrder (antisym A)))
[matrixOperatorInput_i_j, matrixOperatorInput_i~j,
matrixOperatorInput~i_j, matrixOperatorInput~i~j])
[([SubIndex i, SubIndex j], 0, [SubIndex i, SubIndex j], 0),
([SubIndex i, SupIndex j], 0, [SubIndex i, SupIndex j], 0),
([SupIndex i, SubIndex j], 0, [SupIndex i, SubIndex j], 0),
([SupIndex i, SupIndex j], 0, [SupIndex i, SupIndex j], 0)])
withSymbols [i]
(assertEqual
"contractWith accepts an explicit reducer"
(contractWith (*) matrixOperatorInput~i_i)
4)
assertEqual
"named wedge uses the differential-form library definition"
(wedge [|1, 2|] [|3, 4|])
[| [|3, 4|], [|6, 8|] |]
withSymbols [i]
(assertEqual
"MathValue dot uses the shared contraction kernel"
([|1, 2|]~i .' [|3, 4|]_i)
11)
assertEqual
"withSymbols removes temporary tensor indices on exit"
(tensorSignature (withSymbols [i] [|1, 2|]_i),
dfOrder (withSymbols [i] [|1, 2|]_i))
(([2], []), 1)
withSymbols [i, j, k]
(assertEqual
"Tensor product - case 1"
([|[|1, 1|], [|0, 1|]|]~i~j . [|[|1, 1|], [|0, 1|]|]_j_k)
[|[|1, 2|], [|0, 1|]|])
withSymbols [i, j, k, l]
(assertEqual
"Tensor product - case 2"
([|[|1, 1|], [|0, 1|]|]~i~j . [|[|1, 1|], [|0, 1|]|]_j~k . [|[|1, 1|]
, [|0, 1|]|]_k_l)
[|[|1, 3|], [|0, 1|]|]~i_l)
assertEqual "Vector *" (V.* [|1, 1, 0|] [|10, 5, 10|]) 15
assertEqual
"Matrix *"
(M.* [|[|1, 1|], [|0, 1|]|] [|[|1, 1|], [|0, 1|]|])
[|[|1, 2|], [|0, 1|]|]
assertEqual
"Matrix determinant"
(M.det [|[|1, 1|], [|0, 1|]|])
1
assertEqual "Tensor '+' - case 1" (1 + [|1, 2, 3|]) [|2, 3, 4|]
assertEqual "Tensor '+' - case 2" ([|1, 2, 3|] + 1) [|2, 3, 4|]
withSymbols [i, j]
(assertEqual
"Tensor '+' - case 3"
([|[|11, 12|], [|21, 22|], [|31, 32|]|]_i_j + [|100, 200, 300|]_i)
[|[|111, 112|], [|221, 222|], [|331, 332|]|]_i_j)
withSymbols [i, j]
(assertEqual
"Tensor '+' - case 4"
([|100, 200, 300|]_i + [|[|11, 12|], [|21, 22|], [|31, 32|]|]_i_j)
[|[|111, 112|], [|221, 222|], [|331, 332|]|]_i_j)
withSymbols [i, j]
(assertEqual
"Tensor '+' - case 5"
([|[|1, 2, 3|], [|10, 20, 30|]|]_i_j + [|100, 200, 300|]_j)
[|[|101, 202, 303|], [|110, 220, 330|]|]_i_j)
withSymbols [i, j]
(assertEqual
"Tensor '+' - case 6"
([|100, 200, 300|]_j + [|[|1, 2, 3|], [|10, 20, 30|]|]_i_j)
[|[|101, 110|], [|202, 220|], [|303, 330|]|]_j_i)
assertEqual
"generate_tensor completes omitted function-symbol indices"
(let E := generateTensor (\[i] -> function (x, y, z)) [3]
in show E)
"[| E_1 x y z, E_2 x y z, E_3 x y z |]"
assertEqual
"generate_tensor completes all omitted function-symbol indices"
(let T := generateTensor (\[i, j] -> function (x, y, z)) [2, 3]
in show T_2_3)
"T_2_3 x y z"
assertEqual
"generate_tensor preserves explicit variance and completes omitted axes"
(let H~i := generateTensor (\[i, j] -> function (x, y, z)) [2, 2]
in show H~2_1)
"H~2_1 x y z"
assertEqual
"nested generate_tensor accumulates function-symbol indices"
(let A := generateTensor
(\[i] -> generateTensor (\[j] -> function (x)) [2])
[2]
in show A)
"[| [| A_1_1 x, A_1_2 x |], [| A_2_1 x, A_2_2 x |] |]"
assertEqual
"nested generate_tensor preserves completed explicit indices"
(let A~i := generateTensor
(\[i] -> generateTensor (\[j] -> function (x)) [2])
[2]
in show (withSymbols [i] A~i))
"[| [| A~1_1 x, A~1_2 x |], [| A~2_1 x, A~2_2 x |] |]"
assertEqual
"generate_tensor does not rename referenced function symbols"
(let f := function (x, y)
in let R := generateTensor (\_ -> f) [3]
in show R)
"[| f x y, f x y, f x y |]"
assertEqual
"generate_tensor by using function expr"
(let g_i_j := (generateTensor
(\match as list integer with
| [$n, #n] -> function (x, y, z)
| _ -> 0)
[3, 3])_i_j
in show (withSymbols [i, j] d/d g_i_j x))
"[| [| g_1_1|1 x y z, 0, 0 |], [| 0, g_2_2|1 x y z, 0 |], [| 0, 0, g_3_3|1 x y z |] |]"