Add multiple of a matrix without build a new one
<p>Say I have two matrices <code>B</code> and <code>M</code> and I want to execute the following statement:</p>

<pre><code>B += 3*M
</code></pre>

<p>I execute this instruction repeatedly so I don't want to build each time the matrix <code>3*M</code> (<code>3</code> may change, it is just to make cleat that I only do a scalar-matrix product). Is it a numpy-function which makes this computation "in place"?</p>

<p>More precisely, I have a list of scalars <code>as</code> and a list of matrices <code>Ms</code>, I would like to perform the "dot product" (which is not really one since the two operands are of different type) of the two, that is to say:</p>

<pre><code>sum(a*M for a, M in zip(as, Ms))
</code></pre>

<p>The <code>np.dot</code> function does not do what I except...</p>

<p>Another way you could do this, particularly if you favour readability, is to make use of <a href="http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html" rel="nofollow">broadcasting</a>.</p>

<p>So you could make a 3D array from the 1D and 2D arrays and then sum over the appropriate axis:</p>

<pre><code>&gt;&gt;&gt; Ms = np.random.randn(4, 2, 3)   # 4 arrays of size 2x3
&gt;&gt;&gt; As = np.random.randn(4)
&gt;&gt;&gt; np.sum(As[:, np.newaxis, np.newaxis] * Ms)
array([[-1.40199248, -0.40337845, -0.69986566],
       [ 3.52724279,  0.19547118,  2.1485559 ]])
&gt;&gt;&gt; sum(a*M for a, M in zip(As, Ms))
array([[-1.40199248, -0.40337845, -0.69986566],
       [ 3.52724279,  0.19547118,  2.1485559 ]])
</code></pre>

<p>However, it's worth noting that <code>np.einsum</code> and <code>np.tensordot</code> are usually much more efficient:</p>

<pre><code>&gt;&gt;&gt; %timeit np.sum(As[:, np.newaxis, np.newaxis] * Ms, axis=0)
The slowest run took 7.38 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 3: 8.58 Âµs per loop
&gt;&gt;&gt; %timeit np.einsum('i,ijk-&gt;jk', As, Ms)
The slowest run took 19.16 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 3: 2.44 Âµs per loop
</code></pre>

<p>And this is also true for larger numbers:</p>

<pre><code>&gt;&gt;&gt; Ms = np.random.randn(100, 200, 300)
&gt;&gt;&gt; As = np.random.randn(100)
&gt;&gt;&gt; %timeit np.einsum('i,ijk-&gt;jk', As, Ms)
100 loops, best of 3: 5.03 ms per loop
&gt;&gt;&gt; %timeit np.sum(As[:, np.newaxis, np.newaxis] * Ms, axis=0)
100 loops, best of 3: 14.8 ms per loop
&gt;&gt;&gt; %timeit np.tensordot(As,Ms,axes=(0,0))
100 loops, best of 3: 2.79 ms per loop
</code></pre>

<p>So <code>np.tensordot</code> works best in this case.</p>

<p>The only good reason to use <code>np.sum</code> and broadcasting is to make the code a <em>little</em> more readable (helps when you have small matrices).</p>

python numpy matrix