Быстрый поэлементный доступ в Eigen :: SparseMatrix в скрытом распределении Дирихле - PullRequest
0 голосов
/ 24 июня 2019

Я использую Скрытое распределение Дирихле (LDA) в Rcpp. В LDA нам приходится иметь дело с огромной разреженной матрицей (например, 50 x 3000).

Я решил использовать SparseMatrix в Eigen. Однако, поскольку мне нужен доступ к каждой ячейке, вычислительно дорогой .coeffRef сильно замедляет мою работу.

Есть ли способ использовать SparseMatrix, сохраняя скорость?

То, что я хочу сделать, состоит из четырех шагов,

  1. Я знаю, к какой ячейке (i, j) я хочу получить доступ.
  2. Я хочу знать, равна ли ячейка (i, j) 0 или нет.
  3. Если ячейка (i, j) не равна 0, я хочу знать ее значение.
  4. После некоторого анализа значения в шагах 2 и 3 я хочу обновить ячейку (i, j). На этом этапе мне может потребоваться обновить ячейку (i, j), которая изначально имеет 0.
#include <iostream>
#include <Eigen/dense>
#include <Eigen/Sparse>
using namespace std;
using namespace Eigen;
typedef Eigen::Triplet<double> T;

int main(){

  Eigen::SparseMatrix<double> spmat;

  // Insert in spmat
  vector<T> tripletList;
  int value;

  tripletList.push_back(T(0,1,1));
  tripletList.push_back(T(0,3,2));
  tripletList.push_back(T(1,5,3));
  tripletList.push_back(T(2,4,4));
  tripletList.push_back(T(4,1,5));
  tripletList.push_back(T(4,5,6));
  spmat.resize(5,7);  // define size
  spmat.setFromTriplets(tripletList.begin(), tripletList.end());

  for(int i=0; i<5; i++){ // I am accessing all cells just to clarify I need to access cell
    for(int j=0; j<7; j++){
      // Check if (i,j) is 0  
      if(spmat.coeffRef(i,j) != 0){
        // Some analysis
        value = spmat.coeffRef(i,j)*2;  // just an example, more complex in the model
      }
      spmat.coeffRef(i,j) += value;  // update (i,j)
    }
  }

  cout << spmat << endl;

  return 0;
}

Поскольку число строк намного меньше, чем столбцов, я рассмотрел доступ к столбцу и затем проверил значение строки, но не смог обработать SparseMatrix<double>::InnerIterator it(spmat, colid).

...