Recently I was surprised when I encountered the following quote from the Mathematica docs:
The Wolfram Language represents vectors as lists, and never needs to distinguish between row and column cases.
(http://reference.wolfram.com/language/guide/OperationsOnVectors.html)
I find this statement somewhat misleading and here is why.
The usual matrix multiplication clearly distinguishes between row and column vectors, because:
$
\left(
\begin{array}{cc}
1 & 2
\end{array}
\right)
\cdot
\left(
\begin{array}{c}
1 \\
3 \\
\end{array}
\right)
= (7), \qquad $
but
$
\qquad
\left(
\begin{array}{c}
1 \\
2 \\
\end{array}
\right)
\cdot
\left(
\begin{array}{cc}
1 & 3
\end{array}
\right) =
\left(
\begin{array}{cc}
1 & 3 \\
2 & 6
\end{array}
\right)
$
To write a general matrix multiplication in Mathematica we use Dot
:
b.c
If b
and c
are vectors we may need to specify which vector is column and which is row. I.e. depending on dimensions of b
and c
we should write either:
b.c /. b -> {{1}, {2}} /. c -> {{1, 3}}
{{1, 3}, {2, 6}}
or
b.c /. b -> {{1, 2}} /. c -> {{1}, {3}}
{{7}}
If we just use lists we will always get a scalar product
b.c /. b -> {1, 2} /. c -> {1, 3}
7
In your example we can explicitly define row and column vectors
to avoid the problems:
a.b.c /. b -> {{1},{2}} /. c -> {{1, 3}} /. a -> IdentityMatrix[2]
{{1, 3}, {2, 6}}
a.b.c /. b -> {{1}, {2}} /. a -> IdentityMatrix[2] /. c -> {{1, 3}}
{{1, 3}, {2, 6}}
One can argue that Outer
can be used instead. For this simple case I agree, but in other cases it is not always clear where matrix multiplication reduces to an outer product. Thus, for problems with large number of matrix multiplications it may be better to define vectors as $1 \times n$ and $n \times 1$ matrices to avoid any ambiguities.
a=IdentityMatrix[2];b={1,2};c={3,4};
and now comparea.(b.c)
vs.(a.b).c
This just makes it easier to see. No need for all the With code :) $\endgroup$ – Nasser Jun 15 '17 at 22:52Dot
is inconsistent. As an inner product defined in details section of documentation it's not associative when rank of "middle" tensor is lower than 2. I'd even go as far as calling this a bug.Dot
might be better withoutFlat
attribute and with consistent left-associative (or right-associative) evaluation in case of more than 2 arguments involving explicit rank 1 tensors. But given thatDot
worked this way for a long time, I guess WRI will call it a feature not a bug. $\endgroup$ – jkuczm Jun 18 '17 at 16:01a = {{0, 1}, {2, 3}}; v = {4, 5}; b = {{6, 7}, {8, 9}}; a.(v.b) (* {73, 347} *)
vsClearAll[a, b, v]; a.(v.b) /. {a -> {{0, 1}, {2, 3}}, v -> {4, 5}, b -> {{6, 7}, {8, 9}}} (* {214, 242} *)
, they both give 2-element vectors. $\endgroup$ – jkuczm Jun 21 '17 at 10:09