how to print Eigen tensor to text file?

I am trying to print a 3D matrix into a text file and use it to make plots in MATLAB. I have been using std::ofstream("3DTest.txt") << Test; for all my Eigen matrices, but for some reason this isn't working for an Eigen tensor and when I try to read it in MATLAB it returns something like 10x100 instead of 10x10x10.
@JamieAl, you will get more replies if you provide a full example.

Anyway,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <Eigen/Dense>
#include <unsupported/Eigen/CXX11/Tensor>

using namespace std;
using namespace Eigen;

int main()
{
   const int nx = 3, ny = 4, nz = 5;
   Tensor<int,3> T(nx,ny,nz);
   for ( int i = 0; i < nx; i++ )
      for ( int j = 0; j < ny; j++ )
         for ( int k = 0; k < nz; k++ )
            T(i,j,k) = 100 * i + 10 * j + k;

   cout << T << '\n';
}


produces (by default):
  0  10  20  30   1  11  21  31   2  12  22  32   3  13  23  33   4  14  24  34
100 110 120 130 101 111 121 131 102 112 122 132 103 113 123 133 104 114 124 134
200 210 220 230 201 211 221 231 202 212 222 232 203 213 223 233 204 214 224 234


So it looks as if the rank-3 tensor is being treated as a 2-d matrix for the purpose of output. Each change in the first index (i) gets a new row; the remaining (j,k) indices are output as a 1-d array. It's very inconsistent, because index j changes fastest, then k, then i.

I think you will need to write your own output routine, rather than relying on the operator <<
Last edited on
@lastchance
Thanks. I was able to write something very simple that works for only small numbers of nx,ny,nz but somehow not larger numbers.

Example:
1
2
3
4
5
6
  std::ofstream file("test.txt");
  if (file.is_open())
  {
    file << T << '\n';
  }

This works for nx,ny,nz = 4,4,4 but if I try:
1
2
3
static const int nx = 32;
static const int ny = 32; 
static const int nz = 32;

This returns something strange, the test text file looks like:
 
†††‱†††‱†††‱†††‱†††‱†††‱†††‱†††‱†††‱†††‱...
Please include a minimal compileable example showing your code. We have no way of knowing what you have put in your tensor.
Sure, right! Here's an 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
38
39
40
41
42
43
44
45
46
47
static const int nx = 16;  
static const int ny = 16; 
static const int nz = 16;
double Lx = 128; 
double Ly = 128;
double LZ = 128;
double dx = Lx / nx;
double dy = Ly / ny;
double dz = Lz / nz;

double A = (2 * EIGEN_PI)/Lx;
double A1 = (2 * EIGEN_PI)/ Ly;
Eigen::Tensor<double, 3> eXX(nx,ny,nz); 
eXX.setZero(); 
Eigen::Tensor<double, 3> eYY(nx,ny,nz); 
eYY.setZero(); 
Eigen::Tensor<double, 3> eZZ(nx,ny,nz); 
eZZ.setZero(); 
 
for(int i = 0; i< nx; i++){
	for(int j = 0; j< ny; j++){
		for(int k = 0; k< nz; k++){ 
			eXX(k,i,j) = i*dx;
			eYY(j,i,k) = j*dy;//eYY(k,i,j) = j*dy;
			eZZ(j,i,k) = k*dz; //eZZ(k,i,j) = k*dz;
		}

	}		
}

Eigen::Tensor<double, 3> uFun(nx,ny,nz); 
uFun.setZero(); 
	
for(int i = 0; i< nx; i++){
	for(int j = 0; j< ny; j++){
		for(int k = 0; k< nz; k++){ 
				uFun(k,i,j) = sin(3. * A * eZZ(k,i,j)) * sin(A * eXX(k,i,j)) * cos(A1 * eYY(k,i,j));
               
		}

	}		
}
  std::ofstream file("test.txt");
  if (file.is_open())
  {
    file << uFun << '\n'; 
  }
Last edited on
This seems to be "readable" by MATLAB but for some reason it looks weird only when I view it. The issue is this is readable as 16x256 instead of 16x16x16.
The issue is this is readable as 16x256 instead of 16x16x16.


Same reason as here:
https://cplusplus.com/forum/general/284964/#msg1236003

If you use << for ostream ouput in Eigen then it expects to be outputting a 2-d matrix. So it flattens the last two indices, turning 16x16x16 to 16x256.

There is no reason whatsoever that a "quick" output from C++ (or anything else) should be readable in the "same" format in Matlab. If you want to read your output in Matlab then you will have to write an outputter for C++ that formats the output in the same way as Matlab expects to read it.




This returns something strange, the test text file looks like:
†††‱†††‱†††‱†††‱†††‱†††‱†††‱†††‱†††‱†††‱...

Nope, I can't reproduce that. The following works fine.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <fstream>
#include <Eigen/Dense>
#include <unsupported/Eigen/CXX11/Tensor>

using namespace std;
using namespace Eigen;

int main()
{
   const int nx = 32, ny = 32, nz = 32;
   Tensor<int,3> T(nx,ny,nz);
   for ( int i = 0; i < nx; i++ )
      for ( int j = 0; j < ny; j++ )
         for ( int k = 0; k < nz; k++ )
            T(i,j,k) = 100 * i + 10 * j + k;

   ofstream f( "output.txt" );
   f << T << '\n';
}

As I said, you need to upload complete, compileable code ... not some random section from the middle of it.
Last edited on
Topic archived. No new replies allowed.