12

Let X be a M x N matrix. Denote xi the i-th column of X. I want to create a 3 dimensional N x M x M array consisting of M x M matrices xi.dot(xi.T).

How can I do it most elegantly with numpy? Is it possible to do this using only matrix operations, without loops?

5
  • Sounds like a job for np.einsum. Commented Jan 4, 2017 at 17:17
  • It seems as if the (rows,cols) have been mixed up here...To use concrete numbers, assume we begin with (Mrows, Ncols) = (2,3). The OP is using column vector operations Ni*Ni.T. Each column is of length Mrows=2, so the product yields a (2,2) matrix - that is, (Mrows,Mrows). Doing that for each column and stacking the result in the third dimension should result in an (M x M x N) matrix. Commented Jan 4, 2017 at 19:08
  • @MattP OP is probably stacking/storing along the first axis : for i in range(N): out[i] = X[:,i,None].dot(X[None,:,i]). Commented Jan 4, 2017 at 20:16
  • 1
    @Divakar That's some pretty nice broadcasting/indexing there! I learned something new here today. My own (less fancy, more loopy, and likely less performant) solution to this question that gives the same result would have been: Result = np.dstack( X[:,i].reshape((nrows,1)) * X[:,i] for i in range(ncols) ). Commented Jan 4, 2017 at 20:26
  • @MattP An easier version would be : xi = X[:,i,None] and then using OP's code : xi.dot(xi.T). Commented Jan 4, 2017 at 20:29

1 Answer 1

17

One approach with broadcasting -

X.T[:,:,None]*X.T[:,None]

Another with broadcasting and swapping axes afterwards -

(X[:,None,:]*X).swapaxes(0,2)

Another with broadcasting and a multi-dimensional transpose afterwards -

(X[:,None,:]*X).T

Another approach with np.einsum, which might be more intuitive thinking in terms of the iterators involved if you are translating from a loopy code -

np.einsum('ij,kj->jik',X,X)

Basic idea in all of these approaches is that we spread out the last axis for elementwise multiplication against each other keeping the first axis aligned. We achieve this process of putting against each other by extending X to two 3D array versions.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.