Я пытаюсь создать функцию, которая может вычислять серию взвешенных продуктов
где W - диагональная матрица. Существует много W-матриц, но только одна X-матрица.
Чтобы быть эффективным, я могу представить W как массив (w), содержащий диагональную часть. Тогда в R это будет
crossprod(X, w*X)
или просто
crossprod(X * sqrt(w))
Я мог бы перебрать цикл W, но это кажется неэффективным. Весь продукт может быть как Изменяется только w, поэтому продукты X_i * X_j для столбцов я и j могут быть переработаны. Функция, которую я хотел бы создать, выглядит так:
Rcpp::List Crossprod_sparse(Eigen::MappedSparseMatrix<double> X, Eigen::Map<Eigen::MatrixXd> W) {
int K = W.cols();
int p = X.cols();
Rcpp::List crossprods(W.cols());
for (int k = 0; k < K; k++) {
Eigen::SparseMatrix<double> matprod(p, p);
for (int i = 0; i < p; i++) {
Eigen::SparseVector<double> prod = X.col(i).cwiseProduct(W.col(k));
for (int j = i; j < p; j++) {
double out = prod.dot(X.col(j));
matprod.coeffRef(i,j) = out;
matprod.coeffRef(j,i) = out;
}
}
matprod.makeCompressed();
crossprods[k] = matprod;
}
return crossprods;
}
который возвращает правильные продукты и должен быть эффективным из-за работы с промежуточной переменной prod
. Однако для циклирования в R с использованием crossprod
, похоже, все еще намного быстрее, несмотря на то, что не использует переработку. Как я могу оптимизировать эту функцию больше?