# TensorExpand can't expand in the presence of Hadamard product

I'm trying to expand a symbolic matrix product. In the absence of Hadamard product everything works as expected:

P[t_] := P0 + E^(-t/3) P1;

Assuming[
P0 ∈ Matrices[{4, 4}] && P1 ∈ Matrices[{4, 4}] &&
v1 ∈ Vectors, TensorExpand[P[t0].P[t1].v1]]

MatrixPower[P0, 2].v1 + E^(-(t0/3) - t1/3) MatrixPower[P1, 2].v1 +
E^(-t1/3) P0.P1.v1 + E^(-t0/3) P1.P0.v1


But in the presence of a Hadamard product TensorExpand can't expand:

Assuming[P0 ∈ Matrices[{4, 4}] &&
P1 ∈ Matrices[{4, 4}] && v1 ∈ Vectors &&
v2 ∈ Vectors,
TensorExpand[P[t0].((P[t1].v1)*(P[t2].v2))]]


TensorRank::ttimes: Product of nonscalar expressions encountered in (P0+E^(-t2/3) P1).v2.

TensorRank::ttimes: Product of nonscalar expressions encountered in (P0+E^(-t1/3) P1).v2.

TensorRank::ttimes: Product of nonscalar expressions encountered in (P0+E^(-t2/3) P1).v2.

General::stop: Further output of TensorRank::ttimes will be suppressed during this calculation.

P0.((P0.v1 + E^(-t1/3) P1.v1) (P0.v2 + E^(-t2/3) P1.v2)) +
E^(-t0/3) P1.((P0.v1 + E^(-t1/3) P1.v1) (P0.v2 + E^(-t2/3) P1.v2))


Why this happens? How to avoid this problem?

• Have you defined P[t0, 1] somewhere? – bill s Apr 28 '18 at 13:02
• @bills It was a typo, I have corrected the question. – Alexey Popkov Apr 28 '18 at 13:19

As you noted, TensorExpand will not work if there are Hadamard products present. Instead, you can define your own function to do this, using Distribute and defining a function to extract scalars:

myExpand[e_] := e /. h:Dot|Times -> Distribute @* h /. Dot -> scalarExtract @* Dot

scalarExtract[a_Dot] := Times @@ Flatten @ Reap[scalarExtract/@a]
scalarExtract[a_Times] := If[scalarQ[#], Sow[#];1, #]& /@ a
scalarExtract[a_] := a

scalarQ[a_] := TrueQ[TensorRank[a] == 0]


P[t_] := P0 + E^(-t/3) P1

expr = P[t0].((P[t1].v1)*(P[t2].v2));

$Assumptions = (P0|P1) ∈ Matrices[{4,4}] && (v1|v2) ∈ Vectors && (t0|t1|t2) ∈ Complexes; myExpand[expr]  P0.(P0.v1 P0.v2) + E^(-t1/3) P0.(P0.v2 P1.v1) + E^(-t2/3) P0.(P0.v1 P1.v2) + E^(-(t1/3) - t2/3) P0.(P1.v1 P1.v2) + E^(-t0/3) P1.(P0.v1 P0.v2) + E^(-(t0/3) - t1/3) P1.(P0.v2 P1.v1) + E^(-(t0/3) - t2/3) P1.(P0.v1 P1.v2) + E^(-(t0/3) - t1/3 - t2/3) P1.(P1.v1 P1.v2) Let's check that the expressions are equivalent: SeedRandom rules = { P0 -> RandomReal[1, {4,4}], P1 -> RandomReal[1, {4,4}], v1 -> RandomReal[1, 4], v2 -> RandomReal[1, 4], t0 -> RandomReal, t1 -> RandomReal, t2 -> RandomReal }; expr /. rules myExpand[expr] /. rules  {20.4585, 29.4332, 17.0382, 22.5295} {20.4585, 29.4332, 17.0382, 22.5295} The problem is TensorRank cannot find the the rank of the Hadamard product of two symbolic tensors. $Assumptions = (v1 | v2) \[Element] Vectors
TensorRank[v1 v2]


This flags an error.

TensorRank::ttimes: Product of nonscalar expressions encountered in v1 v2.

However, if you are sure about the rank and dimension compatibilities, you can bypass this check by using Inactivate before TensorExpand and Activate it back after the action of TensorExpand:

Assuming[P0 \[Element] Matrices[{4, 4}] &&
P1 \[Element] Matrices[{4, 4}] && v1 \[Element] Vectors &&
v2 \[Element] Vectors,
Inactivate@TensorExpand[P[t0].((P[t1].v1)*(P[t2].v2))]] // Activate
(*P0.((P0.v1 + E^(-t1/3) P1.v1) (P0.v2 + E^(-t2/3) P1.v2)) + E^(-t0/3) P1.((P0.v1 + E^(-t1/3) P1.v1) (P0.v2 + E^(-t2/3) P1.v2))*)

• With your approach the output is the same as in the question: the matrix product isn't expanded. – Alexey Popkov Apr 28 '18 at 15:12