Learn R Programming

qlcMatrix (version 0.9.8)

unfold: Unfolding of Arrays

Description

Multidimensional Arrays ("Tensors") can be unfolded, i.e. multiple dimensions can be combined into a single dimension in a block-wise fashion. Such unfoldings are central to tensor decomposition. In general, computations on tensors are regularly performed by reducing tensors to matrices ("2-dimensional tensors") and then use regular matrix algebra.

Usage

unfold(x, MARGINS)

unfold_to_matrix(x, ROWS, COLS = NULL) tenmat(x, ROWS, COLS = NULL)

Value

unfold returns a simple_sparse_array with the new combined dimension added as the last dimension. All original dimensions are shifted forward. The relation between the original dimensions and the new dimensions is stored as an permutation attribute, e.g. try attr(x, "p"). When multiple unfoldings are performed after each other, these permutations can be subsetted on each other to obtain the final permutation. See examples below.

unfold_to_matrix and tenmat return a sparse matrix of class dgTMatrix.

Arguments

x

Sparse array to be unfolded, using simple_sparse_array from the package spam.

MARGINS

Margins ("dimensions") to be unfolded. The margins specified will be turned into a single dimension, to be added as the last dimension of the resulting array (see Details).

ROWS

Margins of the original array to be unfolded into the rows of the resulting matrix.

COLS

Margins of the original array to be unfolded into the columns of the resulting matrix. If NULL, then all remaining margins, not included in ROWS are unfolded here.

Author

Michael Cysouw <cysouw@mac.com>

Details

The function unfold is a general approach to combining of multiple dimensions into a single dimensions. The function unfold_to_matrix is a special case in which the result is a 2-dimensional matrix. This second function is made to emulate the functionality of the tenmat ("tensor to matrix") from the Matlab Tensor Toolbox. For convenience, the function-name tenmat is also added as a synonym for unfold_to_matrix.

Unfolding basically works by interspercing margins subsequently. E.g. margin A of size 3 (A1, A2, A3) and a margin B of size 2 (B1, B2) are unfolded through c(A,B) as (A1B1, A2B1, A3B1, A1B2, A2B2, A3B2), but they are unfolded through c{B,A} as (B1A1, B2A1, B1A2, B2A2, B1A3, B2A3).

References

see some old notes by Charles Van Loon that inspired this implementation at https://web.archive.org/web/20210505120659/http://www.cs.cornell.edu/cv/SummerSchool/unfold.pdf. The Matlab Tensor Toolbox can be found at https://www.tensortoolbox.org. A different Matlab implementation is https://www.tensorlab.net.

Examples

Run this code
# example from Charles Van Loon:
x <- array(c(111, 211, 311, 411, 121, 221, 321, 
    421, 131, 231, 331, 431, 112, 212, 312, 412, 
    122, 222, 322, 422, 132, 232, 332, 432), dim = c(4, 3, 2))
x

s <- as.simple_sparse_array(x)
( s1  <- as.array(unfold_to_matrix(s,1)) )

# note this is identical to:
( s23 <- as.array(unfold(s,c(2,3))) )
all.equal(s23, s1)

# larger example from same source
x <- array(0, dim = c(2,3,2,2,3))
x[1,2,1,1,2] <- 12112
x[2,3,1,2,2] <- 23122
x[2,2,2,1,1] <- 22211
x[2,2,1,2,3] <- 22123
s <- as.simple_sparse_array(x)

as.array(unfold_to_matrix(s, c(1,2,3), c(4,5)))

# use attribute "permutation" to track dimensions
# first step: unfold 1,2,3 to become dimension 3
# original dimensions 4,5 now become 1,2
s1 <- unfold(s, c(1,2,3))
( p1 <- attr(s1, "permutation") )

# now take these dimension 1,2 (originally 4,5) and unfold them
s2 <- unfold(s1, c(1,2))
( p2 <- attr(s2, "permutation") )

# use subsetting to track dimensions through subsequent unfolding
p2[p1]

Run the code above in your browser using DataLab