2

I am trying to solve a linear equation Ax=b using Eigen's abilities for the A as a square 2D vector. I have the A and b as C++ based 2D vector and 1D vector respectively. However, I could not find a way to pass the values of them to the Eigen format matrix and vectors. Would you please let me how to copy the variable in Eigen format? Moreover, what should include in the beginning to be able to use the Map class as a possible solvent?! Here is the code:

#include <iostream>
#include <vector>

#include "Eigen/Dense"

using namespace std;
using namespace Eigen;
int main()
{
    // Let's consider that the A and b are following CPP based vectors:
    vector<vector<double>> mainA= { { 10.,11.,12. },{ 13.,14.,15. },{ 16.,17.,18. } };  
    vector<double> mainB = { 2.,5.,8. };

    // ??? Here I need to do something to pass the values to the following Eigen 
    //format matrix and vector

    MatrixXf A;
    VectorXf b;

    cout << "Here is the matrix A:\n" << A << endl;
    cout << "Here is the vector b:\n" << b << endl;
    Vector3f x = A.colPivHouseholderQr().solve(b);
    cout << "The solution is:\n" << x << endl;

}
ReA
  • 25
  • 4
  • Why don't you *only* use the Eigen types? Why do you need the C++ vectors? – Some programmer dude Jul 26 '17 at 13:38
  • @Some programmer dude The reason is currently I have existing vectors and I need to use those values for my operation! – ReA Jul 26 '17 at 13:40
  • I found something here: but not sure how to use it properly and what should I include in the beginning! – ReA Jul 26 '17 at 13:42
  • @Avi Ginsburg Thank you for the answer, I was wondering if the main vector should be "std::vector>>"?! because I tried "std::vector>" and got an error in Map!! – ReA Jul 26 '17 at 14:21
  • @Avi: And also what should I include in the beginning to make available the Map class?! -thanks – ReA Jul 26 '17 at 14:23
  • @RezaAbdi You need to write `Eigen::Map(...)` (or `Eigen::VectorXd::Map(...)`) instead of `Eigen::Map`, if you work with `double` instead of `complex` as in the related question. – chtz Jul 26 '17 at 15:30
  • 1
    And if you want to assign a `double` Eigen-vector type to a `float` Eigen matrix/vector, you additionally need to cast it, like so: `Eigen::VectorXd::Map(mainA[i].data(), 3).cast()` – chtz Jul 26 '17 at 15:32

1 Answers1

0

As mentioned in the comments, Eigen::Map<> should do the trick. Usually you'll get away without using the Unaligned, but for correctness/stability, it's best to use it:

auto A = Eigen::Map<Eigen::MatrixXd, Eigen::Unaligned>(mainA.data(), mainA.size(), mainA[0].size())
auto b = Eigen::Map<Eigen::VectorXd, Eigen::Unaligned>(mainB.data(), mainB.size());

Vector3d x = A.colPivHouseholderQr().solve(b);

To answer the question below about robustness: This can be done using helper functions:

template <typename T, int Align>
Eigen::Map<Eigen::Matrix<T, -1, -1>, Align> CreateMatrix(const std::vector<std::vector<T>>& x)
{
    int R = x.size();
    assert(!x.empty());
    int C = x[0].size();
    #ifndef NDEBUG
    for(int r=1; r < R; r++)
        assert(x[r].size() == x[0].size());
    #endif
    return auto A = Eigen::Map<Eigen::Matrix<T,-1,-1>, Align>(x.data(), R, C);
}

Although it looks verbose, it does a lot of sanity checks where you then can rely upon in all code for which you have a unit test.

Mr. White
  • 571
  • 5
  • 12
  • I was wondering if there is a more reliable way to define the matrix or vector based on the Eigen format? I am asking because I have a memory (something relevant with malloc) leak in my code, you can find my question [here](https://stackoverflow.com/questions/45339532/memory-crash-in-just-2nd-round-of-a-for-loop-including-eigen-functions). Appreciate your help. – ReA Jul 27 '17 at 18:58