I'm trying to do some operations on matrices using a matrix library named, "Eigen Library". I've a 50 X 100000 matrix in size and I want to find its covariance matrix. So, can I get a built_in function to to find covariance matrix?
C++ sample code:
#include "Eigen/Core"
#include "Eigen/Dense"
using namespace Eigen;
using namespace std;
int main()
{
MatrixXf my_matrx = MatrixXf::Random(50,100000);
//Now, i want to find a function to find the covariance matrix of "my_matrx", like below:
MatrixXf my_cov_matrix = any_function(my_matrx);
}
Related
I'm having trouble trying to calculate the exponential of a complex matrix with the C++ Eigen library.
Below is an example code I try to make work.
#include <iostream>
#include "Dense"
#include <complex>
#include "unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h"
int main()
{
using namespace std::complex_literals;
Eigen::MatrixXcd test(2,2);
test(0,0)=1i+std::complex<double>(5);
test(1,0)=1i*2.;
test(0,1)=std::complex<double>(2);
test(1,1)=3.*1i+std::complex<double>(3);
std::cout << "The matrix exponential is:\n"
<< test.exp() << "\n\n";
}
When I run this program I get the error:
Implicit instantiation of undefined template 'Eigen::MatrixFunctionReturnValue<Eigen::Matrix<std::__1::complex<double>, -1, -1, 0, -1, -1> >'
I have tried to find an answer but I haven't found one yet.
Any help would be greatly appreciated.
Edit:
The standard matrix operations in Eigen work and the Eigen file/folder are located in my project folder. The only functions that don't seem to work are the matrix functions in the unsupported folder for complex matrixes (they do work for real ones).
You must not directly include headers from the Eigen/src or unsupported/Eigen/src subdirectories. Also, instead of #include "Dense" use #include <Eigen/Dense> (in many cases <Eigen/Core> is actually sufficient).
In your case you actually just need these includes, because all necessary dependencies are included by MatrixFunctions:
#include <iostream>
#include <unsupported/Eigen/MatrixFunctions>
Godbolt-Demo: https://godbolt.org/z/PmJWP3 (compilation may occasionally time out).
I can't compute eigen values and eigen vectors for new type of matrix initialized by means of boost multiprecision.
#include<iostream>
#include<Eigen/Dense>
#include<Eigen/Eigenvalues>
#include<boost/multiprecision/eigen.hpp>
#include<boost/multiprecision/cpp_complex.hpp>
#include<complex>
using namespace std;
using namespace Eigen;
using namespace boost::multiprecision;
int main() {
Matrix<cpp_complex_single, Dynamic, Dynamic> A = Matrix<cpp_complex_single, Dynamic, Dynamic>::Identity(3,3);
ComplexEigenSolver<Matrix<cpp_complex_single, Dynamic, Dynamic>> ces(A);
return 0;
}
Error log is quite long, so I decided to put it on pastebin, here is the link https://pastebin.com/XfvLT9y4. Summarizing: is there any way to compute eigen problem for new type of complex matrix initialized with boost multiprecision ?
I am trying to implement an Eigen library pseudo-inverse function in a Matlab MEX-file. It compiles successfully but crashes when I run it.
I am trying to follow the FAQ on how to implement a pseudo-inverse function using the Eigen library.
The FAQ suggests adding it as a method to the JacobiSVD class but since you can't do that in C++ I'm adding it to a child class. It compiles successfully but then crashes without an error message. It successfully outputs "hi" without crashing if I comment out the line with the .pinv call so that's where the problem is arising. To run, I just compile it (as test.cpp) and then type test at the command line. I am using Matlab R2019a under MacOS 10.14.5 and Eigen 3.3.7. In my full code I also get lots of weird error messages regarding the pinv code but before I can troubleshoot I need this simple test case to work. This is all at the far limits of my understanding of C++. Any help appreciated.
#include "mex.h"
#include <Eigen/Dense>
#include <Eigen/SVD>
#include <cstdlib>
#include <cmath>
#include <iostream>
using namespace Eigen;
using namespace std;
//https://stackoverflow.com/questions/18804402/add-a-method-to-existing-c-class-in-other-file
class JacobiSVDext : public JacobiSVD<MatrixXf> {
typedef SVDBase<JacobiSVD<MatrixXf>> Base;
public:
using JacobiSVD::JacobiSVD; //inherit constructors //https://stackoverflow.com/questions/347358/inheriting-constructors
MatrixXf pinv() //http://eigen.tuxfamily.org/index.php?title=FAQ
{
eigen_assert(m_isInitialized && "SVD is not initialized.");
double pinvtoler=1.e-6; // choose your tolerance wisely!
JacobiSVDext::SingularValuesType singularValues_inv=m_singularValues;
for ( long i=0; i<m_workMatrix.cols(); ++i) {
if ( m_singularValues(i) > pinvtoler )
singularValues_inv(i)=1.0/m_singularValues(i);
else singularValues_inv(i)=0;
}
return m_matrixV*singularValues_inv.asDiagonal()*m_matrixU.transpose();
};
};
/* The gateway function */
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[])
{
MatrixXf X = MatrixXf::Random(5, 5);
JacobiSVDext svd(X);
MatrixXf Y=svd.pinv();
cout << Y << endl;
cout << "hi" << endl;
}
The expected result is to output the pseudo-inverse of the random matrix and also "hi". Instead it crashes without an error message.
When constructing the Eigen::JacobiSVD object, you fail to request that matrices U and V should be computed. By default, these are not computed. Obviously, accessing these matrices if they are not computed will cause a segmentation violation.
See the documentation to the constructor. A second input argument must specify either ComputeFullU | ComputeFullV, or ComputeThinU | ComputeThinV. The thin ones are preferable when computing the pseudo-inverse, as the rest of the matrices are not needed.
I would not derive from the JacobiSVD class just to add a method. Instead, I would simply write a free function. This is both easier, and allows you to use only the documented portions of the Eigen API.
I wrote the following MEX-file, which works as intended (using code I already had for this computation). It does the same, but in a slightly different way that avoids writing an explicit loop. Not sure this way of writing it is very clear, but it works.
// Compile with:
// mex -v test.cpp -I/usr/local/include/eigen3
#include "mex.h"
#include <Eigen/Dense>
#include <Eigen/SVD>
#include <cstdlib>
#include <cmath>
#include <iostream>
Eigen::MatrixXf PseudoInverse(Eigen::MatrixXf matrix) {
Eigen::JacobiSVD< Eigen::MatrixXf > svd( matrix, Eigen::ComputeThinU | Eigen::ComputeThinV );
float tolerance = 1.0e-6f * float(std::max(matrix.rows(), matrix.cols())) * svd.singularValues().array().abs()(0);
return svd.matrixV()
* (svd.singularValues().array().abs() > tolerance).select(svd.singularValues().array().inverse(), 0).matrix().asDiagonal()
* svd.matrixU().adjoint();
}
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
Eigen::MatrixXf X = Eigen::MatrixXf::Random(5, 5);
Eigen::MatrixXf Y = PseudoInverse(X);
std::cout << Y << '\n';
std::cout << "hi\n";
}
Using Eigen 3.2.1, I am trying to save an Eigen::DiagonalMatrix in MarketIO format as below:
#include <Eigen/Sparse>
#include <Unsupported/Eigen/SparseExtra>
using namespace Eigen;
...
size_t n = XX;
DiagonalMatrix<num_t, Dynamic> W(n);
...
saveMarket(W, "W.txt"); // error propagates from here
However, I am getting the following error:
MarketIO.h|236|error: 'const class Eigen::DiagonalMatrix<double, -1>' has no
member named 'nonZeros'
What is the problem here? Is this implemented at all for Diagonal Matrices?
Thanks in advance for any help.
Okay! The only solution for now with minimal effort is to use the following:
saveMarketVector(W.diagonal(), "W.txt");
I am persistently getting error messages whenever I try to use the selfadjointView property of any matrix or sparse matrix using the eigen library. Below is a simple code to check that. In my program I do try with self-adjoint matrix:
#define EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET
#include <Eigen/Sparse>
#include <Eigen/Dense>
#include <Eigen/Core>
#include <iostream>
using namespace Eigen;
int main ()
{
SparseMatrix<float> mat(3,3);
Matrix<float, 3, 1> vec;
std::cout<<mat.selfadjointView<>()*vec;
}
The error message I get is:
error: no matching function for call to ‚'Eigen::SparseMatrix::selfadjointView()‚
You have to specify the template argument, so it should read mat.selfadjointView<Upper>() or mat.selfadjointView<Lower>() . The first one means that it should use the entries in the upper triangular part of mat and fill the lower triangular part to make the matrix self-adjoint. The second one is the other way around.