How to convert an std::vector to a matrix in Eigen?
Asked Answered
C

2

6

I am somewhat new to Stack Overflow and C++ so feel free to correct any errors in my code and the formatting of this question.

I am trying to make a linear regression calculator using the normal equation which involved the transposing of matrices and multiplication of vectors (and their inverses). The program is supposed to read from a csv file and pass the information from that file into a matrix and calculate the regression line. To make the job easier, I decided to use a library called Eigen for matrix-matrix multiplication.

The problem that I have run into is that the Map function can only take in an array as opposed to a std::vector.

This is what I have so far:

float feature_data[] = { 1, 1, 1, 1, 1, 1,
                         2, 4.5, 3, 1,4, 5};
float labels[] = { 1, 4, 3, 2, 5, 7 };


//maps the array to a matrix called "feature_data"
MatrixXf mFeatures = Map< Matrix<float, 6, 2> >(feature_data);
MatrixXf mLabels = Map< Matrix<float, 6, 1> >(labels);

//use the toArray function
std::vector<float> test_vector = { 2,1,3 };
float* test_array = toArray(test_vector);


calcLinReg(mFeatures, mLabels);

const int n = 2;
int arr[n];

system("pause");

For context, the toArray function is my unsuccessful attempt to make an array from a vector (in all honesty, it works but it returns a pointer which you can't pass into the Map function in Eigen.) calcLinReg does exactly what it sounds like: calculates the linear regression line parameters.

Is there anyway I can convert a vector to an array or convert a vector to a matrix in Eigen?

Catchup answered 10/9, 2018 at 15:47 Comment(0)
A
8

How about trying to use the vectors data() method, which gives you access to the memory array used internally by the vector, like this:

    std::vector<float> test_vector = { 2,1,3 };
    float* test_array = test_vector.data();
    Eigen::MatrixXf test = Eigen::Map<Eigen::Matrix<float, 3, 1> >(test_array);

Or shorter:

    std::vector<float> test_vector = { 2,1,3 };
    Eigen::MatrixXf test = Eigen::Map<Eigen::Matrix<float, 3, 1> >(test_vector.data());

Beware The asignment actually copies the data, therefore this is safe. However, you can also directly use the data of the vector like this

    std::vector<float> test_vector(3,2);
    Eigen::Map<Eigen::Matrix<float, 3, 1> > dangerousVec (test_vector.data());

If vector goes out of scope the memory is deallocated and dangerousVec's data is dangeling.

Agrippina answered 10/9, 2018 at 15:55 Comment(2)
This seems to work fine but I didn't think that the Map function could take in a pointer.Catchup
how can we implement this if the row and col number where something dynamic for example something like that Eigen::Map<Eigen::Matrix<float, sqrt(test_vector.size()), sqrt(test_vector.size())> > which dosent compilesKaseykasha
N
4

Someone in a comment is asking for the case of dynamic numbers of rows and columns. This is possible, as follows:

typedef Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic> MyMatrix;

size_t nrow = ...;
size_t ncol = ...;
MyMatrix M = Eigen::Map<MyMatrix>(test_vector.data(), nrow, ncol);
Nombril answered 18/11, 2022 at 10:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.