Последовательное наложение точечного произведения на кусочки трехмерного массива - PullRequest
0 голосов
/ 12 сентября 2018

Сообщество Hi Stack Overflow,

У меня есть массив массивов 3D Rp формы 4x4x701, где каждый из 701 срезов 4x4 представляет определенное количество в другой момент времени. Я пытаюсь эффективно применить матрицу вращения Гивенса Q и ее эрмитово транспонирование QH к каждому из 701 срезов, и в настоящее время я делаю это итеративно, вот так:

for idx in np.arange(Rp.shape[-1]):
    Rp[[j,k],:,idx] = np.dot(Q, Rp[[j,k],:,idx])
    Rp[:,[j,k],idx] = np.dot(Rp[:,[j,k],idx], QH)

но должен быть способ сделать это НЕ итеративно (для ускорения). Я понимаю, что могу просто использовать np.dot для первого случая, но это не сработает для второго без некоторой транспозиции, которая, похоже, замедлит процесс.

Любые идеи будут с благодарностью!

1 Ответ

0 голосов
/ 12 сентября 2018

Грубый тест на фигуры;значения действительно должны быть более диагностическими:

In [46]: Q = np.eye(4); QH = np.conj(Q)
In [47]: R = np.ones((10,4,4))

In [48]: (Q @ R @ QH).shape
Out[48]: (10, 4, 4)

In [49]: np.einsum('ij,kjl,lm->kil',Q,R,QH).shape
Out[49]: (10, 4, 4)

Если большое измерение является последним:

In [50]: Rp = R.transpose(1,2,0)
In [51]: Rp.shape
Out[51]: (4, 4, 10)

In [53]: np.einsum('ij,jlk,lm->ilk',Q,Rp,QH).shape
Out[53]: (4, 4, 10)

In [55]: (Q @ Rp.transpose(2,1,0) @ QH).transpose(1,2,0).shape
Out[55]: (4, 4, 10)

Мы могли бы также написать это с помощью tensordot.

In [58]: np.tensordot(QH,np.tensordot(Q,Rp,(1,1)),(0,1)).shape
Out[58]: (4, 4, 10)
...