Multi-dimensional outer-product in python
<p>I was doing MNIST dataset and trying to get a outer product of my two vectors <code>w_i(ith class)</code> and <code>a_k(kth sample)</code>.</p>

<p>The <code>w_i</code>, for <code>i = 0...9</code>, has 784 coordinates.</p>

<p>The <code>a_k</code>, for <code>k = 1...n</code>, also has 784 coordinates.</p>

<p>I created two arrays <code>w_ij</code> and <code>a_ij</code> which contain all ten classes and k samples. The shape of <code>w_ij</code> is (10, 784) and <code>a_ij</code> is (n, 784).</p>

<p>I was trying to get a result something like:</p>

<pre><code>[[w_0 dot a_1, w_0 dot a_2, ... , w_0 dot a_n], # (first row)
[w_1 dot a_1, w_1 dot a_2, ..., w_1 dot a_n], # (second row)
...,
[w_9 dot a_1, ..., w_9 dot a_n]] # (nth row)
</code></pre>

<p>So the shape of array should be like <code>(10, n)</code>. I tried to use <code>scipy.outer(w_ij, a_k)</code> or <code>scipy.multiply.outer(w_ij, a_k)</code>. However, it led me to a result whose shape is <code>(7840, 784*n)</code>. Could someone direct me to the right path?</p>

<p>It looks like you want the following:</p>

<pre><code>res = np.einsum('pi,qi-&gt;pq', w, a)
</code></pre>

<p>Which is shorthand for the following in index notation:</p>

<pre><code>res[p,q] = w[p,i]*a[q,i]
</code></pre>

<p>In this notation, the convention is to sum over all indices which do not appear in the output</p>

<hr>

<p>However, note that <code>ij,jk-&gt;ik</code> is just the standard matrix product, and <code>ij-&gt;ji</code> is just the matrix transpose. So we can simplify this as follows</p>

<pre><code>np.einsum('pi,qi-&gt;pq', w, a)   # as before
np.einsum('pi,iq-&gt;pq', w, a.T) # transpose and swapping indices cancel out
np.einsum('ij,jk-&gt;ik', w, a.T) # index names don't matter
w @ a.T                        # wait a sec, this is just matrix multiplication (python 3.5+)
</code></pre>

python arrays numpy multidimensional-array scipy