Is there some easy and fast way to convert a sparse matrix to a dense matrix of doubles?
Because my SparseMatrix is not sparse any more, but became dense after some matrix products.
Another question I have: The Eigen library has excellent performance, how is this possible? I don't understand why, because there are only header files, no compiled source.
Let's declare two matrices:
SparseMatrix<double> spMat;
MatrixXd dMat;
Sparse to dense:
dMat = MatrixXd(spMat);
Dense to sparse:
spMat = dMat.sparseView();
Related
I am trying achieve the following dense matrix operation for a sparse symmetrical matrix:
dm.col(j).swap(dm.col(i));
dm.row(j).swap(dm.row(i));
In order to interchange two columns (and rows) in a sparse symmetric matrix, I am trying to generate a permutation matrix so that I can pass it to .twistedBy():
Eigen::PermutationMatrix<Eigen::Dynamic, Eigen::Dynamic> P;
P.setIdentity();
P.col(j).swap(P.col(i));
sm = sm.twistedBy(P);
Unfortunately, .col().swap() is not supported for permutation matrices. What should I do?
This question clarifies the use of .twistedBy, but does not explain how to construct a permutation matrix:
Permuting sparse matrices in Eigen
I am having a hard time trying to understand the documentation of eigen:
https://eigen.tuxfamily.org/dox/classEigen_1_1PermutationMatrix.html
Any general help with that would be appreciated, too!
Thank you for your time!
You are looking for applyTranspositionOnTheRight:
Eigen::PermutationMatrix<Eigen::Dynamic, Eigen::Dynamic >::PermutationMatrix P(n);
P.setIdentity();
P.applyTranspositionOnTheRight(j, i);
For a robotics project I need a 3D matrix of a pre-defined size. Using the Eigen library, I don't see how:
1.) to create a large pre-defined matrix, seems like I have to use matrixXd but that's for a dynamic matrix.
2.) create a 3D matrix, i. e. size = (int from 200 to 1000) and matrix (size, size, size)
Creating a large matrix using static allocation is not advised as it will degrade the performance.
Instead of a 3D matrix, you can create a Vector of 2D matrices.
eg: Eigen::MatrixX< Eigen::MatrixXf, DIMENSION, 1> tmp;
Well, I find a way to build a 3d matrix in my project.
Use the vector:
typedef vector<Matrix<double, Dynamic, Dynamic>> M3;
If you want to initialize a pre-defined matrix with dimension (k,m,n), just use:
M3 W(k, M2(m, n));
This way is easy to store Eigen Matrix. But if you want to calculate 3d matrix, you should slice it to many 2d Matrix and use a loop to get the 3d result.
I am trying to convert some methods implemented in Eigen C++ dense matrix class (MatrixXd from <Eigen/Dense>) to methods with Eigen C++ sparse matrix (like SparseMatrix<double> from <Eigen/Sparse>).
Many methods can be directly transformed by simply chance MatrixXd to SparseMatrix<double>. However, some methods cannot be.
One problem I met is to convert the following elementwise dividend into sparse matrix method:
(beta.array() / beta.cwiseAbs().array()).sum()
Originally, beta is declared as MatrixXd beta. Now, if I declare beta as SparseMatrix<double> beta, there is no more corresponding array() method to allow me to do the above.
How should I still perform element-wise operations with sparse matrix?
Is there any efficient way that I can convert dense matrix to sparse matrix and vice versa?
This is not supported because rigorously you would compute 0/0 for any explicit zeros. You can workaround if the matrix is in compress mode, to be sure call:
beta.makeCompressed();
then map the nonzeros as a dense array:
Map<ArrayXd> a(beta.valuePtr(), beta.nonZeros();
(a / a.abs()).sum;
I am trying to multiply 2 eigen sparse matrices. The code is as follows:
Eigen::SparseMatrix<float> SpMat;
SpMat mat_1;
mat_1.resize(n_e, n_e);
... Fill the matrix. It is sparse
SpMat mat_2;
mat_1.resize(n_e, n_e);
... Fill the matrix. It is sparse
SpMat mat_3 = (mat_1 * mat_2).pruned();
This works fine for small matrices but for larger matrices, it just runs and runs and ten crashes with a seg fault. The same thing in Matlab takes a couple of seconds. So, I wonder if it is trying to keep the full matrix somewhere. If it does, that is really bad! I looked at the documentation and doing this is what it suggested to prune the matrix on the fly.
Basically, the document is sightly confusing for me at least.
the way to do it is simply:
SpMat mat_3 = mat_1 * mat_2
No dense matrix is created along the way.
Eigen rocks!
I'm writing a program with Armadillo C++ (4.400.1)
I have a matrix that has to be sparse and complex, and I want to calculate the inverse of such matrix. Since it is sparse it could be the pseudoinverse, but I can guarantee that the matrix has the full diagonal.
In the API documentation of Armadillo, it mentions the method .i() to calculate the inverse of any matrix, but sp_cx_mat members do not contain such method, and the inv() or pinv() functions cannot handle the sp_cx_mat type apparently.
sp_cx_mat Y;
/*Fill Y ensuring that the diagonal is full*/
sp_cx_mat Z = Y.i();
or
sp_cx_mat Z = inv(Y);
None of them work.
I would like to know how to compute the inverse of matrices of sp_cx_mat type.
Sparse matrix support in Armadillo is not complete and many of the factorizations/complex operations that are available for dense matrices are not available for sparse matrices. There are a number of reasons for this, the largest being that efficient complex operations such as factorizations for sparse matrices is still very much an open research field. So, there is no .i() function available for cx_sp_mat or other sp_mat types. Another reason for this is lack of time on the part of the sparse matrix developers (...which includes me).
Given that the inverse of a sparse matrix is generally going to be dense, then you may simply be better off turning your cx_sp_mat into a cx_mat and then using the same inversion techniques that you normally would for dense matrices. Since you are planning to represent this as a dense matrix anyway, then it's a fair assumption that you have enough RAM to do that.