<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<style type="text/css" style="display:none;"> P {margin-top:0;margin-bottom:0;} </style>
</head>
<body dir="ltr">
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Thanks a lot Matti. It makes a lot more sense now.</div>
<hr style="display:inline-block;width:98%" tabindex="-1">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" style="font-size:11pt" color="#000000"><b>From:</b> NumPy-Discussion <numpy-discussion-bounces+jeffsaremi=hotmail.com@python.org> on behalf of Matti Picus <matti.picus@gmail.com><br>
<b>Sent:</b> Monday, July 9, 2018 10:54 AM<br>
<b>To:</b> numpy-discussion@python.org<br>
<b>Subject:</b> Re: [Numpy-discussion] Looking for description/insight/documentation on matmul</font>
<div> </div>
</div>
<div class="BodyFragment"><font size="2"><span style="font-size:11pt;">
<div class="PlainText">On 09/07/18 09:48, jeff saremi wrote:<br>
> Is there any resource available or anyone who's able to describe <br>
> matmul operation of matrices when n > 2?<br>
><br>
> The only description i can find is: "If either argument is N-D, N > 2, <br>
> it is treated as a stack of matrices residing in the last two indexes <br>
> and broadcast accordingly." which is very cryptic to me.<br>
> Could someone break this down please?<br>
> when a [2 3 5 6] is multiplied by a [7 8 9] what are the resulting <br>
> dimensions? is there one answer to that? Is it deterministic?<br>
> What does "residing in the last two indices" mean? What is broadcast <br>
> and where?<br>
> thanks<br>
> jeff<br>
><br>
<br>
You could do<br>
<br>
np.matmul(np.ones((2, 3, 4, 5, 6)), np.ones((2, 3, 4, 6, 7))).shape<br>
<br>
which yields (2, 3, 4, 5, 7).<br>
<br>
When ndim >= 2 in both operands, matmul uses the last two dimensions as <br>
(..., n, m) @ (...., m, p) -> (..., n, p). Note the repeating "m", so <br>
your example would not work: n1=5, m1=6 in the first operand and m2=8, <br>
p2=9 in the second so m1 != m2.<br>
<br>
The "broadcast" refers only to the "..." dimensions, if in either of the <br>
operands you replace the 2 or 3 or 4 with 1 then that operand will <br>
broadcast (repeat itself) across that dimension to fit the other <br>
operand. Also if one of the three first dimensions is missing in one of <br>
the operands it will broadcast.<br>
<br>
When ndim < 2 for one of the operands only, it will be interpreted as <br>
"m", and the other dimension "n" or "p" will not appear on the output, <br>
so the signature is (..., n, m),(m) -> (..., n) or (m),(..., m, p)->(..., p)<br>
<br>
When ndim < 2 for both of the operands, it is the same as  a dot product <br>
and will produce a scalar.<br>
<br>
You didn't ask, but I will complete the picture: np.dot is different for <br>
the case of n>=2. The result will extend (combine? broadcast across?) <br>
both sets of ... dimensions, so<br>
<br>
np.dot(np.ones((2,3,4,5,6)), np.ones((8, 9, 6, 7))).shape<br>
<br>
which yields (2, 6, 4, 5, 8, 9, 7). The (2, 3, 4) dimensions are <br>
followed by (8, 9)<br>
<br>
Matti<br>
_______________________________________________<br>
NumPy-Discussion mailing list<br>
NumPy-Discussion@python.org<br>
<a href="https://mail.python.org/mailman/listinfo/numpy-discussion">https://mail.python.org/mailman/listinfo/numpy-discussion</a><br>
</div>
</span></font></div>
</body>
</html>