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 ;
}