Multiplying Tensors

Contents

Tensor times vector (ttv for tensor)

Compute a tensor times a vector (or vectors) in one (or more) modes.

rand('state',0);
X = tenrand([5,3,4,2]); %<-- Create a dense tensor.
A = rand(5,1); B = rand(3,1); C = rand(4,1); D = rand(2,1); %<-- Some vectors.
Y = ttv(X, A, 1) %<-- X times A in mode 1.
Y is a tensor of size 3 x 4 x 2
	Y(:,:,1) = 
	    1.6875    1.9480    0.9951    0.9505
	    0.8258    0.9495    1.4104    0.6771
	    1.4496    0.8295    1.5943    1.6259
	Y(:,:,2) = 
	    1.8369    1.3352    1.0743    1.4354
	    1.0471    1.2250    1.5317    1.2519
	    1.4225    1.2897    1.1595    0.5775
Y = ttv(X, {A,B,C,D}, 1) %<-- Same as above.
Y is a tensor of size 3 x 4 x 2
	Y(:,:,1) = 
	    1.6875    1.9480    0.9951    0.9505
	    0.8258    0.9495    1.4104    0.6771
	    1.4496    0.8295    1.5943    1.6259
	Y(:,:,2) = 
	    1.8369    1.3352    1.0743    1.4354
	    1.0471    1.2250    1.5317    1.2519
	    1.4225    1.2897    1.1595    0.5775
Y = ttv(X, {A,B,C,D}, [1 2 3 4]) %<-- All-mode multiply produces a scalar.
Y =
    7.8707
Y = ttv(X, {D,C,B,A}, [4 3 2 1]) %<-- Same as above.
Y =
    7.8707
Y = ttv(X, {A,B,C,D}) %<-- Same as above.
Y =
    7.8707
Y = ttv(X, {C,D}, [3 4]) %<-- X times C in mode-3 & D in mode-4.
Y is a tensor of size 5 x 3
	Y(:,:) = 
	    1.0157    1.1081    1.5654
	    1.3799    1.2137    1.0599
	    1.5625    1.1830    1.0658
	    1.2323    1.2410    1.4481
	    1.4374    0.9573    0.8644
Y = ttv(X, {A,B,C,D}, [3 4]) %<-- Same as above.
Y is a tensor of size 5 x 3
	Y(:,:) = 
	    1.0157    1.1081    1.5654
	    1.3799    1.2137    1.0599
	    1.5625    1.1830    1.0658
	    1.2323    1.2410    1.4481
	    1.4374    0.9573    0.8644
Y = ttv(X, {A,B,D}, [1 2 4]) %<-- 3-way multiplication.
Y is a tensor of size 4
	Y(:) = 
	    4.9369
	    4.5013
	    4.4941
	    3.8857
Y = ttv(X, {A,B,C,D}, [1 2 4]) %<-- Same as above.
Y is a tensor of size 4
	Y(:) = 
	    4.9369
	    4.5013
	    4.4941
	    3.8857
Y = ttv(X, {A,B,D}, -3) %<-- Same as above.
Y is a tensor of size 4
	Y(:) = 
	    4.9369
	    4.5013
	    4.4941
	    3.8857
Y = ttv(X, {A,B,C,D}, -3) %<-- Same as above.
Y is a tensor of size 4
	Y(:) = 
	    4.9369
	    4.5013
	    4.4941
	    3.8857

Sparse tensor times vector (ttv for sptensor)

This is the same as in the dense case, except that the result may be either dense or sparse (or a scalar).

X = sptenrand([5,3,4,2],5); %<-- Create a sparse tensor.
Y = ttv(X, A, 1) %<-- X times A in mode 1. Result is sparse.
Y is a sparse tensor of size 3 x 4 x 2 with 5 nonzeros
	(1,3,1)    0.0014
	(2,2,1)    0.3357
	(3,1,1)    0.5973
	(3,1,2)    0.0005
	(3,3,1)    0.0039
Y = ttv(X, {A,B,C,D}, [1 2 3 4]) %<-- All-mode multiply.
Y =
    0.1196
Y = ttv(X, {C,D}, [3 4]) %<-- X times C in mode-3 & D in mode-4.
Y is a sparse tensor of size 5 x 3 with 5 nonzeros
	(2,3)    0.0009
	(3,2)    0.0612
	(3,3)    0.0959
	(4,1)    0.0064
	(4,3)    0.0149
Y = ttv(X, {A,B,D}, -3) %<-- 3-way multiplication. Result is *dense*!
Y is a tensor of size 4
	Y(:) = 
	    0.1512
	    0.1064
	    0.0014
	         0

Kruskal tensor times vector (ttv for ktensor)

The special structure of a ktensor allows an efficient implementation of vector multiplication. The result is a ktensor or a scalar.

X = ktensor([10;1],rand(5,2),rand(3,2),rand(4,2),rand(2,2)); %<-- Ktensor.
Y = ttv(X, A, 1) %<-- X times A in mode 1. Result is a ktensor.
Y is a ktensor of size 3 x 4 x 2
	Y.lambda = 
		    5.9997    1.1433
	Y.U{1} = 
		    0.6927    0.4418
		    0.0841    0.3533
		    0.4544    0.1536
	Y.U{2} = 
		    0.6756    0.5548
		    0.6992    0.1210
		    0.7275    0.4508
		    0.4784    0.7159
	Y.U{3} = 
		    0.8928    0.2548
		    0.2731    0.8656
norm(full(Y) - ttv(full(X),A,1)) %<-- Result is the same as dense case.
ans =
   7.0654e-16
Y = ttv(X, {A,B,C,D}) %<-- All-mode multiply -- scalar result.
Y =
    4.8677
Y = ttv(X, {C,D}, [3 4]) %<-- X times C in mode-3 & D in mode-4.
Y is a ktensor of size 5 x 3
	Y.lambda = 
		    6.0729    0.7856
	Y.U{1} = 
		    0.6124    0.5869
		    0.6085    0.0576
		    0.0158    0.3676
		    0.0164    0.6315
		    0.1901    0.7176
	Y.U{2} = 
		    0.6927    0.4418
		    0.0841    0.3533
		    0.4544    0.1536
Y = ttv(X, {A,B,D}, [1 2 4]) %<-- 3-way multiplication.
Y is a ktensor of size 4
	Y.lambda = 
		    3.6628    0.9389
	Y.U{1} = 
		    0.6756    0.5548
		    0.6992    0.1210
		    0.7275    0.4508
		    0.4784    0.7159

Tucker tensor times vector (ttv for ttensor)

The special structure of a ttensor allows an efficient implementation of vector multiplication. The result is a ttensor or a scalar.

X = ttensor(tenrand([2,2,2,2]),rand(5,2),rand(3,2),rand(4,2),rand(2,2));
Y = ttv(X, A, 1) %<-- X times A in mode 1.
Y is a ttensor of size 3 x 4 x 2
	Y.core is a tensor of size 2 x 2 x 2
		Y.core(:,:,1) = 
	    1.3171    0.2658
	    1.0694    0.9612
		Y.core(:,:,2) = 
	    1.3377    1.4308
	    0.3816    0.7186
	Y.U{1} = 
		    0.8729    0.9669
		    0.2379    0.6649
		    0.6458    0.8704
	Y.U{2} = 
		    0.0099    0.8903
		    0.1370    0.7349
		    0.8188    0.6873
		    0.4302    0.3461
	Y.U{3} = 
		    0.1660    0.1911
		    0.1556    0.4225
norm(full(Y) - ttv(full(X),A, 1)) %<-- Same as dense case.
ans =
   6.2311e-16
Y = ttv(X, {A,B,C,D}, [1 2 3 4]) %<-- All-mode multiply -- scalar result.
Y =
    3.8758
Y = ttv(X, {C,D}, [3 4]) %<-- X times C in mode-3 & D in mode-4.
Y is a ttensor of size 5 x 3
	Y.core is a tensor of size 2 x 2
		Y.core(:,:) = 
	    0.6489    0.3358
	    0.5348    0.3779
	Y.U{1} = 
		    0.3651    0.4586
		    0.3932    0.8699
		    0.5915    0.9342
		    0.1197    0.2644
		    0.0381    0.1603
	Y.U{2} = 
		    0.8729    0.9669
		    0.2379    0.6649
		    0.6458    0.8704
Y = ttv(X, {A,B,D}, [1 2 4]) %<-- 3-way multiplication.
Y is a ttensor of size 4
	Y.core is a tensor of size 2
		Y.core(:) = 
	    2.3205
	    2.3598
	Y.U{1} = 
		    0.0099    0.8903
		    0.1370    0.7349
		    0.8188    0.6873
		    0.4302    0.3461

Tensor times matrix (ttm for tensor)

Compute a tensor times a matrix (or matrices) in one (or more) modes.

X = tensor(rand(5,3,4,2));
A = rand(4,5); B = rand(4,3); C = rand(3,4); D = rand(3,2);
Y = ttm(X, A, 1);         %<-- X times A in mode-1.
Y = ttm(X, {A,B,C,D}, 1); %<-- Same as above.
Y = ttm(X, A', 1, 't')    %<-- Same as above.
Y is a tensor of size 4 x 3 x 4 x 2
	Y(:,:,1,1) = 
	    1.0365    0.6095    0.7110
	    1.9302    1.4742    2.0003
	    1.7555    1.2961    1.7017
	    1.8896    1.4325    1.5902
	Y(:,:,2,1) = 
	    0.6694    0.9350    0.8098
	    1.4311    2.0724    1.5604
	    1.2080    1.5796    1.4965
	    1.2773    1.7966    1.4659
	Y(:,:,3,1) = 
	    1.1284    1.1872    1.2511
	    1.8427    1.8095    1.8762
	    1.6982    1.5964    1.5908
	    1.8864    1.8810    1.8543
	Y(:,:,4,1) = 
	    0.9565    1.0452    0.8766
	    1.7992    1.8762    1.8659
	    1.4832    1.6716    1.9043
	    1.6718    1.8121    1.7510
	Y(:,:,1,2) = 
	    1.1974    0.8965    0.8668
	    1.5665    2.1589    1.3825
	    1.3373    2.0494    1.1534
	    1.5943    2.0267    1.4569
	Y(:,:,2,2) = 
	    1.0229    1.3605    1.0827
	    2.3149    2.1127    1.9503
	    2.1861    1.8910    1.5869
	    2.0542    1.9491    1.9094
	Y(:,:,3,2) = 
	    0.7033    0.8874    0.5347
	    1.4749    1.4350    1.3381
	    1.5048    1.3274    1.2796
	    1.2465    1.5395    1.1617
	Y(:,:,4,2) = 
	    1.3135    0.2809    0.9096
	    2.4720    1.0792    1.5503
	    2.2423    0.9677    1.1401
	    2.3171    0.8680    1.4500
Y = ttm(X, {A,B,C,D}, [1 2 3 4]); %<-- 4-way mutliply.
Y = ttm(X, {D,C,B,A}, [4 3 2 1]); %<-- Same as above.
Y = ttm(X, {A,B,C,D});            %<-- Same as above.
Y = ttm(X, {A',B',C',D'}, 't')    %<-- Same as above.
Y is a tensor of size 4 x 4 x 3 x 3
	Y(:,:,1,1) = 
	    2.4869    4.5774    4.3080    2.4909
	    4.7042    8.5104    8.0518    4.6694
	    4.1588    7.5379    7.1537    4.1590
	    4.4802    8.1581    7.6647    4.4226
	Y(:,:,2,1) = 
	    2.4107    4.4549    4.1826    2.4144
	    4.8310    8.7053    8.2015    4.7393
	    4.2267    7.6101    7.2157    4.1903
	    4.4979    8.1691    7.6629    4.4153
	Y(:,:,3,1) = 
	    1.8798    3.4093    3.2097    1.8545
	    3.3879    6.1536    5.8167    3.3717
	    3.0143    5.4614    5.1902    3.0207
	    3.2654    5.9270    5.5773    3.2215
	Y(:,:,1,2) = 
	    1.4376    2.7014    2.5398    1.4693
	    2.7470    5.0786    4.7737    2.7583
	    2.4439    4.5664    4.2765    2.4655
	    2.6095    4.8234    4.5165    2.6018
	Y(:,:,2,2) = 
	    1.4740    2.7639    2.5977    1.5023
	    2.8931    5.3300    4.9868    2.8703
	    2.5479    4.7381    4.4189    2.5385
	    2.7060    4.9891    4.6705    2.6895
	Y(:,:,3,2) = 
	    1.0365    1.9368    1.8275    1.0598
	    1.9305    3.6151    3.4161    1.9837
	    1.7213    3.2586    3.0731    1.7830
	    1.8406    3.4297    3.2279    1.8680
	Y(:,:,1,3) = 
	    1.3367    2.4889    2.3411    1.3540
	    2.5428    4.6564    4.3894    2.5403
	    2.2559    4.1595    3.9180    2.2671
	    2.4183    4.4405    4.1641    2.4005
	Y(:,:,2,3) = 
	    1.3373    2.4918    2.3410    1.3528
	    2.6485    4.8327    4.5351    2.6148
	    2.3258    4.2653    4.0063    2.3123
	    2.4723    4.5286    4.2431    2.4440
	Y(:,:,3,3) = 
	    0.9845    1.8150    1.7108    0.9905
	    1.8066    3.3375    3.1542    1.8302
	    1.6093    2.9879    2.8273    1.6426
	    1.7309    3.1876    2.9998    1.7345
Y = ttm(X, {C,D}, [3 4]);    %<-- X times C in mode-3 & D in mode-4
Y = ttm(X, {A,B,C,D}, [3 4]) %<-- Same as above.
Y is a tensor of size 5 x 3 x 3 x 3
	Y(:,:,1,1) = 
	    1.5822    1.3415    1.3949
	    1.2553    1.1977    1.2159
	    1.4244    1.6067    1.3862
	    1.2104    0.7492    1.5089
	    1.2932    1.3210    1.1591
	Y(:,:,2,1) = 
	    1.5112    1.0441    1.3712
	    1.1439    1.2984    1.2236
	    1.5205    1.6549    1.5110
	    1.3913    0.8995    1.5692
	    1.2733    1.4256    1.0567
	Y(:,:,3,1) = 
	    1.0920    1.0458    1.1802
	    0.9569    0.8498    0.8816
	    0.9992    1.0501    0.9638
	    0.8583    0.5944    1.0157
	    0.9676    1.0079    0.8150
	Y(:,:,1,2) = 
	    0.9474    0.8303    0.7452
	    0.8904    0.7530    0.6234
	    0.7403    0.9461    0.8350
	    0.8144    0.4605    0.7893
	    0.7803    0.6910    0.7280
	Y(:,:,2,2) = 
	    0.9542    0.7092    0.7569
	    0.8336    0.8635    0.6079
	    0.8297    0.9292    0.9154
	    0.8980    0.5883    0.7834
	    0.8064    0.7848    0.7567
	Y(:,:,3,2) = 
	    0.6673    0.6108    0.5736
	    0.6973    0.4752    0.4593
	    0.5460    0.6273    0.5737
	    0.5921    0.3631    0.5820
	    0.5514    0.4938    0.5138
	Y(:,:,1,3) = 
	    0.8673    0.7494    0.7182
	    0.7597    0.6751    0.6126
	    0.7228    0.8726    0.7625
	    0.7098    0.4168    0.7683
	    0.7120    0.6726    0.6529
	Y(:,:,2,3) = 
	    0.8539    0.6157    0.7186
	    0.7037    0.7561    0.6064
	    0.7919    0.8754    0.8338
	    0.7962    0.5187    0.7797
	    0.7207    0.7460    0.6432
	Y(:,:,3,3) = 
	    0.6056    0.5653    0.5783
	    0.5887    0.4485    0.4479
	    0.5208    0.5749    0.5266
	    0.5108    0.3295    0.5433
	    0.5160    0.4959    0.4601
Y = ttm(X, {A,B,D}, [1 2 4]);   %<-- 3-way multiply.
Y = ttm(X, {A,B,C,D}, [1 2 4]); %<-- Same as above.
Y = ttm(X, {A,B,D}, -3);        %<-- Same as above.
Y = ttm(X, {A,B,C,D}, -3)       %<-- Same as above.
Y is a tensor of size 4 x 4 x 4 x 3
	Y(:,:,1,1) = 
	    1.0560    2.1553    2.0387    1.1911
	    2.4278    4.3898    4.2181    2.4754
	    2.1441    3.9274    3.7356    2.1771
	    2.2457    4.2196    3.9658    2.2936
	Y(:,:,2,1) = 
	    1.3324    2.2654    2.0972    1.1901
	    2.6489    4.6589    4.2674    2.4065
	    2.2210    3.9024    3.6500    2.0934
	    2.3874    4.1487    3.8458    2.1882
	Y(:,:,3,1) = 
	    1.5259    2.6902    2.5346    1.4625
	    2.4233    4.3577    4.1285    2.3958
	    2.1583    3.9709    3.7404    2.1642
	    2.4544    4.4132    4.1332    2.3769
	Y(:,:,4,1) = 
	    1.2470    2.3630    2.2327    1.2974
	    2.4531    4.5551    4.3305    2.5251
	    2.2263    4.0016    3.8576    2.2685
	    2.3016    4.2637    4.0530    2.3627
	Y(:,:,1,2) = 
	    0.6944    1.3989    1.3155    0.7645
	    1.4979    2.6951    2.5093    1.4364
	    1.3402    2.4234    2.2267    1.2614
	    1.4163    2.6071    2.4098    1.3735
	Y(:,:,2,2) = 
	    0.8962    1.5379    1.4173    0.8018
	    1.6626    3.0068    2.7746    1.5774
	    1.4220    2.6151    2.4249    1.3856
	    1.5214    2.7047    2.5241    1.4463
	Y(:,:,3,2) = 
	    0.8062    1.4427    1.3306    0.7556
	    1.3527    2.4504    2.3102    1.3362
	    1.2317    2.2839    2.1471    1.2410
	    1.3547    2.4308    2.2533    1.2850
	Y(:,:,4,2) = 
	    0.6588    1.3312    1.3007    0.7781
	    1.3637    2.6926    2.5765    1.5156
	    1.2072    2.3770    2.2702    1.3333
	    1.2520    2.4805    2.3848    1.4080
	Y(:,:,1,3) = 
	    0.6109    1.2374    1.1665    0.6794
	    1.3537    2.4408    2.3039    1.3333
	    1.2045    2.1900    2.0426    1.1717
	    1.2680    2.3547    2.1921    1.2574
	Y(:,:,2,3) = 
	    0.7812    1.3355    1.2330    0.6984
	    1.4915    2.6660    2.4525    1.3896
	    1.2650    2.2829    2.1244    1.2158
	    1.3562    2.3881    2.2224    1.2697
	Y(:,:,3,3) = 
	    0.7811    1.3880    1.2929    0.7398
	    1.2777    2.3069    2.1797    1.2626
	    1.1519    2.1284    2.0027    1.1581
	    1.2862    2.3100    2.1515    1.2317
	Y(:,:,4,3) = 
	    0.6383    1.2522    1.2053    0.7119
	    1.2905    2.4790    2.3654    1.3861
	    1.1555    2.1838    2.0942    1.2306
	    1.1966    2.2999    2.2001    1.2917

Sparse tensor times matrix (ttm for sptensor)

It is also possible to multiply an sptensor times a matrix or series of matrices. The arguments are the same as for the dense case. The result may be dense or sparse, depending on its density.

X = sptenrand([5 3 4 2],10);
Y = ttm(X, A, 1);         %<-- X times A in mode-1.
Y = ttm(X, {A,B,C,D}, 1); %<-- Same as above.
Y = ttm(X, A', 1, 't')    %<-- Same as above
Y is a sparse tensor of size 4 x 3 x 4 x 2 with 28 nonzeros
	(1,1,1,1)    0.1506
	(1,2,2,1)    0.0129
	(1,3,2,1)    0.0893
	(1,2,1,2)    0.4196
	(1,1,2,2)    0.0066
	(1,3,2,2)    0.0377
	(1,3,3,2)    0.4310
	(2,1,1,1)    0.7738
	(2,2,2,1)    0.3652
	(2,3,2,1)    0.4116
	(2,2,1,2)    0.2315
	(2,1,2,2)    0.1852
	(2,3,2,2)    0.2910
	(2,3,3,2)    0.7843
	(3,1,1,1)    0.8920
	(3,2,2,1)    0.2743
	(3,3,2,1)    0.3639
	(3,2,1,2)    0.3365
	(3,1,2,2)    0.1391
	(3,3,2,2)    0.2387
	(3,3,3,2)    0.9501
	(4,1,1,1)    0.5556
	(4,2,2,1)    0.3154
	(4,3,2,1)    0.1610
	(4,2,1,2)    0.4202
	(4,1,2,2)    0.1600
	(4,3,2,2)    0.1799
	(4,3,3,2)    0.7447
norm(full(Y) - ttm(full(X),A, 1) ) %<-- Same as dense case.
ans =
   5.5511e-17
Y = ttm(X, {A,B,C,D}, [1 2 3 4]); %<-- 4-way multiply.
Y = ttm(X, {D,C,B,A}, [4 3 2 1]); %<-- Same as above.
Y = ttm(X, {A,B,C,D});            %<-- Same as above.
Y = ttm(X, {A',B',C',D'}, 't')    %<-- Same as above.
Y is a tensor of size 4 x 4 x 3 x 3
	Y(:,:,1,1) = 
	    0.0890    0.1395    0.1470    0.0913
	    0.2458    0.5003    0.5113    0.3157
	    0.2497    0.5323    0.5461    0.3388
	    0.2063    0.4095    0.3985    0.2375
	Y(:,:,2,1) = 
	    0.0985    0.1757    0.1675    0.0976
	    0.3510    0.7241    0.7029    0.4190
	    0.3310    0.7403    0.7158    0.4273
	    0.2770    0.5858    0.5249    0.2942
	Y(:,:,3,1) = 
	    0.0419    0.0376    0.0617    0.0462
	    0.1291    0.1583    0.1999    0.1358
	    0.1288    0.1546    0.2055    0.1430
	    0.1050    0.1303    0.1583    0.1054
	Y(:,:,1,2) = 
	    0.0981    0.1224    0.1323    0.0821
	    0.1729    0.2599    0.3046    0.2013
	    0.1919    0.2865    0.3360    0.2219
	    0.1682    0.2465    0.2699    0.1710
	Y(:,:,2,2) = 
	    0.0973    0.1452    0.1299    0.0708
	    0.1977    0.3532    0.3625    0.2229
	    0.2021    0.3706    0.3744    0.2280
	    0.1835    0.3276    0.3052    0.1747
	Y(:,:,3,2) = 
	    0.0483    0.0371    0.0666    0.0510
	    0.1054    0.0994    0.1585    0.1176
	    0.1157    0.1031    0.1730    0.1305
	    0.0945    0.0895    0.1386    0.1018
	Y(:,:,1,3) = 
	    0.0719    0.0965    0.1034    0.0642
	    0.1480    0.2538    0.2795    0.1794
	    0.1587    0.2752    0.3040    0.1956
	    0.1361    0.2251    0.2346    0.1450
	Y(:,:,2,3) = 
	    0.0738    0.1169    0.1071    0.0599
	    0.1860    0.3555    0.3552    0.2152
	    0.1835    0.3684    0.3644    0.2199
	    0.1610    0.3092    0.2830    0.1605
	Y(:,:,3,3) = 
	    0.0350    0.0282    0.0491    0.0374
	    0.0853    0.0892    0.1296    0.0932
	    0.0905    0.0902    0.1384    0.1016
	    0.0739    0.0773    0.1094    0.0777
Y = ttm(X, {C,D}, [3 4]);    %<-- X times C in mode-3 & D in mode-4
Y = ttm(X, {A,B,C,D}, [3 4]) %<-- Same as above.
Y is a tensor of size 5 x 3 x 3 x 3
	Y(:,:,1,1) = 
	         0    0.1004    0.0998
	    0.4075         0    0.1363
	    0.0221    0.1332    0.0167
	         0         0    0.3307
	         0         0         0
	Y(:,:,2,1) = 
	         0    0.1323    0.0395
	    0.5371         0    0.0540
	    0.0427    0.2578    0.0322
	         0         0    0.6257
	         0         0         0
	Y(:,:,3,1) = 
	         0    0.0154    0.0943
	    0.0626         0    0.1289
	    0.0123    0.0742    0.0093
	         0         0    0.1878
	         0         0         0
	Y(:,:,1,2) = 
	         0    0.1342    0.1334
	    0.1478         0    0.1823
	    0.0295    0.0483    0.0223
	         0         0    0.1626
	         0         0         0
	Y(:,:,2,2) = 
	         0    0.1769    0.0528
	    0.1948         0    0.0722
	    0.0571    0.0935    0.0431
	         0         0    0.2955
	         0         0         0
	Y(:,:,3,2) = 
	         0    0.0206    0.1262
	    0.0227         0    0.1724
	    0.0164    0.0269    0.0124
	         0         0    0.0954
	         0         0         0
	Y(:,:,1,3) = 
	         0    0.0933    0.0927
	    0.1737         0    0.1267
	    0.0205    0.0568    0.0155
	         0         0    0.1630
	         0         0         0
	Y(:,:,2,3) = 
	         0    0.1229    0.0367
	    0.2290         0    0.0502
	    0.0397    0.1099    0.0300
	         0         0    0.3022
	         0         0         0
	Y(:,:,3,3) = 
	         0    0.0143    0.0877
	    0.0267         0    0.1198
	    0.0114    0.0316    0.0086
	         0         0    0.0942
	         0         0         0
Y = ttm(X, {A,B,D}, [1 2 4]);   %<-- 3-way multiply.
Y = ttm(X, {A,B,C,D}, [1 2 4]); %<-- Same as above.
Y = ttm(X, {A,B,D}, -3);        %<-- Same as above.
Y = ttm(X, {A,B,C,D}, -3)       %<-- Same as above.
Y is a tensor of size 4 x 4 x 4 x 3
	Y(:,:,1,1) = 
	    0.1010    0.2463    0.1918    0.0950
	    0.1515    0.7021    0.6066    0.3415
	    0.1879    0.8297    0.7130    0.3989
	    0.1573    0.5785    0.4856    0.2645
	Y(:,:,2,1) = 
	    0.0416    0.0313    0.0563    0.0431
	    0.3903    0.4667    0.4983    0.3058
	    0.3136    0.3615    0.4026    0.2533
	    0.2647    0.3646    0.3297    0.1801
	Y(:,:,3,1) = 
	    0.0468    0.0249    0.0651    0.0543
	    0.0851    0.0453    0.1184    0.0988
	    0.1031    0.0549    0.1434    0.1196
	    0.0808    0.0430    0.1124    0.0938
	Y(:,:,4,1) = 
	     0     0     0     0
	     0     0     0     0
	     0     0     0     0
	     0     0     0     0
	Y(:,:,1,2) = 
	    0.1147    0.2091    0.1501    0.0656
	    0.0980    0.3207    0.2645    0.1410
	    0.1308    0.3970    0.3232    0.1696
	    0.1353    0.3298    0.2568    0.1271
	Y(:,:,2,2) = 
	    0.0194    0.0152    0.0275    0.0211
	    0.1805    0.2340    0.2663    0.1713
	    0.1451    0.1809    0.2133    0.1397
	    0.1221    0.1841    0.1830    0.1087
	Y(:,:,3,2) = 
	    0.0626    0.0333    0.0870    0.0726
	    0.1138    0.0606    0.1584    0.1321
	    0.1379    0.0735    0.1919    0.1600
	    0.1081    0.0576    0.1504    0.1254
	Y(:,:,4,2) = 
	     0     0     0     0
	     0     0     0     0
	     0     0     0     0
	     0     0     0     0
	Y(:,:,1,3) = 
	    0.0834    0.1668    0.1233    0.0566
	    0.0868    0.3335    0.2816    0.1545
	    0.1125    0.4033    0.3373    0.1830
	    0.1074    0.3086    0.2487    0.1289
	Y(:,:,2,3) = 
	    0.0200    0.0153    0.0277    0.0212
	    0.1865    0.2324    0.2566    0.1616
	    0.1499    0.1798    0.2064    0.1327
	    0.1263    0.1822    0.1733    0.0992
	Y(:,:,3,3) = 
	    0.0435    0.0232    0.0605    0.0504
	    0.0791    0.0421    0.1100    0.0918
	    0.0958    0.0510    0.1333    0.1112
	    0.0751    0.0400    0.1045    0.0872
	Y(:,:,4,3) = 
	     0     0     0     0
	     0     0     0     0
	     0     0     0     0
	     0     0     0     0

The result may be dense or sparse.

X = sptenrand([5 3 4],1);
Y = ttm(X, A, 1) %<-- Sparse result.
Y is a sparse tensor of size 4 x 3 x 4 with 4 nonzeros
	(1,3,2)    0.0232
	(2,3,2)    0.1067
	(3,3,2)    0.0943
	(4,3,2)    0.0417
X = sptenrand([5 3 4],50);
Y = ttm(X, A, 1) %<-- Dense result.
Y is a tensor of size 4 x 3 x 4
	Y(:,:,1) = 
	    0.4159    0.5631    0.0406
	    0.9765    1.4239    0.2088
	    0.9029    1.2234    0.2406
	    0.8744    1.2606    0.1499
	Y(:,:,2) = 
	    1.0127    0.5477         0
	    1.4153    1.1141         0
	    1.1989    1.0105         0
	    1.6381    0.9835         0
	Y(:,:,3) = 
	    0.5923    0.6934    0.9184
	    0.8260    0.9650    0.8641
	    0.4955    0.7236    0.5323
	    0.8762    0.9604    1.0351
	Y(:,:,4) = 
	    1.2906    0.7036    0.4899
	    1.2638    0.8427    1.1469
	    1.1332    0.8936    1.0464
	    1.5305    0.9649    0.9588

Sometimes the product may be too large to reside in memory. For example, try the following: X = sptenrand([100 100 100 100], 1e4); A = rand(1000,100); ttm(X,A,1); %<-- too large for memory

Matricized Khatri-Rao product of a tensor.

mttkrp computes the matricized Khatri-Rao product of a tensor X with a cell array of matrices U. The operation first matricizes (i.e. flattens) a tensor X with m modes, in a given mode n. Then the Khatri-Rao product of a cell array of matrices U={U1,...,Um} is computed, omitting the nth term in the array. The returned value is then the product matricized tensor X and Khatri-Rao product of the cell array. This operation is useful in many numerical procedures, e.g. formulating the subproblems in an alternating least squares CP decomposition of tensor.

Each matrix in the cell array U must have the same number of columns. The number of rows of the matrix Ui equal the dimension of X in mode i. In the example that follows we will verify that mttkrp performs the calculation indicated above.

U = {rand(2,3), 2*rand(3,3), 3*rand(4,3)}; %<--the cell array
X = tensor(rand(2,3,4)); %<--the tensor
n = 2; %<--the dimension to matricize with respect to.

KRP = khatrirao(U{1}, U{3}); %<--Khatri-Rao product, omitting U{2}
M = permute(X.data, [n:size(X,n), 1:n-1]);
M = reshape(M,size(X,n),[]); %<--Matricized tensor data

norm(M*KRP-mttkrp(X,U,n)) < 1e-14 %<--They are equal, within machine precision
ans =
  logical
   1

Kruskal tensor times matrix (ttm for ktensor)

The special structure of a ktensor allows an efficient implementation of matrix multiplication. The arguments are the same as for the dense case.

X = ktensor({rand(5,1) rand(3,1) rand(4,1) rand(2,1)});
Y = ttm(X, A, 1);         %<-- X times A in mode-1.
Y = ttm(X, {A,B,C,D}, 1); %<-- Same as above.
Y = ttm(X, A', 1, 't')    %<-- Same as above.
Y is a ktensor of size 4 x 3 x 4 x 2
	Y.lambda = 
		     1
	Y.U{1} = 
		    0.9195
		    1.0464
		    1.0804
		    1.2324
	Y.U{2} = 
		    0.3348
		    0.3762
		    0.9522
	Y.U{3} = 
		    0.7193
		    0.7793
		    0.6177
		    0.6492
	Y.U{4} = 
		    0.7563
		    0.1478
Y = ttm(X, {A,B,C,D}, [1 2 3 4]); %<-- 4-way mutliply.
Y = ttm(X, {D,C,B,A}, [4 3 2 1]); %<-- Same as above.
Y = ttm(X, {A,B,C,D});            %<-- Same as above.
Y = ttm(X, {A',B',C',D'}, 't')    %<-- Same as above.
Y is a ktensor of size 4 x 4 x 3 x 3
	Y.lambda = 
		     1
	Y.U{1} = 
		    0.9195
		    1.0464
		    1.0804
		    1.2324
	Y.U{2} = 
		    0.6186
		    0.8281
		    0.9655
		    0.6314
	Y.U{3} = 
		    1.2905
		    1.3673
		    0.9019
	Y.U{4} = 
		    0.7582
		    0.3193
		    0.3461
Y = ttm(X, {C,D}, [3 4]);    %<-- X times C in mode-3 & D in mode-4.
Y = ttm(X, {A,B,C,D}, [3 4]) %<-- Same as above.
Y is a ktensor of size 5 x 3 x 3 x 3
	Y.lambda = 
		     1
	Y.U{1} = 
		    0.9971
		    0.3462
		    0.1761
		    0.0679
		    0.3094
	Y.U{2} = 
		    0.3348
		    0.3762
		    0.9522
	Y.U{3} = 
		    1.2905
		    1.3673
		    0.9019
	Y.U{4} = 
		    0.7582
		    0.3193
		    0.3461
Y = ttm(X, {A,B,D}, [1 2 4]);   %<-- 3-way multiply.
Y = ttm(X, {A,B,C,D}, [1 2 4]); %<-- Same as above.
Y = ttm(X, {A,B,D}, -3);        %<-- Same as above.
Y = ttm(X, {A,B,C,D}, -3)       %<-- Same as above.
Y is a ktensor of size 4 x 4 x 4 x 3
	Y.lambda = 
		     1
	Y.U{1} = 
		    0.9195
		    1.0464
		    1.0804
		    1.2324
	Y.U{2} = 
		    0.6186
		    0.8281
		    0.9655
		    0.6314
	Y.U{3} = 
		    0.7193
		    0.7793
		    0.6177
		    0.6492
	Y.U{4} = 
		    0.7582
		    0.3193
		    0.3461

Tucker tensor times matrix (ttm for ttensor)

The special structure of a ttensor allows an efficient implementation of matrix multiplication.

X = ttensor(tensor(rand(2,2,2,2)),{rand(5,2) rand(3,2) rand(4,2) rand(2,2)});
Y = ttm(X, A, 1);         %<-- computes X times A in mode-1.
Y = ttm(X, {A,B,C,D}, 1); %<-- Same as above.
Y = ttm(X, A', 1, 't')    %<-- Same as above.
Y is a ttensor of size 4 x 3 x 4 x 2
	Y.core is a tensor of size 2 x 2 x 2 x 2
		Y.core(:,:,1,1) = 
	    0.5995    0.1719
	    0.8986    0.8189
		Y.core(:,:,2,1) = 
	    0.0693    0.3173
	    0.9557    0.0052
		Y.core(:,:,1,2) = 
	    0.7599    0.7153
	    0.3087    0.0809
		Y.core(:,:,2,2) = 
	    0.8459    0.8704
	    0.7184    0.8722
	Y.U{1} = 
		    1.3576    0.9672
		    2.5857    1.7605
		    2.2392    1.4629
		    2.4193    1.6863
	Y.U{2} = 
		    0.7233    0.4236
		    0.2397    0.7957
		    0.4899    0.7634
	Y.U{3} = 
		    0.2389    0.2685
		    0.6351    0.9912
		    0.2315    0.7603
		    0.6159    0.4822
	Y.U{4} = 
		    0.9452    0.0844
		    0.3607    0.9485
Y = ttm(X, {A,B,C,D}, [1 2 3 4]); %<-- 4-way multiply.
Y = ttm(X, {D,C,B,A}, [4 3 2 1]); %<-- Same as above.
Y = ttm(X, {A,B,C,D});            %<-- Same as above.
Y = ttm(X, {A',B',C',D'}, 't')    %<-- Same as above.
Y is a ttensor of size 4 x 4 x 3 x 3
	Y.core is a tensor of size 2 x 2 x 2 x 2
		Y.core(:,:,1,1) = 
	    0.5995    0.1719
	    0.8986    0.8189
		Y.core(:,:,2,1) = 
	    0.0693    0.3173
	    0.9557    0.0052
		Y.core(:,:,1,2) = 
	    0.7599    0.7153
	    0.3087    0.0809
		Y.core(:,:,2,2) = 
	    0.8459    0.8704
	    0.7184    0.8722
	Y.U{1} = 
		    1.3576    0.9672
		    2.5857    1.7605
		    2.2392    1.4629
		    2.4193    1.6863
	Y.U{2} = 
		    0.4280    0.8254
		    0.9494    1.2692
		    0.9504    1.2097
		    0.5811    0.6974
	Y.U{3} = 
		    0.7658    1.1522
		    0.8756    1.1782
		    0.5976    0.9002
	Y.U{4} = 
		    1.0017    0.3714
		    0.4715    0.4192
		    0.4829    0.3051
Y = ttm(X, {C,D}, [3 4]);    %<-- X times C in mode-3 & D in mode-4
Y = ttm(X, {A,B,C,D}, [3 4]) %<-- Same as above.
Y is a ttensor of size 5 x 3 x 3 x 3
	Y.core is a tensor of size 2 x 2 x 2 x 2
		Y.core(:,:,1,1) = 
	    0.5995    0.1719
	    0.8986    0.8189
		Y.core(:,:,2,1) = 
	    0.0693    0.3173
	    0.9557    0.0052
		Y.core(:,:,1,2) = 
	    0.7599    0.7153
	    0.3087    0.0809
		Y.core(:,:,2,2) = 
	    0.8459    0.8704
	    0.7184    0.8722
	Y.U{1} = 
		    0.7616    0.6399
		    0.6695    0.1562
		    0.9020    0.7832
		    0.8215    0.7314
		    0.8327    0.5647
	Y.U{2} = 
		    0.7233    0.4236
		    0.2397    0.7957
		    0.4899    0.7634
	Y.U{3} = 
		    0.7658    1.1522
		    0.8756    1.1782
		    0.5976    0.9002
	Y.U{4} = 
		    1.0017    0.3714
		    0.4715    0.4192
		    0.4829    0.3051
Y = ttm(X, {A,B,D}, [1 2 4]);   %<-- 3-way multiply
Y = ttm(X, {A,B,C,D}, [1 2 4]); %<-- Same as above.
Y = ttm(X, {A,B,D}, -3);        %<-- Same as above.
Y = ttm(X, {A,B,C,D}, -3)       %<-- Same as above.
Y is a ttensor of size 4 x 4 x 4 x 3
	Y.core is a tensor of size 2 x 2 x 2 x 2
		Y.core(:,:,1,1) = 
	    0.5995    0.1719
	    0.8986    0.8189
		Y.core(:,:,2,1) = 
	    0.0693    0.3173
	    0.9557    0.0052
		Y.core(:,:,1,2) = 
	    0.7599    0.7153
	    0.3087    0.0809
		Y.core(:,:,2,2) = 
	    0.8459    0.8704
	    0.7184    0.8722
	Y.U{1} = 
		    1.3576    0.9672
		    2.5857    1.7605
		    2.2392    1.4629
		    2.4193    1.6863
	Y.U{2} = 
		    0.4280    0.8254
		    0.9494    1.2692
		    0.9504    1.2097
		    0.5811    0.6974
	Y.U{3} = 
		    0.2389    0.2685
		    0.6351    0.9912
		    0.2315    0.7603
		    0.6159    0.4822
	Y.U{4} = 
		    1.0017    0.3714
		    0.4715    0.4192
		    0.4829    0.3051

Tensor times tensor (ttt for tensor)

X = tensor(rand(4,2,3)); Y = tensor(rand(3,4,2));
Z = ttt(X,Y); %<-- Outer product of X and Y.
size(Z)
ans =
     4     2     3     3     4     2
Z = ttt(X,X,1:3) %<-- Inner product of X with itself.
Z =
    8.9942
Z = ttt(X,Y,[1 2 3],[2 3 1]) %<-- Inner product of X & Y.
Z =
    6.3410
Z = innerprod(X,permute(Y, [2 3 1])) %<-- Same as above.
Z =
    6.3410
Z = ttt(X,Y,[1 3],[2 1]) %<-- Product of X & Y along specified dims.
Z is a tensor of size 2 x 2
	Z(:,:) = 
	    2.4886    2.4765
	    3.2827    3.8524

Sparse tensor times sparse tensor (ttt for sptensor)

X = sptenrand([4 2 3],3); Y = sptenrand([3 4 2],3);
Z = ttt(X,Y) %<--Outer product of X and Y.
Z is a sparse tensor of size 4 x 2 x 3 x 3 x 4 x 2 with 9 nonzeros
	(1,1,3,1,3,1)    0.1445
	(1,1,3,3,1,1)    0.4935
	(1,1,3,3,4,1)    0.5292
	(2,2,3,1,3,1)    0.1181
	(2,2,3,3,1,1)    0.4033
	(2,2,3,3,4,1)    0.4325
	(3,2,1,1,3,1)    0.1132
	(3,2,1,3,1,1)    0.3867
	(3,2,1,3,4,1)    0.4147
norm(full(Z)-ttt(full(X),full(Y))) %<-- Same as dense.
ans =
     0
Z = ttt(X,X,1:3) %<-- Inner product of X with itself.
Z =
    2.2738
X = sptenrand([2 3],1); Y = sptenrand([3 2],1);
Z = ttt(X, Y) %<-- Sparse result.
Z is a sparse tensor of size 2 x 3 x 3 x 2 with 1 nonzeros
	(2,1,2,1)    0.7262
X = sptenrand([2 3],20); Y = sptenrand([3 2],20);
Z = ttt(X, Y) %<-- Dense result.
Z is a tensor of size 2 x 3 x 3 x 2
	Z(:,:,1,1) = 
	         0    0.1584    0.1237
	    0.5586    0.2357    0.0374
	Z(:,:,2,1) = 
	         0    0.1367    0.1067
	    0.4820    0.2034    0.0322
	Z(:,:,3,1) = 
	         0    0.1968    0.1536
	    0.6939    0.2928    0.0464
	Z(:,:,1,2) = 
	         0    0.0550    0.0430
	    0.1940    0.0819    0.0130
	Z(:,:,2,2) = 
	         0    0.0418    0.0326
	    0.1473    0.0622    0.0099
	Z(:,:,3,2) = 
	         0    0.1293    0.1009
	    0.4559    0.1924    0.0305
Z = ttt(X,Y,[1 2],[2 1]) %<-- inner product of X & Y
Z =
    0.5770

Inner product (innerprod)

The function innerprod efficiently computes the inner product between two tensors X and Y. The code does this efficiently depending on what types of tensors X and Y.

X = tensor(rand(2,2,2))
Y = ktensor({rand(2,2),rand(2,2),rand(2,2)})
X is a tensor of size 2 x 2 x 2
	X(:,:,1) = 
	    0.6496    0.3348
	    0.0418    0.4334
	X(:,:,2) = 
	    0.0986    0.0271
	    0.6809    0.3208
Y is a ktensor of size 2 x 2 x 2
	Y.lambda = 
		     1     1
	Y.U{1} = 
		    0.0525    0.3839
		    0.3696    0.3359
	Y.U{2} = 
		    0.8907    0.0810
		    0.2381    0.3015
	Y.U{3} = 
		    0.1800    0.7903
		    0.7162    0.3313
z = innerprod(X,Y)
z =
    0.3010

Contraction on tensors (contract for tensor)

The function contract sums the entries of X along dimensions I and J. Contraction is a generalization of matrix trace. In other words, the trace is performed along the two-dimensional slices defined by dimensions I and J. It is possible to implement tensor multiplication as an outer product followed by a contraction.

X = sptenrand([4 3 2],5);
Y = sptenrand([3 2 4],5);
Z1 = ttt(X,Y,1,3); %<-- Normal tensor multiplication
Z2 = contract(ttt(X,Y),1,6); %<-- Outer product + contract
norm(Z1-Z2) %<-- Should be zero
ans =
     0

Using contract on either sparse or dense tensors gives the same result

X = sptenrand([4 2 3 4],20);
Z1 = contract(X,1,4)        % sparse version of contract
Z1 is a tensor of size 2 x 3
	Z1(:,:) = 
	    0.0047    0.2498    0.2491
	    0.5821    0.4739    0.3943
Z2 = contract(full(X),1,4)  % dense version of contract
Z2 is a tensor of size 2 x 3
	Z2(:,:) = 
	    0.0047    0.2498    0.2491
	    0.5821    0.4739    0.3943
norm(full(Z1) - Z2) %<-- Should be zero
ans =
     0

The result may be dense or sparse, depending on its density.

X = sptenrand([4 2 3 4],8);
Y = contract(X,1,4) %<-- should be sparse
Y is a sparse tensor of size 2 x 3 with 2 nonzeros
	(1,3)    0.5531
	(2,2)    0.7281
X = sptenrand([4 2 3 4],80);
Y = contract(X,1,4) %<-- should be dense
Y is a tensor of size 2 x 3
	Y(:,:) = 
	    1.0451    1.9378    0.9447
	    1.9514    1.3196    1.6253

Relationships among ttv, ttm, and ttt

The three "tensor times _" functions (ttv, ttm, ttt) all perform specialized calculations, but they are all related to some degree. Here are several relationships among them:

X = tensor(rand(4,3,2));
A = rand(4,1);

Tensor times vector gives a 3 x 2 result

Y1 = ttv(X,A,1)
Y1 is a tensor of size 3 x 2
	Y1(:,:) = 
	    1.3897    1.2870
	    0.3184    0.6756
	    0.5032    1.3496

When ttm is used with the transpose option, the result is almost the same as ttv

Y2 = ttm(X,A,1,'t')
Y2 is a tensor of size 1 x 3 x 2
	Y2(:,:,1) = 
	    1.3897    0.3184    0.5032
	Y2(:,:,2) = 
	    1.2870    0.6756    1.3496

We can use squeeze to remove the singleton dimension left over from ttm to give the same answer as ttv

squeeze(Y2)
ans is a tensor of size 3 x 2
	ans(:,:) = 
	    1.3897    1.2870
	    0.3184    0.6756
	    0.5032    1.3496

Tensor outer product may be used in conjuction with contract to produce the result of ttm. Please note that this is more expensive than using ttm.

Z = ttt(tensor(A),X);
size(Z)
ans =
     4     1     4     3     2
Y3 = contract(Z,1,3)
Y3 is a tensor of size 1 x 3 x 2
	Y3(:,:,1) = 
	    1.3897    0.3184    0.5032
	Y3(:,:,2) = 
	    1.2870    0.6756    1.3496

Finally, use squeeze to remove the singleton dimension to get the same result as ttv.

squeeze(Y3)
ans is a tensor of size 3 x 2
	ans(:,:) = 
	    1.3897    1.2870
	    0.3184    0.6756
	    0.5032    1.3496

Frobenius norm of a tensor

The Frobenius norm of any type of tensor may be computed with the function norm. Each class is optimized to calculate the norm in the most efficient manner.

X = sptenrand([4 3 2],5)
norm(X)
norm(full(X))
X is a sparse tensor of size 4 x 3 x 2 with 5 nonzeros
	(2,2,1)    0.8295
	(2,3,2)    0.7905
	(3,2,2)    0.8002
	(3,3,1)    0.9895
	(4,1,1)    0.8698
ans =
    1.9206
ans =
    1.9206
X = ktensor({rand(4,2),rand(3,2)})
norm(X)
X is a ktensor of size 4 x 3
	X.lambda = 
		     1     1
	X.U{1} = 
		    0.8201    0.6458
		    0.9506    0.2407
		    0.5689    0.0888
		    0.1064    0.9876
	X.U{2} = 
		    0.7440    0.7862
		    0.5461    0.8098
		    0.4219    0.6288
ans =
    2.6010
X = ttensor(tensor(rand(2,2)),{rand(4,2),rand(3,2)})
norm(X)
X is a ttensor of size 4 x 3
	X.core is a tensor of size 2 x 2
		X.core(:,:) = 
	    0.3186    0.0491
	    0.3027    0.6021
	X.U{1} = 
		    0.2244    0.6691
		    0.8587    0.8619
		    0.7536    0.8412
		    0.2630    0.0178
	X.U{2} = 
		    0.8048    0.1238
		    0.5318    0.0792
		    0.3100    0.3897
ans =
    1.0605