53
$\begingroup$

This is a really newbie question, but it has me confused. Why does this code work without // MatrixForm and doesn't work with // MatrixForm?

cov = {{0.02, -0.01}, {-0.01, 0.04}} // MatrixForm
W = {w1, w2}; FindMinimum[ W.cov.W, W]

The error is:

The function value ... is not a real number

Is MatrixForm supposed to be typesetting feature or it has other impact?


A similar problem appears here:

a = {{1, 0, 1, 0}, {2, 1, 1, 1}, {1, 2, 1, 0}, {0, 1, 1, 1}};
inv = Inverse[a];
b = MatrixForm@{{0}, {0}, {0}, {1}};
soln = inv.b

enter image description here

$\endgroup$
5
  • 1
    $\begingroup$ From the MoreInformation section of MatrixForm in the docs: MatrixForm acts as a "wrapper", which affects printing, but not evaluation. $\endgroup$
    – kglr
    Mar 16, 2012 at 19:54
  • 1
    $\begingroup$ @kguler and not all functions actually respect it, such as MatrixExp. $\endgroup$
    – rcollyer
    Mar 16, 2012 at 19:57
  • 8
    $\begingroup$ I also discuss this here $\endgroup$ Mar 16, 2012 at 19:57
  • $\begingroup$ You may prefer to have your output rendered as TraditionalForm. You can do this easily from the preferences menu, Evaluation tab. $\endgroup$ Mar 16, 2012 at 22:43
  • 1
    $\begingroup$ See also: (44189) $\endgroup$
    – Mr.Wizard
    Feb 28, 2015 at 18:43

4 Answers 4

58
$\begingroup$

MatrixForm is a wrapper that pretty-prints your matrices. When you do the following:

cov = {{0.02, -0.01}, {-0.01, 0.04}} // MatrixForm

you're assigning the prettified matrix to cov (i.e., wrapped inside a MatrixForm). This is not accepted as an input by most functions (perhaps all) that take matrix arguments. What you should be doing to actually assign the raw matrix to cov, yet get a pretty print in the output, is the following:

(cov = {{0.02, -0.01}, {-0.01, 0.04}}) // MatrixForm

You can also read more about why this happens due to the different precedences here in Leonid's book.


You can also avoid having to use MatrixForm every time by setting the default display for matrix outputs to be typeset accordingly. For this, you set the $PrePrint variable in your init.m file as:

$PrePrint = Replace[# , mat_?MatrixQ :> MatrixForm[mat]] &

You can also find this in Szabolcs's mathematica tricks. To reset the value of $PrePrint, simply unset it with $PrePrint=.

$\endgroup$
3
  • 1
    $\begingroup$ You could also set the format type for output cells to traditional form. $\endgroup$ Mar 16, 2012 at 22:42
  • $\begingroup$ I am guilty here because wrapping matrices by MatrixForm when they're inside object such as Image or Graph will break the formatting of that object. $\endgroup$
    – Szabolcs
    Mar 17, 2012 at 8:00
  • 4
    $\begingroup$ @Szabolcs the link to your "mathematica tricks" page is now broken $\endgroup$
    – glS
    Nov 2, 2016 at 20:23
25
$\begingroup$

While the question has been more than answered there are still some things that seem to me worth adding. The first is that, in my opinion, MatrixForm is "essentially" obsolete. If you wish your matrices always look like matrices (in the output) you can set the format type of output cells to TraditionalForm (use the Appearance tab in the Preferences menu). In fact, you can also set the format type of your input cells to TraditionalForm, although you have to be a little careful if you do that (doing that is not recommended by WRI but it has some well known supporters...).

Alternatively you can use the ConvertTo menu to convert any matrices to TraditionalForm while keeping other cells or expressions in StandardForm (if you prefer that). The keyboard shortcut for this is Ctrl-Shift-T. Finally, if you would like all your matrices always to appear in MatrixForm and avoid these evaluation problems, you can evaluate at the beginning of your Mathematica session

$Post = If[MatrixQ[#], MatrixForm[#], #] & 

or you can put it into an init file and have it evaluate automatically. (Of course you can use TraditionalForm in place of MatrixForm).

Coming back to the issue of TraditionalForm vs MatrixForm for matrices: the only problem I can see with using the former is that it looks "too nice" so that if the rest of your output is in StandardForm the style of your matrices will not match the rest of your output. But other than that I can't think of any use for MatrixForm.

$\endgroup$
1
  • $\begingroup$ Thanks. This was useful information to know. So exactly, how does this $Post = If[MatrixQ[#], MatrixForm[#], #] & works internally or in general? Because it let's the kernel know of some preliminary settings before you actually start creating List to do computations on, correct. And Mathematica will know what to do with the result (in terms of how you want it to be outputted to the screen). $\endgroup$
    – night owl
    Mar 25, 2012 at 23:52
16
$\begingroup$

MatrixForm is a function to prettyprint matrices and cannot be used in computations. Just leave the MatrixForm away and you're fine:

a = {{1, 0, 1, 0}, {2, 1, 1, 1}, {1, 2, 1, 0}, {0, 1, 1, 1}};
inv = Inverse[a];
b = {{0}, {0}, {0}, {1}};
soln = inv.b
{{-(1/2)}, {0}, {1/2}, {1/2}}

If you want that result displayed (!) in a nice readable way, you can of course use MatrixForm again:

soln // MatrixForm

$\left( \begin{array}{c} -\frac{1}{2} \\ 0 \\ \frac{1}{2} \\ \frac{1}{2} \\ \end{array} \right)$

$\endgroup$
2
  • $\begingroup$ Thanks. Was always wondering why it always did that. I just turned to a calculator if it was a big complicated system. But now I wanted to figure out why so I can do it in mathematica. $\endgroup$
    – night owl
    Mar 24, 2012 at 4:32
  • $\begingroup$ Of course MatrixForm (like all formatting functions) is special in that it is stripped away from the output stored in Out if it is applied top-level (but only in that case). This may cause the wrong impression that it has no effect on calculation, but only on display. $\endgroup$
    – celtschk
    Mar 24, 2012 at 8:13
16
$\begingroup$

David's answer is correct and the one you need to solve your specific problem. I thought nonetheless that it is worth providing some additional information that might help explain how to diagnose similar issues.

Matrix/tensor operations like Dot and Inverse are designed to work with lists, that is, expressions with a Head of List. It also works with SparseArray objects. From the documentation:

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

You can check whether your expressions have compatible Heads using FullForm. It is common for people to use postfix (//) notation to check this. As you can see, in your version of the code, a has head List while b has head MatrixForm. So they can't combine.

a//FullForm

List[List[1,0,1,0],List[2,1,1,1],List[1,2,1,0],List[0,1,1,1]]

b//FullForm

MatrixForm[List[List[0],List[0],List[0],List[1]]]

If you discover you have erroneously created a matrix wrapped in MatrixForm, you can change it back to a list using First.

FullForm[First[b]]

List[List[0],List[0],List[0],List[1]]

As an aside, I don't see any point assigning the variable inv to represent the Inverse of a. Unless your real problem uses $a'$ more than once (especially if it is expensive to calculate), you can just as easily do:

Inverse[a].(First@b)

Note that I have mixed using of @ and [] style notation for pedagogical reasons.

$\endgroup$
1
  • 1
    $\begingroup$ Thank You! This was very pleasing to read. I like to read something and it physically makes since (in terms of how the kernel internally deciphers computations) and learn different ways to implement the same task, while also making it robust and more efficient without defining extra variables unnecessarily. +1 :) $\endgroup$
    – night owl
    Mar 25, 2012 at 23:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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