Eigen library --> initialize matrix with data from file or existing std::vector<string> content (c++)

The following code works with files containing matrices of arbitrary size:

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

using namespace std;
using namespace Eigen;

#define MAXBUFSIZE  ((int) 1e6)

MatrixXd readMatrix(const char *filename)
    {
    int cols = 0, rows = 0;
    double buff[MAXBUFSIZE];

    // Read numbers from file into buffer.
    ifstream infile;
    infile.open(filename);
    while (! infile.eof())
        {
        string line;
        getline(infile, line);

        int temp_cols = 0;
        stringstream stream(line);
        while(! stream.eof())
            stream >> buff[cols*rows+temp_cols++];

        if (temp_cols == 0)
            continue;

        if (cols == 0)
            cols = temp_cols;

        rows++;
        }

    infile.close();

    rows--;

    // Populate matrix with numbers.
    MatrixXd result(rows,cols);
    for (int i = 0; i < rows; i++)
        for (int j = 0; j < cols; j++)
            result(i,j) = buff[ cols*i+j ];

    return result;
    };

Regards.


I just released an extension of the Eigen package that does some of what you want. It defines the >> operator, so you can say:

MatrixXd A(5,5); cin >> A;

It also lets you assign a VectorXd to equal a std::vector. The extended version of Eigen can be found here. However, it doesn't (yet) let you copy a std::vector into a MatrixXd object that isn't a vector. The functionality you want is the Map function in Eigen.


I think I found a solution! Its not fast or efficient but it works:

#include "topo.h"
#include <iostream>
#include <fstream>
#include <vector>
#include <Eigen/Dense>
#include <Eigen/Sparse>
#include <iterator>
#include <algorithm>


using namespace std;
using namespace Eigen;

/**Read data from File and store it in vector as string**/
int readFromFile (const char * path, vector <string> & mv) // muss vector vorher resized werden? wenn ja lese zeilenanzahl
{
    fstream file;
    string line;
    file.open(path);

    while (getline(file,line)) // lese zeile für zeile
    {
        mv.push_back(line); //fülle vector von hinten last in first
    }
    file.close();
    return 0;
}


typedef Matrix <int, 4, 4> MyMatrix; // Matrix später dynamisch

/**Parsing data to be used as Eigen Matrix**/
int fromVectoEigen (vector<string> & source, MyMatrix & target)
{   /**convert string to int and write it to the two dimensional array **/
    int array [4][4]; // noch resize nach vectorsize -->matrizen sind quadratisch
    int i = source.size();
    for ( i= i-1 ; i >= 0 ; i-- ) // da nur von hintern auf vector zugreifbar auch von hinten bei array anfangen
    {
        string myString = source.back(); // leztzes Element von Vector als String
        stringstream ssin(myString);
        int j = 0;
        while (ssin.good() && j < 4) // auch hier vectorsize später dynamisch
            {
            ssin >> array[j][i]; // fülle spalten in i.ter zeile
            ++j;
            }


        source.pop_back(); //lösche letztes element

    }
//        cout<<array[0][0]<<array[1][0]<<array[2][0]<<array[3][0]<<'\n';
//        cout<<array[0][1]<<array[1][1]<<array[2][1]<<array[3][1]<<'\n';
//        cout<<array[0][2]<<array[1][2]<<array[2][2]<<array[3][2]<<'\n';
//        cout<<array[0][3]<<array[1][3]<<array[2][3]<<array[3][3]<<'\n';
//
    /** from 2 dimensional array to one dimensional array**/
    int newarray [16]; // vectorsize * vectorsize
    int k = 0;
    for ( int i = 0 ; i< 4 ; i++) // vectorsize
    {   for (int j = 0 ; j<4; j++) // vectorsize
            {
                newarray[k]=array[j][i];
                k++;
            }

    }
    /**create Eigen Matrix from Array**/
    target= Map<Matrix4i>(newarray);
    target.transposeInPlace();
    cout<<target<<'\n';



return 0 ;
}