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 =

  8.8340e-016

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.78558 ]
	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.93892 ]
	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 =

  3.9154e-016

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 =

     0

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

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.7712
		    2.1158
		    2.0046
		    1.8224
	Y.U{2} = 
		    0.3790
		    0.3373
		    0.3146
	Y.U{3} = 
		    0.9471
		    0.5352
		    0.7020
		    0.8750
	Y.U{4} = 
		    0.9862
		    0.8853
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.7712
		    2.1158
		    2.0046
		    1.8224
	Y.U{2} = 
		    0.3761
		    0.7098
		    0.6619
		    0.3805
	Y.U{3} = 
		    1.4859
		    1.4836
		    1.0471
	Y.U{4} = 
		    1.2018
		    0.7014
		    0.6494
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.5430
		    0.9035
		    0.8613
		    0.6315
		    0.2624
	Y.U{2} = 
		    0.3790
		    0.3373
		    0.3146
	Y.U{3} = 
		    1.4859
		    1.4836
		    1.0471
	Y.U{4} = 
		    1.2018
		    0.7014
		    0.6494
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.7712
		    2.1158
		    2.0046
		    1.8224
	Y.U{2} = 
		    0.3761
		    0.7098
		    0.6619
		    0.3805
	Y.U{3} = 
		    0.9471
		    0.5352
		    0.7020
		    0.8750
	Y.U{4} = 
		    1.2018
		    0.7014
		    0.6494

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.4048    0.3855
	    0.6271    0.8479
		Y.core(:,:,2,1) = 
	    0.5268    0.3935
	    0.8074    0.9617
		Y.core(:,:,1,2) = 
	    0.0301    0.7144
	    0.9537    0.6465
		Y.core(:,:,2,2) = 
	    0.4467    0.8352
	    0.1746    0.9701
	Y.U{1} = 
		    0.7287    1.1203
		    1.8017    1.4937
		    1.3952    1.1431
		    1.5770    1.4536
	Y.U{2} = 
		    0.0144    0.7729
		    0.4858    0.4881
		    0.4164    0.5226
	Y.U{3} = 
		    0.7820    0.6629
		    0.5912    0.9971
		    0.1264    0.3462
		    0.1097    0.1761
	Y.U{4} = 
		    0.0679    0.3348
		    0.3094    0.3762
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.4048    0.3855
	    0.6271    0.8479
		Y.core(:,:,2,1) = 
	    0.5268    0.3935
	    0.8074    0.9617
		Y.core(:,:,1,2) = 
	    0.0301    0.7144
	    0.9537    0.6465
		Y.core(:,:,2,2) = 
	    0.4467    0.8352
	    0.1746    0.9701
	Y.U{1} = 
		    0.7287    1.1203
		    1.8017    1.4937
		    1.3952    1.1431
		    1.5770    1.4536
	Y.U{2} = 
		    0.4505    0.6010
		    0.5530    1.2351
		    0.5263    1.1635
		    0.2970    0.6779
	Y.U{3} = 
		    0.6823    0.9247
		    0.9196    1.1786
		    0.2928    0.5203
	Y.U{4} = 
		    0.1592    0.4312
		    0.1505    0.2692
		    0.1157    0.2421
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.4048    0.3855
	    0.6271    0.8479
		Y.core(:,:,2,1) = 
	    0.5268    0.3935
	    0.8074    0.9617
		Y.core(:,:,1,2) = 
	    0.0301    0.7144
	    0.9537    0.6465
		Y.core(:,:,2,2) = 
	    0.4467    0.8352
	    0.1746    0.9701
	Y.U{1} = 
		    0.1350    0.5122
		    0.2510    0.0035
		    0.9100    0.2269
		    0.6765    0.9785
		    0.6232    0.8613
	Y.U{2} = 
		    0.0144    0.7729
		    0.4858    0.4881
		    0.4164    0.5226
	Y.U{3} = 
		    0.6823    0.9247
		    0.9196    1.1786
		    0.2928    0.5203
	Y.U{4} = 
		    0.1592    0.4312
		    0.1505    0.2692
		    0.1157    0.2421
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.4048    0.3855
	    0.6271    0.8479
		Y.core(:,:,2,1) = 
	    0.5268    0.3935
	    0.8074    0.9617
		Y.core(:,:,1,2) = 
	    0.0301    0.7144
	    0.9537    0.6465
		Y.core(:,:,2,2) = 
	    0.4467    0.8352
	    0.1746    0.9701
	Y.U{1} = 
		    0.7287    1.1203
		    1.8017    1.4937
		    1.3952    1.1431
		    1.5770    1.4536
	Y.U{2} = 
		    0.4505    0.6010
		    0.5530    1.2351
		    0.5263    1.1635
		    0.2970    0.6779
	Y.U{3} = 
		    0.7820    0.6629
		    0.5912    0.9971
		    0.1264    0.3462
		    0.1097    0.1761
	Y.U{4} = 
		    0.1592    0.4312
		    0.1505    0.2692
		    0.1157    0.2421

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 =

   10.8350

Z = ttt(X,Y,[1 2 3],[2 3 1]) %<-- Inner product of X & Y.
Z =

    9.3217

Z = innerprod(X,Y) %<-- Same as above.
Z =

    8.3864

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(:,:) = 
	    4.6551    3.8834
	    4.4565    4.6666

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,2,1,1,1,1)    0.0241
	(1,2,1,3,2,2)    0.0505
	(1,2,1,3,4,2)    0.0700
	(2,2,1,1,1,1)    0.1406
	(2,2,1,3,2,2)    0.2947
	(2,2,1,3,4,2)    0.4084
	(4,2,3,1,1,1)    0.1106
	(4,2,3,3,2,2)    0.2319
	(4,2,3,3,4,2)    0.3214
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 =

    0.5856

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,2,1,2)    0.2167
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.8652    0.4460    0.3551
	    0.8837    0.6871    0.8792
	Z(:,:,2,1) = 
	    0.1967    0.1014    0.0807
	    0.2009    0.1562    0.1998
	Z(:,:,3,1) = 
	    0.7741    0.3991    0.3177
	    0.7907    0.6148    0.7867
	Z(:,:,1,2) = 
	    0.6209    0.3201    0.2549
	    0.6343    0.4931    0.6310
	Z(:,:,2,2) = 
	    0.0666    0.0344    0.0274
	    0.0681    0.0529    0.0677
	Z(:,:,3,2) = 
	    0.4093    0.2110    0.1680
	    0.4181    0.3250    0.4159
Z = ttt(X,Y,[1 2],[2 1]) %<-- inner product of X & Y
Z =

    2.3874

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.8923    0.4009
	    0.9919    0.3407
	X(:,:,2) = 
	    0.3167    0.6157
	    0.3643    0.5975
Y is a ktensor of size 2 x 2 x 2
	Y.lambda = [ 1  1 ]
	Y.U{1} = 
		    0.6852    0.2803
		    0.9738    0.1740
	Y.U{2} = 
		    0.9219    0.3751
		    0.2602    0.6447
	Y.U{3} = 
		    0.3165    0.2332
		    0.1924    0.2198
z = innerprod(X,Y)
z =

    0.7764

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         0    0.6799
	    0.9183    0.1945    0.5504
Z2 = contract(full(X),1,4)  % dense version of contract
Z2 is a tensor of size 2 x 3
	Z2(:,:) = 
	         0         0    0.6799
	    0.9183    0.1945    0.5504
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,2)    0.3194
	(2,3)    0.0341
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.9795    1.3526    1.7949
	    0.8789    1.7861    0.2635

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.3525    0.7826
	    0.4640    0.6248
	    0.3595    0.6841

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.3525    0.4640    0.3595
	Y2(:,:,2) = 
	    0.7826    0.6248    0.6841

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.3525    0.7826
	    0.4640    0.6248
	    0.3595    0.6841

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.3525    0.4640    0.3595
	Y3(:,:,2) = 
	    0.7826    0.6248    0.6841

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.3525    0.7826
	    0.4640    0.6248
	    0.3595    0.6841

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
	(1,1,1)    0.4315
	(1,3,2)    0.0963
	(2,3,1)    0.2578
	(3,1,2)    0.1131
	(3,2,1)    0.1691

ans =

    0.5507


ans =

    0.5507

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.7782    0.7981
		    0.5535    0.2071
		    0.0126    0.5604
		    0.5964    0.9688
	X.U{2} = 
		    0.2473    0.9360
		    0.4601    0.0894
		    0.6999    0.3869

ans =

    2.0976

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.8863    0.9777
	    0.1854    0.6602
	X.U{1} = 
		    0.1073    0.6613
		    0.3096    0.8004
		    0.1871    0.5998
		    0.3794    0.2723
	X.U{2} = 
		    0.6679    0.6879
		    0.5256    0.1727
		    0.1006    0.7775

ans =

    1.7854