2016-09-30 4 views
1

Предположат, имеющие два вектора с м х 6, п х 6Python вычислить конкретное скалярное произведение на векторах

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

с использованием np.inner работает как ожидались, и выходы

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

с каждым элементом является скалярной продукт каждой комбинации. Теперь я хочу вычислить специальный внутренний продукт (а именно Plucker). Прямо сейчас с использованием

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 

с a, b нарезанный петлей для петли. Это слишком медленно. Любые планы по векторизации терпят неудачу. В основном распространены ошибки из-за неправильных фигур. Не могу заставить np.vectorize работать. Может быть, здесь кто-то может помочь?

+0

Так, 'a' в' pluckerSide' является каждая строка из исходного входа массив 'a'? Аналогично для 'b'? Не могли бы вы поделиться кодом цикла, который генерирует 'a' и' b', которые вы загружаете в 'pluckerSide (a, b)'? – Divakar

+0

a, b - Линии в пространстве plucker, 6-пространство, представляющее геометрические линии. поэтому каждая строка в a или b является строкой в ​​3d. pluckerside вычисляет внутреннее произведение такой 2 строки, давая информацию о том, с какой стороны они проходят друг друга в пространстве (или если они пересекаются, его == 0) – Max

ответ

3

Как представляется, индексирование основано на некоторых случайных индексах для парного умножения и суммирования на этих двух входных массивах с функцией pluckerSide. Итак, я бы перечислял эти индексы, индексировал их в массивы и, наконец, использовал matrix-multiplication с np.dot для выполнения суммирования.

Таким образом, один подход был бы, как это -

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]) 

Если вы делаете это в цикле по всем строкам a и b и, таким образом, генерируя выходной массив формы (m,n), мы можем векторизации, что, как так -

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

Чтобы сделать вещи немного проще, мы можем переставить a_idx таким образом, что она становится range(6) и вновь организовать b_idx с этим шаблоном. Итак, мы имеем:

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

Таким образом, мы можем пропустить индексирование в a и решение было бы просто -

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

оба решения работают отлично. Спасибо. прямо сейчас im оптимизация остальной части кода и, возможно, «chunk» его, так как этот способ использует больше памяти (смотря на m, n в порядке 10e4 float32 - так легко пересечь несколько концертов) – Max

+0

@Max Да chunk it как показано в предыдущем посте - http://stackoverflow.com/a/39751039/3293881 – Divakar

Смежные вопросы