# How to apply a linear transformation to a tensor?

I would like to apply a linear transformation to a tensor. My linear transformation is encoded by a matrix, for example

M = Table[m[i, j], {i, 4}, {j, 4}]

Take some vectors

V = Table[v[i], {i, 4}]

W = Table[w[i], {i, 4}]

I apply the linear transformation to vectors with the dot operator

M . V

M . W

Now I would like to apply the same linear transformation to tensors, in a compatible ways. For a tensor of order two, the linear transformation is encoded by the tensor product matrix

TensorProduct[M,M]

But how do I apply it to a tensor? The dot operator doesn't give the right result. For example, imagine I want to apply my linear transformation to the following tensor

TensorProduct[V,W]

I would like to have that

TensorProduct[M,M] . TensorProduct[V,W] === TensorProduct[M . V, M . W]

But this is False. The dot operator is not the correct way. What is the right way? I would like to apply this linear transformation also to other tensors, not just tensors of the form TensorProduct[V,W]

Moreover, I would like to apply the linear transformation also to tensors of higher order, not just tensors of order 2.

Thank you for any help!

• Welcome to Mathematica.SE! I hope you will become a regular contributor. To get started, 1) take the introductory tour now, 2) when you see good questions and answers, vote them up by clicking the gray triangles, because the credibility of the system is based on the reputation gained by users sharing their knowledge, 3) remember to accept the answer, if any, that solves your problem, by clicking the checkmark sign, and 4) give help too, by answering questions in your areas of expertise. Jan 16 at 16:10

If I understand your question correctly, you're looking to rotate a tensor of arbitrary rank using a transformation matrix. This can be done using the tensor product:

$$$$\hat{B}_{i_1 i_2 ... i_ n} = \sum_{j_1 = 1}^d \sum_{j_1 = 1}^d ... \sum_{j_n = 1}^d A_{i_1 j_1} A_{i_2 j_2} ... A_{i_n j_n} B_{j_1 j_2 ... j_n} \ .$$$$

There's several implementations of this in this question. Here's one example:

rayleighProduct[transformationMatrix_, tensor_] := Block[{n, it, t1},
n = TensorRank[tensor];
it = RotateLeft[Range[n]];
t1 = tensor;
Do[t1 = TensorTranspose[transformationMatrix . t1, it], {i, n}];
t1]


Some examples:

M = Table[m[i, j], {i, 4}, {j, 4}];
V = Table[v[i], {i, 4}];
Q = Table[q[i, j], {i, 4}, {j, 4}];

M.V == rayleighProduct[M, V]
M.Q.Transpose[M] == rayleighProduct[M, Q]

• Thank you very much! I didn't know the name Rayleigh Product. I tested it. The following command Simplify[rayleighProduct[M, TensorProduct[V, W]] - TensorProduct[M . V, M . W]] Gives zero. It also works for tensors of order 3:  Simplify[rayleighProduct[M, TensorProduct[V, W, X]] - TensorProduct[M . V, M . W, M . X]]  this also gives zero. So I think this is what I need! Jan 16 at 16:44

Assume you have 2 vectors V and W and construct the tensor product "t1=TesorProduct[V,W]". If you apply a linear transformation: M to the vectors V,W: M.V,M.W. How do you then get "t2=TensorProduct[M.V,M.W]" from t1?

t2=M.TensorProduct[V, W].Transpose[M]


You can check this by a simple example:

n = 4;
M = Table[m[i, j], {i, n}, {j, n}];
V = Table[v[i], {i, n}];
W = Table[w[i], {i, n}];

M. TensorProduct[V, W].Transpose[M] ==
TensorProduct[M . V, M . W] // Simplify

( True *)


Update

The same can be written using "TensorContract" in a form that can easily be generalized to more dimensions:

TensorProduct[M . V, M . W] ==
TensorContract[
TensorProduct[M, V, M, W], {{2, 3}, {5, 6}}] // Expand

(* True *)


For more dimensions we may have e.g:

X = Table[w[i], {i, n}];
TensorProduct[M . V, M . W, M . X] ==
TensorContract[
TensorProduct[M, V, M, W, M,
X], {{2, 3}, {5, 6}, {8, 9}}] // Expand

(* True*)

• Thanks! Yes, I know the transpose on the other side can work for tensors of order 2. But How can I generalize this for tensors of order 3 or higher? George's answer works for tensors of any order. Jan 16 at 17:36
• With the right notation, this can easily be generalized for higher tensors. Look my update. Jan 16 at 18:18
• Unfortunately, using TensorProduct and TensorContract like this becomes quickly super slow... Jan 16 at 18:21
• I see, I had never used TensorContract before. But there is still an issue with this solution. You have to imagine that I don't know V and W, I only have one tensor (in this case, TensorProduct[V,W]). So, what I need to do is to permute the factors with reference to your solution. The right order is TensorContract[TensorProduct[M, M, V, W], {{2, 5}, {4, 6}}]  Jan 16 at 21:05
• With this order, I can now write the equivalent  TensorContract[ TensorProduct[M, M, TensorProduct[V, W]], {{2, 5}, {4, 6}}] This contains only things I know. Jan 16 at 21:06