A module defining a recursive multi-dimensional tensor data type and arithmetic functions for it.

- data Tensor n
- type TensorAlgebra n r = (n -> r, [r] -> r)
- tenVerify :: Tensor n -> Bool
- isScalar :: Tensor n -> Bool
- order :: Tensor n -> Int
- tenDims :: Tensor n -> [Int]
- tenFold :: TensorAlgebra n r -> Tensor n -> r
- tenMap :: (a -> b) -> Tensor a -> Tensor b
- tenZipWith :: TensorAlgebra (a, b) c -> Tensor a -> Tensor b -> c
- list2tensor :: [Int] -> [n] -> Tensor n
- tensor2list :: Tensor n -> ([Int], [n])
- dim2tensor :: Num n => [[n]] -> Tensor n
- dim3tensor :: Num n => [[[n]]] -> Tensor n
- kronecker :: Num n => Int -> Tensor n
- levicivita :: Num n => Int -> Tensor n
- scalarmul :: Num n => n -> Tensor n -> Tensor n
- tenAdd :: Num n => Tensor n -> Tensor n -> Tensor n
- tenBinOp :: (a -> b -> c) -> Tensor a -> Tensor b -> Tensor c
- fullcontract :: Num n => Tensor n -> Tensor n -> n
- externalprod :: Num n => Tensor n -> Tensor n -> Tensor n
- contract :: Num n => [(Int, Int)] -> Tensor n -> Tensor n -> Tensor n
- selfcontract :: Num n => Int -> Int -> Tensor n -> Tensor n
- transpose :: Tensor n -> Tensor n
- swapind :: Int -> Int -> Tensor n -> Tensor n
- revind :: Tensor n -> Tensor n
- reindex :: [Int] -> Tensor n -> Tensor n
- slice :: [(Int, Int)] -> Tensor n -> Tensor n

# Data types

data Tensor n

The Tensor data type is defined recursively as either a Scalar or an array of sub-tensors called Vector. Equal size of all sub-tensors in a Vector is assumed by most functions below. Use the tenVerify function to verify correctness if you build tensors using constructors.

type TensorAlgebra n r = (n -> r, [r] -> r)

Function type for folds. The first function processes Scalars, the second combines the results from sub-tensors.

# Basic functions

Verify correctness of Tensor data. To be used if you build tensors yourself from constructors.

# Folds, maps etc.

tenFold :: TensorAlgebra n r -> Tensor n -> r

Fold for the Tensor data type.

tenZipWith :: TensorAlgebra (a, b) c -> Tensor a -> Tensor b -> c

zipWith for tensors with the same order and dimensions

# Creation and export of tensors

list2tensor :: [Int] -> [n] -> Tensor n

Build Tensor from list of dimensions and list of elements. The last tensor index = innermost Vector element changes fastest.

tensor2list :: Tensor n -> ([Int], [n])

Turn tensor into pair of list of dimensions and list of elements

dim2tensor :: Num n => [[n]] -> Tensor n

Build 2D tensor from nested lists. Haskell's strong typing forbids generalising this. In order to guard against higher-order nested lists being passed, this function is restricted to Num's.

dim3tensor :: Num n => [[[n]]] -> Tensor n

Build 3D tensor from nested lists. Haskell's strong typing forbids generalising this. In order to guard against higher-order nested lists being passed, this function is restricted to Num's.

# Special tensors

levicivita :: Num n => Int -> Tensor n

Levi-Civita or fully antisymmetric tensor in d dimensions (and of order d)

# Arithmetic

fullcontract :: Num n => Tensor n -> Tensor n -> n

Full contraction with respect to all indices of two tensors with equal dimensions. The result is a scalar not wrapped in a Scalar constructor.

externalprod :: Num n => Tensor n -> Tensor n -> Tensor n

External product (no contractions)

contract :: Num n => [(Int, Int)] -> Tensor n -> Tensor n -> Tensor n

General contraction of two tensors. The first argument contains pairs of one-based indices to be contracted. The contraction is performed by shifting indices to be contracted to the end, then using fullcontract on corresponding inner tensors of the two tensor arguments.

selfcontract :: Num n => Int -> Int -> Tensor n -> Tensor n

Contract two indices of one tensor. The indices are one-based.

# Index rearrangement

swapind :: Int -> Int -> Tensor n -> Tensor n

Swap two indices. As for all exported functions, these are one-based.