SparseMatrix, setZero, распределение данных и innerNonZeros: как эффективно обнулить матрицу? - PullRequest
0 голосов
/ 15 мая 2019

Собственное перераспределение слишком много раз.

[Проблема]

setZero не освобождает память - и это здорово.setZero устанавливает innerNNZ в ноль: это (почти) правильно, так как я хочу нулевую матрицу.

Если я хочу установить значение в выделенном месте в матрице, код просматривает innerNNZ, чтобы определить, что ничегобыло выделено и перераспределить все.

Очевидно, использование coeffRef () вместо insert () не поможет по той же причине.

[Background]

I 'м манипулируя SparseMatrix.Сначала я предварительно распределяю матрицу по некоторому шаблону.Во-вторых, я открываю цикл, чтобы: - установить матрицу в ноль - помечать значения в ней - выполнить некоторую математику

Я хочу обнулить матрицу в начале цикла (я не ставлю на одну и ту же модель каждыйвремя).Установка его в ноль приводит к обнулению innerNNZ, и тиснение (элемент за элементом) будет по-настоящему реальным: огромное потерянное количество времени.

[Код для проверки]

int nx = 10;
int ny = nx;
Eigen::VectorXi sizeToReserve(nx);
for(int i = 0; i < nx; i++) 
   sizeToReserve[i] = myOwnBusiness(i);
SparseMatrix<double> mat;
mat.uncompress();
mat.reserve(sizeToReserve);

for(int i = 0; i < nbRun; i++) {
   mat.setZero();
   for(int j = 0; j < nx; j++) {
      for (int k = 0; k < ny; k++) {
         mat.insert(j,k) = aValue(i,j,k);
      }
   }
   // Do fancy stuff
}

Я ожидаю, что мат.insert, чтобы не перераспределять память.

[Trick]

Я уменьшу матрицу до нуля, чтобы не касаться массива innerNNZ и outerIndex.

1 Ответ

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

Вы можете перебрать ненулевые значения с помощью (адаптировано из документов ):

for (int k=0; k<mat.outerSize(); ++k)
   for (SparseMatrix<double>::InnerIterator it(mat,k); it; ++it)
      it.valueRef() = 0.0;

Другой вариант - заключить указатель данных в Eigen::Map<VectorXd> и использовать его для setZero():

Map<VectorXf> myMap(mat.valuePtr(), mat.nonZeros());
myMap.setZero();
...