# Collapsing and Scaling Tensors

The tensor and sptensor classes support the notion of collapsing and scaling dimensions, and the tensor class also supports centering (see below).

## Examples of collapsing a tensor

```rng('default'); %<-- Make this reproducible.
X = tenrand([4 3 2]) %<-- Generate some data.
```
```X is a tensor of size 4 x 3 x 2
X(:,:,1) =
0.8147    0.6324    0.9575
0.9058    0.0975    0.9649
0.1270    0.2785    0.1576
0.9134    0.5469    0.9706
X(:,:,2) =
0.9572    0.4218    0.6557
0.4854    0.9157    0.0357
0.8003    0.7922    0.8491
0.1419    0.9595    0.9340
```
```Y = collapse(X,[2 3]) %<-- Sum of entries in each mode-1 slice.
```
```Y is a tensor of size 4
Y(:) =
4.4393
3.4050
3.0047
4.4662
```
```Y = collapse(X,-1) %<-- Same as above.
```
```Y is a tensor of size 4
Y(:) =
4.4393
3.4050
3.0047
4.4662
```
```Z = collapse(X,2) %<-- Sum of entries in each row fiber.
```
```Z is a tensor of size 4 x 2
Z(:,:) =
2.4046    2.0347
1.9682    1.4368
0.5631    2.4416
2.4309    2.0354
```
```collapse(X,1:3) %<-- Sum of all entries.
```
```ans =

15.3152

```

## Alternate accumulation functions for tensor

```Y = collapse(X,[1 2],@max) %<-- Max entry in each mode-3 slice.
```
```Y is a tensor of size 2
Y(:) =
0.9706
0.9595
```
```Z = collapse(X,-3,@mean) %<-- Average entry in each mode-3 slice.
```
```Z is a tensor of size 2
Z(:) =
0.6139
0.6624
```

## Examples of collapsing a sptensor

```X = sptenrand([4 3 2],6) %<-- Generate some data.
```
```X is a sparse tensor of size 4 x 3 x 2 with 6 nonzeros
(1,3,1)    0.7655
(2,1,1)    0.7952
(3,1,1)    0.1869
(3,1,2)    0.4898
(3,3,2)    0.4456
(4,1,1)    0.6463
```
```Y = collapse(X,[2 3]) %<-- Sum of entries in each mode-1 slice.
```
```Y =

0.7655
0.7952
1.1222
0.6463

```
```Y = collapse(X,-1) %<-- Same as above.
```
```Y =

0.7655
0.7952
1.1222
0.6463

```
```Z = collapse(X,2) %<-- Sum of entries in each row fiber.
```
```Z is a sparse tensor of size 4 x 2 with 5 nonzeros
(1,1)    0.7655
(2,1)    0.7952
(3,1)    0.1869
(3,2)    0.9354
(4,1)    0.6463
```
```collapse(X,1:3) %<-- Sum of all entries.
```
```ans =

3.3293

```

## Center tensor fibers for a dense tensor.

Suppose that we want to center a tensor's fiber in mode-2 so that they each have mean zero. To do so, we can use scale function in an unusual way, passing it a function handle to do the differences. (Note that sptensor does not support centering because it would cause the tensor to become dense.)

```X = tensor(1:24,[4 3 2]) %<-- Generate some data.
```
```X is a tensor of size 4 x 3 x 2
X(:,:,1) =
1     5     9
2     6    10
3     7    11
4     8    12
X(:,:,2) =
13    17    21
14    18    22
15    19    23
16    20    24
```

Calculate the means in mode 2

```mu = collapse(X,2,@mean)
```
```mu is a tensor of size 4 x 2
mu(:,:) =
5    17
6    18
7    19
8    20
```

Show the means of the mode-2 fibers

```Y = scale(X,mu,[1 3],@(x,y) x-y);
mu_new = collapse(Y,2,@mean)
```
```mu_new is a tensor of size 4 x 2
mu_new(:,:) =
0     0
0     0
0     0
0     0
```

## Alternate accumulation functions for sptensor

```Y = collapse(X,[1 2],@min) %<-- Min *nonzero* entry in each mode-3 slice.
```
```Y is a tensor of size 2
Y(:) =
1
13
```
```Z = collapse(X,-3,@mean) %<-- Average *nonzero* entry in each mode-3 slice.
```
```Z is a tensor of size 2
Z(:) =
6.5000
18.5000
```

## Scaling a tensor in different modes

```X = tenones([3,4,5]); %<-- Generate data
S = 10 * [1:5]'; Y = scale(X,S,3) %<-- Scale in mode-3
```
```Y is a tensor of size 3 x 4 x 5
Y(:,:,1) =
10    10    10    10
10    10    10    10
10    10    10    10
Y(:,:,2) =
20    20    20    20
20    20    20    20
20    20    20    20
Y(:,:,3) =
30    30    30    30
30    30    30    30
30    30    30    30
Y(:,:,4) =
40    40    40    40
40    40    40    40
40    40    40    40
Y(:,:,5) =
50    50    50    50
50    50    50    50
50    50    50    50
```
```S = tensor(10 * [1:5]',5); Y = scale(X,S,3) %<-- First argument is a tensor.
```
```Y is a tensor of size 3 x 4 x 5
Y(:,:,1) =
10    10    10    10
10    10    10    10
10    10    10    10
Y(:,:,2) =
20    20    20    20
20    20    20    20
20    20    20    20
Y(:,:,3) =
30    30    30    30
30    30    30    30
30    30    30    30
Y(:,:,4) =
40    40    40    40
40    40    40    40
40    40    40    40
Y(:,:,5) =
50    50    50    50
50    50    50    50
50    50    50    50
```
```S = tensor(1:12,[3 4]); Y = scale(X,S,[1 2]) %<-- Scale in two modes.
```
```Y is a tensor of size 3 x 4 x 5
Y(:,:,1) =
1     4     7    10
2     5     8    11
3     6     9    12
Y(:,:,2) =
1     4     7    10
2     5     8    11
3     6     9    12
Y(:,:,3) =
1     4     7    10
2     5     8    11
3     6     9    12
Y(:,:,4) =
1     4     7    10
2     5     8    11
3     6     9    12
Y(:,:,5) =
1     4     7    10
2     5     8    11
3     6     9    12
```
```S = tensor(1:12,[3 4]); Y = scale(X,S,-3) %<-- Same as above.
```
```Y is a tensor of size 3 x 4 x 5
Y(:,:,1) =
1     4     7    10
2     5     8    11
3     6     9    12
Y(:,:,2) =
1     4     7    10
2     5     8    11
3     6     9    12
Y(:,:,3) =
1     4     7    10
2     5     8    11
3     6     9    12
Y(:,:,4) =
1     4     7    10
2     5     8    11
3     6     9    12
Y(:,:,5) =
1     4     7    10
2     5     8    11
3     6     9    12
```
```S = tensor(1:60,[3 4 5]); Y = scale(X,S,1:3) %<-- Scale in every mode.
```
```Y is a tensor of size 3 x 4 x 5
Y(:,:,1) =
1     4     7    10
2     5     8    11
3     6     9    12
Y(:,:,2) =
13    16    19    22
14    17    20    23
15    18    21    24
Y(:,:,3) =
25    28    31    34
26    29    32    35
27    30    33    36
Y(:,:,4) =
37    40    43    46
38    41    44    47
39    42    45    48
Y(:,:,5) =
49    52    55    58
50    53    56    59
51    54    57    60
```
```Y = S .* X %<-- Same as above.
```
```Y is a tensor of size 3 x 4 x 5
Y(:,:,1) =
1     4     7    10
2     5     8    11
3     6     9    12
Y(:,:,2) =
13    16    19    22
14    17    20    23
15    18    21    24
Y(:,:,3) =
25    28    31    34
26    29    32    35
27    30    33    36
Y(:,:,4) =
37    40    43    46
38    41    44    47
39    42    45    48
Y(:,:,5) =
49    52    55    58
50    53    56    59
51    54    57    60
```

## Scaling a sptensor in different modes

```X = ones(sptenrand([3 4 5], 10)) %<-- Generate data.
```
```X is a sparse tensor of size 3 x 4 x 5 with 10 nonzeros
(1,1,1)     1
(1,4,1)     1
(1,4,5)     1
(2,1,3)     1
(2,1,5)     1
(3,1,2)     1
(3,2,3)     1
(3,2,5)     1
(3,4,1)     1
(3,4,2)     1
```
```S = 10 * [1:5]'; Y = scale(X,S,3) %<-- Scale in one mode.
```
```Y is a sparse tensor of size 3 x 4 x 5 with 10 nonzeros
(1,1,1)    10
(1,4,1)    10
(1,4,5)    50
(2,1,3)    30
(2,1,5)    50
(3,1,2)    20
(3,2,3)    30
(3,2,5)    50
(3,4,1)    10
(3,4,2)    20
```
```S = tensor(10 * [1:5]',5); Y = scale(X,S,3) %<-- Same as above.
```
```Y is a sparse tensor of size 3 x 4 x 5 with 10 nonzeros
(1,1,1)    10
(1,4,1)    10
(1,4,5)    50
(2,1,3)    30
(2,1,5)    50
(3,1,2)    20
(3,2,3)    30
(3,2,5)    50
(3,4,1)    10
(3,4,2)    20
```
```S = tensor(1:12,[3 4]); Y = scale(X,S,[1 2]) %<-- Scale in two modes.
```
```Y is a sparse tensor of size 3 x 4 x 5 with 10 nonzeros
(1,1,1)     1
(1,4,1)    10
(1,4,5)    10
(2,1,3)     2
(2,1,5)     2
(3,1,2)     3
(3,2,3)     6
(3,2,5)     6
(3,4,1)    12
(3,4,2)    12
```
```S = tensor(1:12,[3 4]); Y = scale(X,S,-3) %<-- Same as above.
```
```Y is a sparse tensor of size 3 x 4 x 5 with 10 nonzeros
(1,1,1)     1
(1,4,1)    10
(1,4,5)    10
(2,1,3)     2
(2,1,5)     2
(3,1,2)     3
(3,2,3)     6
(3,2,5)     6
(3,4,1)    12
(3,4,2)    12
```
```Z = scale(X,Y,1:3) %<-- Scale by a sparse tensor.
```
```Z is a sparse tensor of size 3 x 4 x 5 with 10 nonzeros
(1,1,1)     1
(1,4,1)    10
(1,4,5)    10
(2,1,3)     2
(2,1,5)     2
(3,1,2)     3
(3,2,3)     6
(3,2,5)     6
(3,4,1)    12
(3,4,2)    12
```
```X .* Y %<-- Same as above.
```
```ans is a sparse tensor of size 3 x 4 x 5 with 10 nonzeros
(1,1,1)     1
(1,4,1)    10
(1,4,5)    10
(2,1,3)     2
(2,1,5)     2
(3,1,2)     3
(3,2,3)     6
(3,2,5)     6
(3,4,1)    12
(3,4,2)    12
```