Итак, мы хотим приблизить матрицу A с m строками и n столбцами с произведением двух матриц P и Q, которые имеют размерность mxk и kxn соответственно. Вот реализация мультипликативного правила обновления из-за Ли в C ++ с использованием библиотеки Eigen.
void multiplicative_update()
{
Q = Q.cwiseProduct((P.transpose()*matrix).cwiseQuotient(P.transpose()*P*Q));
P = P.cwiseProduct((matrix*Q.transpose()).cwiseQuotient(P*Q*Q.transpose()));
}
, где P
, Q
и matrix
(матрица = A) являются глобальными переменными в class mat_fac
. Таким образом, я тренирую их, используя следующий метод,
void train_2(){
double error_trial = 0;
for (int count = 0;count < num_iterations; count ++)
{
multiplicative_update();
error_trial = (matrix-P*Q).squaredNorm();
if (error_trial < 0.001)
{
break;
}
}
}
, где num_iterations
также является глобальной переменной в class mat_fac
.
Проблема в том, что я работаю с очень большими матрицами и, в частности, у меня нет доступа ко всей матрице. Учитывая тройку (i, j, matrix [i] [j]), у меня есть доступ к вектору строки P [i] [:] и вектору столбца Q [:] [j]. Поэтому моя цель - написать переписать правило мультипликативного обновления таким образом, чтобы я обновлял эти два вектора каждый раз, когда вижу ненулевое значение матрицы.
В коде я хочу что-то вроде этого:
void multiplicative_update(int i, int j, double mat_value)
{
Eigen::MatrixXd q_vect = get_vector(1, j); // get_vector returns Q[:][j] as a column vector
Eigen::MatrixXd p_vect = get_vector(0, i); // get_vector returns P[i][:] as a column vector
// Somehow compute coeff_AQ_t, coeff_PQQ_t, coeff_P_tA and coeff_P_tA.
for(int i = 0; i< k; i++):
p_vect[i] = p_vect[i]* (coeff_AQ_t)/(coeff_PQQ_t)
q_vect[i] = q_vect[i]* (coeff_P_tA)/(coeff_P_tA)
}
Таким образом, проблема сводится к вычислению требуемых коэффициентов с учетом двух векторов. Это возможно сделать? Если нет, какие дополнительные данные мне нужны для мультипликативного обновления, чтобы работать таким образом?