# Output to preserve dot product

I am fairly new to Mathematica and I am faced with a problem. I tried to search for the solution but it seems that I don't know how to formulate the short search request.

I need to perform a matrix product of

g = -I*Pi {{I1[x], 0}, {0, I2[x]}}.{{1 + G[x].Gt[x], 2*G[x]}, {-2*G[x], -1 - Gt[x].G[x]}}


However, I know that all the entries are matrices themselves, so I would like the dot product to be preserved in the output, i.e. to get something like

{{-I \[Pi] (1 + G[x].Gt[x]).I1[x], -2 I \[Pi] I1[x].G[x]},
{2 I \[Pi] I2[x].G[x], -I \[Pi] (-1 - Gt[x].G[x]).I2[x]}}


as opposed to

{{-I \[Pi] (1 + G[x].Gt[x]) I1[x], -2 I \[Pi] I1[x] G[x]},
{2 I \[Pi] I2[x] G[x], -I \[Pi] (-1 - Gt[x].G[x]) I2[x]}}


Is there any way to do this in Mathematica? N.B.: I don't want to specify the entire form of G[x],Gt[x] and other matrices at this stage.

• Eugene, it is best if you do not Accept an answer so quickly; I usually wait 24 hours to give everyone a chance to reply. You will often get more and sometimes better answers this way. Jun 18, 2013 at 15:29
• I added simplifying-expressions as this falls into a general and notoriously hard category with a lot of pitfalls. For the same reason, +1. Jun 18, 2013 at 15:38
• – Jens
Jun 18, 2013 at 17:21

Use Inner instead of Dot per Silvia, but it is not the whole story. In more complex expressions, though, there will be some simplification and you are likely to end up with terms like

0.(1 + G[x].Gt[x]) + (-I π I2[x]).(-2 G[x])


where the leading term is nonsensical. But, Dot does not know how to handle scalars. You could use Distribute, but it may cause more problems than it is worth:

Distribute[(-I π I2[x]).(-2 G[x]), Times, Dot]
(*
(-I).(-2) (-I).G[x] π.(-2)π.G[x] I2[x].(-2) I2[x].G[x]
*)


which is not all that pleasant to simplify. So, I'd suggest using the following

Inner[Dot, -I π {{I1[x], 0}, {0, I2[x]}},
{{1 + G[x].Gt[x], 2 G[x]}, {-2 G[x], -1 - Gt[x].G[x]}}] //.
{
Dot[a_?NumericQ, q_] | Dot[q_, a_?NumericQ] :> a q,
Dot[(a___?NumericQ) q_, p_] :> a q.p,
Dot[ q_, (a___?NumericQ) p_] :> a q.p,
Dot[(a___?NumericQ) q_, b___?NumericQ p_] :> a b q.p}
(*
{{-I π I1[x].(1 + G[x].Gt[x]), -2 I π I1[x].G[x]},
{2 I π I2[x].G[x], -I π I2[x].(-1 - Gt[x].G[x])}}
*)


which is most of the way towards where you want to go. The term in the lower right still poses problems in extracting the extra minus sign, but it may not be worth trying to add a rule to accommodate it.

• Yeah, this is great! Jun 18, 2013 at 15:31
• +1 this is how I'll do it. Though I would prefer define a myDot function which contains all the rules. Jun 18, 2013 at 15:32
• @Silvia absolutely reasonable. Self-contained code is a good thing. Jun 18, 2013 at 15:34
• Generalized the Dot[0, _] rule to any number, so it will now catch the case: Dot[5, q]. Jun 18, 2013 at 17:10

What you're looking for is Inner with Dot playing the role of multiplication:

Inner[Dot, {{a, b}, {c, d}}, {{x, y}, {w, z}}]


{{a.x + b.w, a.y + b.z}, {c.x + d.w, c.y + d.z}}

• Amazing! Thank you very much! Jun 18, 2013 at 15:20
• @EugeneB hold up, there is more to the story. Give me a second to post my answer. Jun 18, 2013 at 15:20
• @EugeneB You're welcome. But you might want to wait for some more time, in cases others will post better answers. Jun 18, 2013 at 15:23
• @rcollyer I'm looking forward to your more story. :) Jun 18, 2013 at 15:24
• @EugeneB my answer is up. Jun 18, 2013 at 15:29

You could define it as a function and defer the computations.

g[I1_, I2_, G_, Gt_] := -I*Pi ArrayFlatten[{{I1, 0}, {0, I2}}].ArrayFlatten[{{1 + G.Gt, 2 G}, {-2 G, -1 - Gt.G}}]


To get explicit results you can then later use g[I1[x], I2[x], G[x], Gt[x]].