packages feed

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 |] |]"