# Do not expand matrices in Mathematica calculation

Here is an example of a problem I'm having. Consider that I have defined:

omega={{p[t]},{q[t]},{r[t]}}

x={{a},{b},{c}}

R={{1,2,3},{4,5,6},{7,8,d}}


What I would like to do is the calculation:

h=(R.omega+x).x


My problem: the output I would like to get is:

h=R.omega.x+x.x


However, mathematica by default will expand everything and just give me the resulting scalar number - I do not want this. Using //HoldForm will give me just:

h=(R.omega+x).x


Which does not help either. So how do I get the output h=R.omega.x+x.x where the expression is expanded but the variables are retained, i.e. not expanded themselves?

Thanks a lot! I appreciate it.

• If you only want the expanded expression, why do you need to Set your variables to begin with? Simply do h = Distribute[(R.omega + x).x] before the three lines where you Set them to be matrices... Then you can of course use @march's method to replace them a posteriori if you want. Commented Jul 20, 2015 at 20:03
• @MariusLadegårdMeyer because eventually I want to switch between the developed version (where the R, omega and x get substituted with what they really are) and the undeveloped version. What you suggest is a stupid constraint to put on a user, there must be a way. Commented Jul 20, 2015 at 20:37
• Would you like to accept one of the answers below (even if it's your own)? That way, we can remove it from the unanswered list. Commented Aug 20, 2015 at 3:03
• @march Done, thanks for reminding me. Commented Aug 20, 2015 at 16:03

There will be more clever answers from people who better understand Mathematica's order of evaluation and how to use Hold and such, and so I can't answer your question in exactly the way that you've phrased it, but here's how I go about doing these types of things.

First, instead of declaring the values of x, omega, and R as you've done, make a list of rules:

Clear[x, omega, R]
rules = {omega -> {p[t], q[t], r[t]
, x -> {a, b, c}
, R -> {{1, 2, 3}, {4, 5, 6}, {7, 8, d}}
}


Then, your expression (R.omega+x).x evaluates to itself, because, as shown in the documentation,

When its arguments are not lists or sparse arrays, Dot remains unevaluated.

Therefore, we have to tell Mathematica to distribute the Dot through the parantheses:

h = Distribute[(R.omega+x).x]


results in

R.omega.x + x.x


Now, to replace these quantities with your defined quantities above, merely do

h /. rules


resulting in

a^2 + b^2 + c^2
+ a (p[t] + 2 q[t] + 3 r[t])
+ b (4 p[t] + 5 q[t] + 6 r[t])
+ c (7 p[t] + 8 q[t] + d r[t])


### Aside on notation

Typically, you want to define both "row vectors" and "column vectors" the same in mathematica, i.e.

rowVector = {a, b, c}
columnVector = {d, e, f}


The Dot operation will understand what you want:

rowVector.columVector


results in

a*b + b*e + d*f


Of course, this is also the result of

columnVector.rowVector


so if you're interested in doing other operations, you have to use something other than Dot.

You can use Inactivate with TraditionalForm.

Inactivate[h = (R.omega + x).x] // TraditionalForm


Inactivate prevents the operations from executing and TraditionalForm gives the formatted output.

Hope this helps.

I like march's idea of automation but I think at the moment his updated code is not working. Perhaps this will serve the purpose:

SetAttributes[heldDistribute, HoldFirst]
heldDistribute[expr_] :=
Unevaluated[expr] /.
Cases[Unevaluated[expr], x_Symbol :> (HoldPattern[x] :> Defer[x]), {-1},


Now with the question definitions in place:

heldDistribute[(R.omega + x).x]

x.x + R.omega.x


Thank you for your replies, they will be useful in the future. I found the solution to my specific problem however. One can use:

Distribute[(HoldForm[R].HoldForm[omega]+HoldForm[x]).HoldForm[x]]


Albeit cumbersome, it does the trick. To avoid it one can use @march or @MariusLadegårdMeyer solutions! Thank you.

Here's a completely different take (from my other answer, which I think justifies a separate answer) that somewhat automates the idea of using HoldForm on the variables. It works as long as you name the variables consistently. It's still not perfect, since, you need to make the List of replacements, but once that's done, you don't need to do the cumbersome thing of adding HoldForm to each Symbol in each expression that you create.

replacements = {HoldPattern[R] -> HoldForm[R], HoldPattern[x] -> HoldForm[x], HoldPattern[omega] -> HoldForm[omega]}
SetAttributes[heldDistribute, HoldFirst]
heldDistribute[expr_] := Distribute@ReleaseHold[Hold[expr] /. replacements]


Then

heldDistribute[(R.omega + x).x]


results in

x.x + R.omega.x

• Your updated version does not appear to work properly, and I cannot see how it would without additional measures of expression holding. I think you should check it again. Commented Jan 13, 2016 at 22:56
• @Mr.Wizard. You're right. I tested it with the symbols undefined. I will roll back the changes until I have a working version (although since you have a version, I am unlikely to work on this much; we'll see). Thanks for the heads-up. Commented Jan 13, 2016 at 23:41