Skip to contents

Once a labeled array (tensor) has been defined, tensor arithmetic operations can be carried out with the usual +, -, *, /, and == symbols.

Usage

# S3 method for class 'tensor'
Ops(e1, e2)

Arguments

e1, e2

Labeled arrays created with %_%.

Value

A resulting labeled array in case of +, -, *, /. TRUE or FALSE in case of ==.

Addition and Subtraction

Addition and subtraction requires the two tensors to have an equal index structure, i.e. the index names their position and the dimensions associated to the index names have to agree. The index order does not matter, the operation will match dimensions by index name.

Multiplication

Tensor multiplication takes into account implicit Ricci calculus rules depending on index placement.

  • Equal-named and opposite-positioned dimensions are contracted.

  • Equal-named and equal-positioned dimensions are subsetted.

  • The result is an outer product for distinct index names.

Division

Division performs element-wise division. If the second argument is a scalar, each element is simply divided by the scalar. Similar to addition and subtraction, division requires the two tensors to have an equal index structure, i.e. the index names their position and the dimensions associated to the index names have to agree.

Equality check

A tensor \(a_{i_1 i_2 ...}\) is equal to a tensor \(b_{j_1 j_2 ...}\) if and only if the index structure agrees and all components are equal.

See also

Other tensor operations: asym(), kron(), l(), r(), subst(), sym()

Examples

a <- array(1:4, c(2, 2))
b <- array(3 + 1:4, c(2, 2))

# addition
a %_% .(i, j) + b %_% .(j, i)
#> <Labeled Array> [2x2] .(-i, -j)
#>      [,1] [,2]
#> [1,]    5    8
#> [2,]    8   11

# multiplication
a %_% .(i, j) * b %_% .(+i, k)
#> <Labeled Array> [2x2] .(-j, -k)
#>      [,1] [,2]
#> [1,]   14   20
#> [2,]   32   46

# division
a %_% .(i, j) / 10
#> <Labeled Array> [2x2] .(-i, -j)
#>      [,1] [,2]
#> [1,]  0.1  0.3
#> [2,]  0.2  0.4

# equality check
a %_% .(i, j) == a %_% .(i, j)
#> [1] TRUE
a %_% .(i, j) == a %_% .(j, i)
#> [1] FALSE
a %_% .(i, j) == b %_% .(i, j)
#> [1] FALSE

# this will err because index structure does not agree
try(a %_% .(i, j) == a %_% .(k, j))
#> Error in `==`() : Tensor indices do not agree.
#>  Tensor index `i` appears in `e1` but not in `e2`.
#>  Tensor index `k` appears in `e2` but not in `e1`.
#>  Operation can only be carried out with two tensors having identical indices.