Рассчитать сумму компонентов СВД - PullRequest
1 голос
/ 23 мая 2019

Теперь мы знаем, что A_(m x n) = U_(m x k) * S_(k x k) * V_(k x n)^T = u_(1) * s_1 * v_(1) + u_(2) * s_2 * v_(2) + ...,, где u_(i) и v(i) - i-тые столбцы U и V, s_i - i-й диагональный элемент S. Я пытаюсь получить массив a без использования циклов, где a[i] = u_(1) * s_1 * v_(1) + u_(2) * s_2 * v_(2) + ... + u_(i) * s_i * v_(i). Что мне делать дальше?

from numpy.linalg import svd

U, S, VT = svd(A, full_matrices=False)
A_1 = U[:, 0:1] * S[0] @ VT[0:1]

1 Ответ

1 голос
/ 23 мая 2019

Один простой способ будет einsum:

A_ = np.einsum("ij,j,jk->jik",U[:,:len(VT)],S,VT[:len(U)]).cumsum(0)

Если, как вы правильно сделали, svd был вызван с full_matrices=False, это упрощается до

A_ = np.einsum("ij,j,jk->jik",U,S,VT).cumsum(0)

Ваш A_1 будет соответствовать A_[0] и т. Д., A_[-1] является (с точностью до округления) исходным массивом A.

П.С .: То же самое без einsum:

A_ = ((U*S).T[:,:,None]*VT[:,None,:]).cumsum(0)
...