MttD
MttD

Reputation: 11

How to use Eigen::Matrix by reference

I have a small problem, but i don't know how to solve it.

Let's start: I need to work on a big Eigen Matrix using multithreads. Each thread need to access to the matrix. The dimension is specified during the program execution, so I must declare it inside the main(), and not as global. I tried different solutions without success. I search something like "pass by reference" but i read that this method don't work with Eigen Matrix. Here there is a small example. Can someone tell me how can I solve this problem? The program need to be fast, so something like: -save the matrix in a file, and read the file in each thread, work on the matrix, save the matrix in a file, re-read the file from the main- is not the best way, I think... ;) Does someone know a better solution? Thanks at all!

void calc() {
    // work on the Matrix
}

int main() {
    Eigen::Matrix<bool, a, b> Mat;
    // Start some thread(calc);
    cout << Mat;
}

Upvotes: 1

Views: 3075

Answers (2)

wu1meng2
wu1meng2

Reputation: 547

If you want to modify the matrix and the matrix could come from either Eigen::MatrixXd or Eigen::Map<Eigen::MatrixXd>, then you can only use Eigen::Ref<Eigen::MatrixXd>. This is common if you want to refactor some legacy projects by mapping a std::vector to an Eigen::VectorXd or Eigen::MatrixXd without making copies.

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

// // ERROR:
// // candidate function not viable: no known conversion from
// // 'Eigen::Map<Eigen::MatrixXd>' (aka 'Map<Matrix<double, Dynamic,
// // Dynamic>>') to 'Eigen::MatrixXd &' (aka 'Matrix<double, Dynamic, Dynamic>
// // &') for 1st argument
// void calc(Eigen::MatrixXd &eigen_mat) { eigen_mat *= 2.0; }

// OK
void calc(Eigen::Ref<Eigen::MatrixXd> eigen_mat) { eigen_mat *= 2.0; }

int main() {
  std::vector<double> vec(9, 1.0);
  { // OK for both `Eigen::MatrixXd &` and `Eigen::Ref<Eigen::MatrixXd>`
    Eigen::MatrixXd eigen_mat = Eigen::MatrixXd::Constant(3, 3, 1.0);
    calc(eigen_mat);
    std::cout << "MatrixXd:\n" << eigen_mat << std::endl;
  }
  { // OK only for `Eigen::Ref<Eigen::MatrixXd>`
    Eigen::Map<Eigen::MatrixXd> eigen_mat(vec.data(), 3, 3);
    calc(eigen_mat);
    std::cout << "Map<MatrixXd>:\n" << eigen_mat << std::endl;
  }
}

Upvotes: 0

Vtik
Vtik

Reputation: 3150

Si ! Eigen matrix can be passed as a reference.

Here's a working example :

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

void calc(Eigen::MatrixXf& mat) {
    mat = Eigen::MatrixXf::Constant(mat.rows(), mat.cols(), 1.0);
}

int main() {
    Eigen::MatrixXf Mat;
    Mat = Eigen::Matrix4f::Identity();
    std::cout << Mat << std::endl;
    calc(Mat);
    std::cout << Mat << std::endl;
}
  • Output :

    1 0 0 0    
    0 1 0 0    
    0 0 1 0    
    0 0 0 1
    
    1 1 1 1
    1 1 1 1
    1 1 1 1
    1 1 1 1
    

Upvotes: 1

Related Questions