packages feed

egison-5.1.0: lib/math/algebra/tensor.egi

--
--
-- Tensor
--
--

inductive TensorIndex :=
  | SubIndex MathValue
  | SupIndex MathValue
  | DiagIndex MathValue
  | UserIndex MathValue

inductive pattern TensorIndex :=
  | subIndex MathValue
  | supIndex MathValue
  | diagIndex MathValue
  | userIndex MathValue

def tensorIndex : Matcher TensorIndex :=
  algebraicDataMatcher
    | subIndex mathValue
    | supIndex mathValue
    | diagIndex mathValue
    | userIndex mathValue

infixl expression 7 .
infixl expression 7 .'

def tensorOrder {a} (A: Tensor a) : Integer := length (tensorShape A)

def tensorSignature {a} (A: Tensor a) : ([Integer], [TensorIndex]) :=
  (tensorShape A, tensorIndices A)

def tensorIndexVariance (index: TensorIndex) : String :=
  match index as tensorIndex with
    | subIndex _ -> "down"
    | supIndex _ -> "up"
    | diagIndex _ -> "diag"
    | userIndex _ -> "user"

def tensorVariances {a} (A: Tensor a) : [String] :=
  map tensorIndexVariance (tensorIndices A)

def unitTensor (ns: [Integer]) : Tensor Integer := generateTensor kroneckerDelta ns

def scalarToTensor {MulSemigroup a} (x: a) (ns: [Integer]) : Tensor a := x * unitTensor ns

def zeroTensor (ns: [Integer]) : Tensor Integer := generateTensor (\_ -> 0) ns

-- Reduce every diagonal component produced by `contract` with an explicit
-- reducer.  This is the common contraction kernel used by (.) and (.').
def contractWith {a} (reducer: Tensor a -> Tensor a -> Tensor a)
                     (t: Tensor a) : Tensor a :=
  foldl1 reducer (contract t)

def (.') (t1: Tensor MathValue) (t2: Tensor MathValue) : Tensor MathValue := 
  contractWith (+') (t1 *' t2)

def (.) {Ring a} (t1: Tensor a) (t2: Tensor a) : Tensor a :=
  contractWith (+) (t1 * t2)