# Converting a tensor to a matrix and vice versa

We show how to convert a tensor to a matrix stored with extra information so that it can be converted back to a tensor. Converting to a matrix requies an ordered mapping of the tensor indices to the rows and the columns of the matrix.

## Contents

- Creating a tenmat (tensor as matrix) object
- Creating a tenmat by specifying the dimensions mapped to the rows
- Creating a tenmat by specifying the dimensions mapped to the columns
- Vectorize via tenmat
- Alternative ordering for the columns for mode-n matricization
- Constituent parts of a tenmat
- Creating a tenmat from its constituent parts
- Creating an empty tenmat
- Use double to convert a tenmat to a MATLAB matrix
- Use tensor to convert a tenmat to a tensor
- Use size and tsize for the dimensions of a tenmat
- Subscripted reference for a tenmat
- Subscripted assignment for a tenmat
- Use end for the last index
- Basic operations for tenmat
- Multiplying two tenmats
- Displaying a tenmat

## Creating a tenmat (tensor as matrix) object

```
X = tensor(1:24,[3 2 2 2]) %<-- Create a tensor.
```

X is a tensor of size 3 x 2 x 2 x 2 X(:,:,1,1) = 1 4 2 5 3 6 X(:,:,2,1) = 7 10 8 11 9 12 X(:,:,1,2) = 13 16 14 17 15 18 X(:,:,2,2) = 19 22 20 23 21 24

```
A = tenmat(X,[1 2],[3 4]) %<-- Dims [1 2] map to rows, [3 4] to columns.
```

A is a matrix corresponding to a tensor of size 3 x 2 x 2 x 2 A.rindices = [ 1 2 ] (modes of tensor corresponding to rows) A.cindices = [ 3 4 ] (modes of tensor corresponding to columns) A.data = 1 7 13 19 2 8 14 20 3 9 15 21 4 10 16 22 5 11 17 23 6 12 18 24

```
B = tenmat(X,[2 1],[3 4]) %<-- Order matters!
```

B is a matrix corresponding to a tensor of size 3 x 2 x 2 x 2 B.rindices = [ 2 1 ] (modes of tensor corresponding to rows) B.cindices = [ 3 4 ] (modes of tensor corresponding to columns) B.data = 1 7 13 19 4 10 16 22 2 8 14 20 5 11 17 23 3 9 15 21 6 12 18 24

```
C = tenmat(X,[1 2],[4 3]) %<-- Order matters!
```

C is a matrix corresponding to a tensor of size 3 x 2 x 2 x 2 C.rindices = [ 1 2 ] (modes of tensor corresponding to rows) C.cindices = [ 4 3 ] (modes of tensor corresponding to columns) C.data = 1 13 7 19 2 14 8 20 3 15 9 21 4 16 10 22 5 17 11 23 6 18 12 24

## Creating a tenmat by specifying the dimensions mapped to the rows

If just the row indices are specified, then the columns are arranged in increasing order.

```
A = tenmat(X,1) %<-- Same as A = tenmat(X,1,2:4)
```

A is a matrix corresponding to a tensor of size 3 x 2 x 2 x 2 A.rindices = [ 1 ] (modes of tensor corresponding to rows) A.cindices = [ 2 3 4 ] (modes of tensor corresponding to columns) A.data = 1 4 7 10 13 16 19 22 2 5 8 11 14 17 20 23 3 6 9 12 15 18 21 24

## Creating a tenmat by specifying the dimensions mapped to the columns

Likewise, just the columns can be specified if the 3rd argument is a 't'. The rows are arranged in increasing order.

A = tenmat(X, [2 3], 't') %<-- Same as A = tenmat(X,[1 4],[2 3]).

A is a matrix corresponding to a tensor of size 3 x 2 x 2 x 2 A.rindices = [ 1 4 ] (modes of tensor corresponding to rows) A.cindices = [ 2 3 ] (modes of tensor corresponding to columns) A.data = 1 4 7 10 2 5 8 11 3 6 9 12 13 16 19 22 14 17 20 23 15 18 21 24

## Vectorize via tenmat

All the dimensions can be mapped to the rows or the columnns.

A = tenmat(X,1:4,'t') %<-- Map all the dimensions to the columns

A is a matrix corresponding to a tensor of size 3 x 2 x 2 x 2 A.rindices = [ ] (modes of tensor corresponding to rows) A.cindices = [ 1 2 3 4 ] (modes of tensor corresponding to columns) A.data = Columns 1 through 13 1 2 3 4 5 6 7 8 9 10 11 12 13 Columns 14 through 24 14 15 16 17 18 19 20 21 22 23 24

## Alternative ordering for the columns for mode-n matricization

Mode-n matricization means that only mode n is mapped to the rows. Different column orderings are available.

```
A = tenmat(X,2) %<-- By default, columns are ordered as [1 3 4].
```

A is a matrix corresponding to a tensor of size 3 x 2 x 2 x 2 A.rindices = [ 2 ] (modes of tensor corresponding to rows) A.cindices = [ 1 3 4 ] (modes of tensor corresponding to columns) A.data = 1 2 3 7 8 9 13 14 15 19 20 21 4 5 6 10 11 12 16 17 18 22 23 24

```
A = tenmat(X,2,[3 1 4]) %<-- Explicit specification.
```

A is a matrix corresponding to a tensor of size 3 x 2 x 2 x 2 A.rindices = [ 2 ] (modes of tensor corresponding to rows) A.cindices = [ 3 1 4 ] (modes of tensor corresponding to columns) A.data = 1 7 2 8 3 9 13 19 14 20 15 21 4 10 5 11 6 12 16 22 17 23 18 24

A = tenmat(X,2,'fc') %<-- Forward cyclic, i.e., [3 4 1].

A is a matrix corresponding to a tensor of size 3 x 2 x 2 x 2 A.rindices = [ 2 ] (modes of tensor corresponding to rows) A.cindices = [ 3 4 1 ] (modes of tensor corresponding to columns) A.data = 1 7 13 19 2 8 14 20 3 9 15 21 4 10 16 22 5 11 17 23 6 12 18 24

A = tenmat(X,2,'bc') %<-- Backward cyclic, i.e., [1 4 3].

A is a matrix corresponding to a tensor of size 3 x 2 x 2 x 2 A.rindices = [ 2 ] (modes of tensor corresponding to rows) A.cindices = [ 1 4 3 ] (modes of tensor corresponding to columns) A.data = 1 2 3 13 14 15 7 8 9 19 20 21 4 5 6 16 17 18 10 11 12 22 23 24

## Constituent parts of a tenmat

```
A.data %<-- The matrix itself.
```

ans = 1 2 3 13 14 15 7 8 9 19 20 21 4 5 6 16 17 18 10 11 12 22 23 24

```
A.tsize %<-- Size of the original tensor.
```

ans = 3 2 2 2

```
A.rdims %<-- Dimensions that were mapped to the rows.
```

ans = 2

```
A.cdims %<-- Dimensions that were mapped to the columns.
```

ans = 1 4 3

## Creating a tenmat from its constituent parts

```
B = tenmat(A.data,A.rdims,A.cdims,A.tsize) %<-- Recreates A
```

B is a matrix corresponding to a tensor of size 3 x 2 x 2 x 2 B.rindices = [ 2 ] (modes of tensor corresponding to rows) B.cindices = [ 1 4 3 ] (modes of tensor corresponding to columns) B.data = 1 2 3 13 14 15 7 8 9 19 20 21 4 5 6 16 17 18 10 11 12 22 23 24

## Creating an empty tenmat

```
B = tenmat %<-- Empty tenmat.
```

B is a matrix corresponding to a tensor of size [empty tensor] B.rindices = [ ] (modes of tensor corresponding to rows) B.cindices = [ ] (modes of tensor corresponding to columns) B.data = []

## Use double to convert a tenmat to a MATLAB matrix

```
double(A) %<-- converts A to a standard matrix
```

ans = 1 2 3 13 14 15 7 8 9 19 20 21 4 5 6 16 17 18 10 11 12 22 23 24

## Use tensor to convert a tenmat to a tensor

Y = tensor(A)

Y is a tensor of size 3 x 2 x 2 x 2 Y(:,:,1,1) = 1 4 2 5 3 6 Y(:,:,2,1) = 7 10 8 11 9 12 Y(:,:,1,2) = 13 16 14 17 15 18 Y(:,:,2,2) = 19 22 20 23 21 24

## Use size and tsize for the dimensions of a tenmat

size(A) %<-- Matrix size tsize(A) %<-- Corresponding tensor size

ans = 2 12 ans = 3 2 2 2

## Subscripted reference for a tenmat

```
A(2,1) %<-- returns the (2,1) element of the matrix.
```

ans = 4

## Subscripted assignment for a tenmat

```
A(1:2,1:2) = ones(2) %<-- Replace part of the matrix.
```

A is a matrix corresponding to a tensor of size 3 x 2 x 2 x 2 A.rindices = [ 2 ] (modes of tensor corresponding to rows) A.cindices = [ 1 4 3 ] (modes of tensor corresponding to columns) A.data = 1 1 3 13 14 15 7 8 9 19 20 21 1 1 6 16 17 18 10 11 12 22 23 24

## Use end for the last index

```
A(end,end) %<-- Same as X(2,12)
```

ans = 24

## Basic operations for tenmat

```
norm(A) %<-- Norm of the matrix.
```

ans = 69.6994

```
A' %<-- Calls ctranspose (also swaps mapped dimensions).
```

ans is a matrix corresponding to a tensor of size 3 x 2 x 2 x 2 ans.rindices = [ 1 4 3 ] (modes of tensor corresponding to rows) ans.cindices = [ 2 ] (modes of tensor corresponding to columns) ans.data = 1 1 1 1 3 6 13 16 14 17 15 18 7 10 8 11 9 12 19 22 20 23 21 24

```
+A %<-- Calls uplus.
```

ans is a matrix corresponding to a tensor of size 3 x 2 x 2 x 2 ans.rindices = [ 2 ] (modes of tensor corresponding to rows) ans.cindices = [ 1 4 3 ] (modes of tensor corresponding to columns) ans.data = 1 1 3 13 14 15 7 8 9 19 20 21 1 1 6 16 17 18 10 11 12 22 23 24

```
-A %<-- Calls uminus.
```

ans is a matrix corresponding to a tensor of size 3 x 2 x 2 x 2 ans.rindices = [ 2 ] (modes of tensor corresponding to rows) ans.cindices = [ 1 4 3 ] (modes of tensor corresponding to columns) ans.data = -1 -1 -3 -13 -14 -15 -7 -8 -9 -19 -20 -21 -1 -1 -6 -16 -17 -18 -10 -11 -12 -22 -23 -24

```
A+A %<-- Calls plus.
```

ans is a matrix corresponding to a tensor of size 3 x 2 x 2 x 2 ans.rindices = [ 2 ] (modes of tensor corresponding to rows) ans.cindices = [ 1 4 3 ] (modes of tensor corresponding to columns) ans.data = 2 2 6 26 28 30 14 16 18 38 40 42 2 2 12 32 34 36 20 22 24 44 46 48

```
A-A %<-- Calls minus.
```

ans is a matrix corresponding to a tensor of size 3 x 2 x 2 x 2 ans.rindices = [ 2 ] (modes of tensor corresponding to rows) ans.cindices = [ 1 4 3 ] (modes of tensor corresponding to columns) ans.data = 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

## Multiplying two tenmats

It is possible to compute the product of two tenmats and have a result that can be converted into a tensor.

```
B = A * A' %<-- Tenmat that is the product of two tenmats.
```

B is a matrix corresponding to a tensor of size 2 x 2 B.rindices = [ 1 ] (modes of tensor corresponding to rows) B.cindices = [ 2 ] (modes of tensor corresponding to columns) B.data = 1997 2384 2384 2861

```
tensor(B) %<-- Corresponding tensor.
```

ans is a tensor of size 2 x 2 ans(:,:) = 1997 2384 2384 2861

## Displaying a tenmat

Shows the original tensor dimensions, the modes mapped to rows, the modes mapped to columns, and the matrix.

disp(A)

ans is a matrix corresponding to a tensor of size 3 x 2 x 2 x 2 ans.rindices = [ 2 ] (modes of tensor corresponding to rows) ans.cindices = [ 1 4 3 ] (modes of tensor corresponding to columns) ans.data = 1 1 3 13 14 15 7 8 9 19 20 21 1 1 6 16 17 18 10 11 12 22 23 24