tensor {tensor} | R Documentation |
The tensor product of two arrays is notionally an
outer product of the arrays collapsed in specific extents by
summing along the appropriate diagonals. For example, a matrix
product is the tensor product along the second extent of the
first matrix and the first extent of the second. Thus A
%*% B
could also be evaluated as tensor(A, B, 2, 1)
,
likewise A %*% t(B)
could be tensor(A, B, 2, 2)
.
tensor(A, B, alongA = integer(0), alongB = integer(0))
A, B |
Numerical vectors, matrices or arrays |
alongA |
Extents in A to be collapsed |
alongB |
Extents in B to be collapsed |
A straightforward implementation of tensor
in R
would be to perm the along extents to the end of each object,
reshape each object as a matrix with the columns corresponding to
the along extents, take the matrix product of the first object
with the transpose of the second, and then reshape the result.
This happens to be very expensive if the objects are large (and
people who want tensors often have large objects!). But it is
recommended if speed is an issue and RAM is ample.
This tensor
implements the tensor product without perming
or reshaping using the concept of `strides', which will be
familiar to numerical programmers in Python. In other words, if
A
, B
and their required tensor product fit into the
available memory, then the calculation will complete (modulo a
few small objects created en route). All code is written
in "C", for speed. NA
is fully supported and the original
storage type of the objects (integer, double or complex) is
preserved, where possible. This might be useful for matrix
products on integers (which R promotes to doubles): see the
Section on Shortcuts below.
Generally, an array with dimension comprising the
remaining extents of A
concatenated with the remaining
extents of B
.
If both A
and B
are completely collapsed then the
result is a scalar without a dim
attribute. This
is quite deliberate and consistent with the general rule that the
dimension of the result is the sum of the original dimensions
less the sum of the collapse dimensions (and so could be zero).
A 1D array of length 1 arises in a different set of
circumstances, eg if A
is a 1 by 5 matrix and B
is
a 5-vector then tensor(A, B, 2, 1)
is a 1D array of length
1.
Some special cases of tensor
may be
independently useful, and these have got shortcuts as follows.
%O% | Outer product of A and B |
%*t% | Matrix product A %*% t(B) |
%t*% | Matrix product t(A) %*% B |
%t*t% | Matrix product t(A) %*% t(B) |
Jonathan Rougier, J.C.Rougier@durham.ac.uk
A <- matrix(1:6, 2, 3) # has storage mode "integer" dimnames(A) <- list(happy = LETTERS[1:2], sad = NULL) # just for fun! B <- matrix(1:12, 4, 3) all(A %*% t(B) == tensor(A, B, 2, 2)) # TRUE A %*t% B # same answer A <- A %O% A # now 2 by 3 by 2 by 3 C <- tensor(A, B, 2, 2) # will be 2 by 2 by 3 by 4 D <- tensor(C, B, c(4, 3), c(1, 2)) # will be 2 by 2 E <- matrix(9:12, 2, 2) s <- tensor(D, E, 1:2, 1:2) # scalar, NO dim attribute s == sum(D * E) # TRUE