1
$\begingroup$

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[4], 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[4] && 
  v2 ∈ Vectors[4], 
 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?

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

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]

For your example:

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[4] && (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[0]
rules = {
    P0 -> RandomReal[1, {4,4}],
    P1 -> RandomReal[1, {4,4}],
    v1 -> RandomReal[1, 4],
    v2 -> RandomReal[1, 4],
    t0 -> RandomReal[1],
    t1 -> RandomReal[1],
    t2 -> RandomReal[1]
};

expr /. rules
myExpand[expr] /. rules

{20.4585, 29.4332, 17.0382, 22.5295}

{20.4585, 29.4332, 17.0382, 22.5295}

$\endgroup$
0
$\begingroup$

The problem is TensorRank cannot find the the rank of the Hadamard product of two symbolic tensors.

$Assumptions = (v1 | v2) \[Element] Vectors[4]
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[4] && 
   v2 \[Element] Vectors[4], 
  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))*)
$\endgroup$
  • $\begingroup$ With your approach the output is the same as in the question: the matrix product isn't expanded. $\endgroup$ – Alexey Popkov Apr 28 '18 at 15:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.