I have a class that needs to use an Eigen Matrix as an instance variable. Unfortunately I have more then one size so I think I am forced to use dynamic as the size parameter;
I declare the instance variable as:
Matrix<std::complex<float>, Dynamic, Dynamic> mCSM;
and in the constructor I fix the size with:
mCSM.resize(40, 40);
I look at the matrix in the debugger and it has the correct size so I think this is good.
I now want to get the Eigen Values and Eigen Vectors for the matrix and this is where I get lost.
I try
ComplexEigenSolver<Matrix<std::complex<float>, Dynamic, Dynamic>> ces;
ces.compute(mCSM);
and to get the eigen values and eigen vectors I use:
mEva = ces.eigenvalues();
mEve = ces.eigenvectors();
mEva and mEve are both instance variables and are built just like mCSM:
Matrix<std::complex<float>, Dynamic, Dynamic> mEve;
Matrix<std::complex<float>, Dynamic, 1> mEva;
//mEve.resize(40, 40);
//mEva.resize(40);
And after the call to mEva = ces.eigenvalues(); mEva has cols = 0 and rows = 0;
Do I somehow need to tell ComplexEigenSolver the matrixSize? Is this the correct way when using dynamic matrices?
I now check if the call to compute was successful with:
ces.compute(mCSM);
if (ces.info() == Eigen::Success)
{
....
Related
This is very basic: I am normally using Eigen3 for my math operations, but need to use libtorch for a network forward pass. Now I want to populate the torch::tensor with the data from my Eigen3 (or pure C++ array), but without a for loop. How can I do this?
Here is the solution with a loop:
Eigen::Matrix<double, N, 1> inputEigen; // previously initialized
torch::Tensor inputTorch = torch::ones({1, N}); // my torch tensor for the forward pass
for (int i = 0; i < N; i++) {
inputTorch[0][i] = inputEigen[i]; // batch size == 1
}
std::vector<torch::jit::IValue> inputs;
inputs.push_back(inputTorch);
at::Tensor output = net.forward(inputs).toTensor();
This works fine for now, but N might become really large and I'm just looking for a way to directly set the underlying data of my torch::tensor with a previously used C++ array
Libtorch provides the torch::from_blob function (see this thread), which asks for a void* pointer to some data and an IntArrayRef to know the dimensions of the interpreted data. So that would give something like:
Eigen::Matrix<double, N, 1> inputEigen; // previously initialized;
torch::Tensor inputElement = torch::from_blob(inputEigen.data(), {1,N}).clone(); // dims
Please note the call to clone which you may or may not need depending or your use case : basically from_blob does not take ownership of the underlying data, so without the clone it will remain shared with (and possibly destroyed by) your Eigen matrix
For flexibility, I'm loading data into dynamic-sized matrices (e.g. Eigen::MatrixXf) using the C++ library Eigen. I've written some functions which require mixed- or fixed-sized matrices as parameters (e.g. Eigen::Matrix<float, 3, Eigen::Dynamic> or Eigen::Matrix4f). Assuming I do the proper assertions for row and column size, how can I convert the dynamic matrix (size set at runtime) to a fixed matrix (size set at compile time)?
The only solution I can think of is to map it, for example:
Eigen::MatrixXf dyn = Eigen::MatrixXf::Random(3, 100);
Eigen::Matrix<float, 3, Eigen::Dynamic> fixed =
Eigen::Map<float, 3, Eigen::Dynamic>(dyn.data(), 3, dyn.cols());
But it's unclear to me if that will work either because the fixed size map constructor doesn't accept rows and columns as parameters in the docs. Is there a better solution? Simply assigning dynamic- to fixed-sized matrices doesn't work.
You can use Ref for that purpose, it's usage in your case is simpler, and it will do the runtime assertion checks for you, e.g.:
MatrixXf A_dyn(4,4);
Ref<Matrix4f> A_fixed(A_dyn);
You might even require a fixed outer-stride and aligned memory:
Ref<Matrix4f,Aligned16,OuterStride<4> > A_fixed(A_dyn);
In this case, A_fixed is really like a Matrix4f.
I wish to convert a simple 2D array into a SparseMatrix, in order to improve performance and run time, since I am dealing with an array of a size around 50,000-70,000.
So far what I have:
SparseMatrix<double> sp;
sp.resize(numCells,numCells);
double Matrix[numCells,numCells];
Matrix = Map<SparseMatrix>(Matrix,numCells,numCells);
The compiler returns type mismatch value at argument 1 in template parameter list for 'template class Eigen::Map'.
I understand I am missing something here, but I can not figure it out.
Make a dense matrix and convert it into a sparse matrix:
double matrix[numCells * numCells]; // 1d array representation of your matrix
SparseMatrix<double> sp = Map<MatrixXd>(matrix,numCells,numCells).sparseView();
Is there a way to set a dynamic vector or matrix in Eigen library? If not, is there a way to still use the Eigen library in conjunction with another class like vector?
For example let's say I have n*1 matrix called MatrixXd S(n,1); Now for simplicity let n=3 and S = 4 2 6. Pretend that the elements in S are future stock prices and let K = 2 which will be the strike price. Don't worry you won't need to understand the terminology of an option. Now say I want to know at what positions of S will we have S - K > 0 and say I want to store these positions in a vector call b.
Clearly, depending on the elements of S the vector b will be of a different size. Thus, I need to have b being of a dynamic variable. The only class I am familiar with that allows this is the vector class i.e., #include <vector>.
My question is as follows: Is it okay to use the Eigen library and the #include <vector> class together? Note that I will be performing operations of b with the Eigen library vectors and matrices I have created.
If I am not making sense, or if my question is unclear please let me know and I will clarify as much as possible.
Yes, it does. It's presented in the "A simple first program" of Getting started:
#include <iostream>
#include <Eigen/Dense>
using Eigen::MatrixXd;
int main()
{
MatrixXd m(2,2);
m(0,0) = 3;
m(1,0) = 2.5;
m(0,1) = -1;
m(1,1) = m(1,0) + m(0,1);
std::cout << m << std::endl;
}
You do need to pass the size to the constructor, but it's works like a vector. You can resize it later on too.
MatrixXd is a convenient typedef to a Matrix template which uses Dynamic as a template value for Rows, and Cols. It's basically Matrix<double, Dynamic, Dynamic>.
So you can have not only dynamic sized vectors and matrices, but also arbitrarily large fixed-size ones. Eigen does pretty nifty optimizations for small matrices, so using a fixed size there might be beneficial.
I have an array of doubles, and I want to create a 4-by-4 matrix using the Eigen library. I also want to specify that the data is stored in row-major order. How can I do this?
I have tried the following, but it does not compile:
double data[16];
Eigen::Matrix4d M = Eigen::Map<Eigen::Matrix4d>(data, 4, 4, Eigen::RowMajor);
You need to pass a row-major matrix type to Map, e.g.:
Map<Matrix<double,4,4,RowMajor> > M(data);
then you can use M as an Eigen matrix, and the values of data will be modified, e.g.:
M = M.inverse();
If you want to copy the data to a true column-major Eigen matrix, then do:
Matrix4d M = Map<Matrix<double,4,4,RowMajor> >(data);
Of course, you can also copy to a row-major matrix by using the right type for M.
RowMajor forms actually come in handy when using arrays to store data sometimes. Hence you can also prefer using a typedef to RowMajor type.
namespace Eigen{
typedef Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> MatrixXfRowMajor;
}
You can replace by float by any datatype of choice. For a 4x4 matrix then, we can simply do
Eigen::MatrixXfRowMajor mat;
mat.resize(4,4);