Search code examples
c++eigeneigen3

Writing Eigen vector to a library in a tab delimited fashion


I'm currently writing a bunch of values to an eigen array during a for loop. I want to write the state of that Eigen array to that file after every iteration of the for loop in a tab delimited fashion. However, in the way I'm currently doing it, I'm writing the file and it just appends the values of the eigen array onto the column that the previous vector is already on. The result is files that are 1 columns thats 200,000 entries long where they should be 200 columns that's 1000 entries long. Quick example code below to show the process.

#include<iostream>
#include<fstream>
#include<Eigen>

using Eigen::VectorXd;

int main()
{
    std::ofstream myfile1;
    VectorXd en(1000);
    std::string energyname = "Energies.txt";
    myfile1.open(energyname);
    for (int i = 0; i < 200; i++)
    {

        for (int j = 0; j < 1000; j++)
        {
            en(j) = 10;
        }
        myfile1 << en << std::endl;
    }

}

How do I reword this so that it doens't append the code onto the back of the end of the output


Solution

  • VectorXd is a column vector. If you actually want a row vector, you need RowVectorXd:

    #include <iostream>
    #include <fstream>
    #include <Eigen>
    
    using Eigen::RowVectorXd;
    
    int main()
    {
        std::ofstream myfile1;
        RowVectorXd en(1000);
        std::string energyname = "Energies.txt";
        myfile1.open(energyname);
        for (int i = 0; i < 200; i++)
        {
    
            for (int j = 0; j < 1000; j++)
            {
                en(j) = 10;
            }
            myfile1 << en << std::endl;
        }
    
    }
    

    If you actually need a column vector, and just want to print the transpose of this column vector, you can use Eigen::IOFormat to change the end-of-row separator from "\n" to " ". This is the 4th parameter to IOFormat so we need to re-pass defaults to the first 3 parameters.

    #include<iostream>
    #include<fstream>
    #include<Eigen>
    
    using Eigen::VectorXd;
    using Eigen::IOFormat;
    using Eigen::StreamPrecision;
    
    int main()
    {
        std::ofstream myfile1;
        VectorXd en(1000);
        std::string energyname = "Energies.txt";
        myfile1.open(energyname);
    
        IOFormat column_transpose_format(StreamPrecision, 0, " ", " ");
    
        for (int i = 0; i < 200; i++)
        {
    
            for (int j = 0; j < 1000; j++)
            {
                en(j) = 10;
            }
            myfile1 << en.format(column_transpose_format) << std::endl;
        }
    
    }
    

    Neither of these are tested.