How to print Eigen tensor EVERY iteration?

I made an older post about printing an Eigen tensor into a text file and where the example I am using here isn't really ideal, it ended up working for me through using a workaround.

So, I end up using this code snippet to print my Eigen tensor as a 2D matrix and then I would reshape it back to a 3D matrix in MATLAB.
1
2
3
4
5
std::ofstream Test("test.txt");
if (file.is_open())
{
   Test<< T<< '\n'; 
}

Now I have an printf statement in my code that prints out stuff every single iteration and I would like it to print out the above text file every single iteration as well.

Example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
static const int nx = 16; 
static const int ny = 16;
static const int nz = 16;

double saveFrequency = 1.0;
int phi_iter = 0;
int saveNum = 1;
int iter_max = 100000;

Eigen::Tensor<double, 3> F(nx,ny,nz); 
F.setZero();
for(int i = 0; i< nx; i++){
    for(int j = 0; j< ny; j++){
	for(int k = 0; k< nz; k++){ 
             F(k,i,j) = 1.0; //for simplicity
    }
  }		
}
std::vector<double> time(iter_max + 1,0.0);  
	

for (int iter = 0; iter < iter_max; iter++){
    double dt = 0.8;
    time[iter + 1] = time[iter] + dt; 
    printf("Iteration = %d    t = %.10f   phi_iter = %d\n", iter, time[iter+1], phi_iter);
		if ((iter/saveFrequency) - saveNum == 0){
           
            std::ofstream file("ne.txt");
            if (file.is_open())
            {
                file << F<< '\n'; //how to print this every iteration as well?
            }
            saveNum++;
			
        }
    }
	


Thanks.
Replace the printf with fprintf so the output is sent to a file stream instead of stdout.

https://en.cppreference.com/w/cpp/io/c/fprintf

You might be better off learning C++ file I/O methods, as well as using C++20's std::format for the formatted output.

https://en.cppreference.com/w/cpp/utility/format/format

If your compiler doesn't support <format> yet, currently GCC doesn't, there is the {fmt} 3rd party library.

https://fmt.dev/latest/index.html
@George P
Replace the printf with fprintf so the output is sent to a file stream instead of stdout.

Well I used that in the past with a fftw_malloc array, the thing here is I am trying to print out an Eigen tensor and something like this for example doesn't work:
1
2
3
4
5
6
7
8
9
10
11
12
13
FILE *fptr;
	
fptr = fopen(filename, "w");
	
	
for (int i = 0; i < nx; i++) {
	for (int j = 0 ; j < ny ; j++) {
		fprintf(fptr, "%+4.16le  ",arr[j + ny*i]);
	}
	fprintf(fptr, "\n");		
}
	
fclose(fptr);

This is an older function I had for a different code, but when I try to use something similar it returns an error. Something like:
1
2
3
4
5
warning: format ‘%le’ expects argument of type ‘double’, but argument 3 has type ‘Eigen::Tensor<double, 3>’ [-Wformat=]
  720 |             fprintf(fptr, "%+4.16le  ",F);
      |                            ~~~~~~~^
      |                                   |
      |                                   double


So, for now I just wanted a simple fix where I can look at my solution at different iteration and sort of have an idea if things are working well or not.
Last edited on
I have something like this, however, this prints F at every iteration in ONE single text file instead of separate files.

1
2
3
4
5
6
ofstream myfile;
myfile.open ("neTest.txt");
 for (int iter = 0; iter < iter_max; iter++){ 
  	myfile << T<< '\n';
}
 myfile.close();
Looks like tensor printing is already built-in:
std::cout << tensor3d.format(Eigen::TensorIOFormat::Plain()) << std::endl;
https://eigen.tuxfamily.org/dox/unsupported/eigen_tensors.html#title97
No clue if any of those options can be used to print the tensor in a way compatible with MATLAB, though.

I have something like this, however, this prints F at every iteration in ONE single text file instead of separate files.

Make up a new file name every iteration. Something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <string>
#include <fstream>
std::string file_name_for_iteration(int n) 
{ return "neTest" + std::to_string(n) + ".txt"; } 
// ...
for (int iter = 0; iter < iter_max; ++iter)
{
  std::ofstream my_file( file_name_for_iteration(iter) ); 
  my_file << T << '\n'; 
  // in most cases there is no need to close the file manually,
  // but we can do it anyway just to be defensive
  my_file.close();
}
Last edited on
@mbozzi
Thanks A LOT! This is perfect.
Topic archived. No new replies allowed.