Eigen: разреженная матрица pruned () не удаляет записи ниже порога - PullRequest
2 голосов
/ 11 марта 2019

Я хочу использовать Eigen для умножения разреженных матриц, где на каждой итерации я хочу удалить все записи ниже определенного порога.Мне кажется, что Eigen удаляет только элементы, точно равные нулю.

Я запускаю Eigen 3.3.7, компилируя с помощью g ++.

#include <Eigen/Sparse>
#include <Eigen/Dense>
#include <iostream>

using namespace Eigen;
typedef SparseMatrix<double> CscMat;            
typedef SparseMatrix<double,RowMajor> CsrMat;    

int N = 4;
CsrMat S, S2;

MatrixXd D(N, N), D2(N,N);
D << 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16;
D *= 0.1;

S = D.sparseView(0.5);
std::cout << D  << std::endl;
std::cout << S.nonZeros()  << std::endl;

D2 = D;
D2 = (D2.array() < 0.5).select(0, D2);
S2 = D2.sparseView();
std::cout << D  << std::endl;
std::cout << S2.nonZeros() << std::endl;

В приведенном выше S.nonzeros () возвращает 16вместо ожидаемых 12, как в S2.nonzeros ().

Вывод:

0.1 0.2 0.3 0.4
0.5 0.6 0.7 0.8
0.9   1 1.1 1.2
1.3 1.4 1.5 1.6
16

  0   0   0   0
0.5 0.6 0.7 0.8
0.9   1 1.1 1.2
1.3 1.4 1.5 1.6
12

Ответы [ 2 ]

1 голос
/ 11 марта 2019

Если вы прочитаете документ из sparseView, вы увидите, что первый аргумент - не абсолютный порог, а ссылка ненулевая (или ожидаемая величина, если выпредпочитают).Тогда второй необязательный аргумент является относительным порогом.Это та же логика, что и для pruned().Если вы хотите абсолютный порог, то вы можете сделать:

S = D.sparseView(1,0.5);
S = D.sparseView(0.5,1);
1 голос
/ 11 марта 2019

Второй параметр для sparseView есть reference.В итоге, произведение этих двух будет определять порог, поэтому вы должны использовать строку:

S = D.sparseView(0.5, 1.0 - std::numeric_limits<double>::epsilon());

, чтобы получить то, что вы, кажется, хотите.

Фактический код, который делаетоценка находится в MathFunctions.h

static inline bool isMuchSmallerThan(const Scalar& x, const OtherScalar& y, 
                                     const RealScalar& prec)
{
   return numext::abs(x) <= numext::abs(y) * prec;
}

, где по умолчанию prec типа double (в настоящее время) 1e-12.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...