How to store a custom Eigen Tensor class into std::vector?

158 views Asked by At

I am trying to create a std::vector (DIIS_Tensors) that holds a few (DIIS_num_iters) iterates of a tensor I'm converging.

I initialized DIIS_Tensors as such:

std::vector<TensorRank4> DIIS_Tensors(DIIS_num_iters);

where TensorRank4 is a custom class defined below:

class TensorRank4 {
public:
  TensorRank4(size_t dim0, size_t dim1, size_t dim2, size_t dim3) {
    dims_[0] = dim0;
    dims_[1] = dim1;
    dims_[2] = dim2;
    dims_[3] = dim3;
    data_.resize(dims_[0] * dims_[1] * dims_[2] * dims_[3]);
  }
  double& operator ()(size_t i, size_t j, size_t k, size_t l) {
    return data_(index(i, j, k, l));
  }
  const double& operator ()(size_t i, size_t j, size_t k, size_t l) const {
    return data_(index(i, j, k, l));
  }


//  std::vector<double> resizeR4TensortoVector(const TensorRank4 &t_dim4, int dim0, int dim1, int dim2, int dim3){

  void setZero() { data_.setZero();}
  void clear() {
    data_.resize(0);
    std::fill(dims_, dims_ + 4, 0); // It may not be std::fill but you get the posize_t.
  }

private:
  size_t index(size_t i, size_t j, size_t k, size_t l) const {
    return i * dims_[3] * dims_[2] * dims_[1]
         + j * dims_[3] * dims_[2]
         + k * dims_[3]
         + l;
  }
  size_t dims_[4];
  Eigen::VectorXd data_;
};

However, when I run this code, I get the error:

no matching constructor for initialization of 'TensorRank4'

Based on some searching, it seems to be related to not having a default constructor for this class, but I'm confused as to how to work around this issue.

2

There are 2 answers

1
leslie.yao On BEST ANSWER

std::vector<TensorRank4> DIIS_Tensors(DIIS_num_iters);> is trying construct DIIS_num_iters default-inserted elements of type TensorRank4.

Constructs the container with count default-inserted instances of T.

But TensorRank4 doesn't have default constructor and can't be default-inserted.

You can add a default constructor for TensorRank4, or pass an instance to the constructor of vector.

Constructs the container with count copies of elements with value value.

e.g.

// construct DIIS_Tensors with DIIS_num_iters copies of TensorRank4(1,2,3,4)
std::vector<TensorRank4> DIIS_Tensors(DIIS_num_iters, TensorRank4(1,2,3,4));
0
Javier Silva Ortíz On

This line:

std::vector<TensorRank4> DIIS_Tensors(DIIS_num_iters);

is trying to default contruct DIIS_num_iters amount of TensorRank4 objects. Therefore, if you don't have a default ctor, the compiler complains.

Just add a default ctor to your TensorRank4 class:

TensorRank4() {
      //Code if needed
  }

Note that you can also have a default ctor if you supply default parameters for your parameterized ctor like this:

TensorRank4(size_t dim0 = val0, size_t dim1 = val1, size_t dim2 = val2, size_t dim3 = val3) {
    ...
}

Alternatively, you can explicitly construct the copies in the vector by using your ctor like this:

std::vector<TensorRank4> DIIS_Tensors(DIIS_num_iters, TensorRank4(5,5,5,5));