Max
Max

Reputation: 357

Python compute a specific inner product on vectors

Assume having two vectors with m x 6, n x 6

import numpy as np
a = np.random.random(m,6)
b = np.random.random(n,6)

using np.inner works as expected and yields

np.inner(a,b).shape
(m,n)

with every element being the scalar product of each combination. I now want to compute a special inner product (namely Plucker). Right now im using

def pluckerSide(a,b):
    a0,a1,a2,a3,a4,a5 = a
    b0,b1,b2,b3,b4,b5 = b
    return a0*b4+a1*b5+a2*b3+a4*b0+a5*b1+a3*b2

with a,b sliced by a for loop. Which is way too slow. Any plans on vectorizing fail. Mostly broadcast errors due to wrong shapes. Cant get np.vectorize to work either. Maybe someone can help here?

Upvotes: 1

Views: 1003

Answers (1)

Divakar
Divakar

Reputation: 221684

There seems to be an indexing based on some random indices for pairwise multiplication and summing on those two input arrays with function pluckerSide. So, I would list out those indices, index into the arrays with those and finally use matrix-multiplication with np.dot to perform the sum-reduction.

Thus, one approach would be like this -

a_idx = np.array([0,1,2,4,5,3])
b_idx = np.array([4,5,3,0,1,2])
out = a[a_idx].dot(b[b_idx])

If you are doing this in a loop across all rows of a and b and thus generating an output array of shape (m,n), we can vectorize that, like so -

out_all = a[:,a_idx].dot(b[:,b_idx].T)

To make things a bit easier, we can re-arrange a_idx such that it becomes range(6) and re-arrange b_idx with that pattern. So, we would have :

a_idx = np.array([0,1,2,3,4,5])
b_idx = np.array([4,5,3,2,0,1])

Thus, we can skip indexing into a and the solution would be simply -

a.dot(b[:,b_idx].T)

Upvotes: 3

Related Questions