Search code examples
c++armadillo

Is there a way to create std::vector<arma::mat> from arma::mat matrices without creating a copy of the matrices?


I am new to C++. For a statistical method, I compute large matrices, e.g. A and B . They are n x n so for large sample sizes n, they become very large. If they are double and n = 70k , I think it might be on the order of 30GB? Because the number of matrices needed can vary, I implemented the algorithm to use a vector of matrices and iterate over it for some operations. E.g.

arma::mat A;
arma::mat B;
std::vector<arma::mat> matrices;
matrices = {A, B};

Is there a way to create this std::vector without copying the matrices?

I tried to check whether the memory is the same by doing this:

logger->info("Memory address for A: {}.", (void *)&A);
logger->info("Memory address for matrices.at(0): {}.", (void *)&matrices.at(0));

And it showed different addresses so I assume it is creating a copy but I am not sure.

I tried to use

std::vector<arma::mat> matrices;
matrices.push_back(A);

The memory addresses differed still. With

std::vector<arma::mat> matrices;
matrices.push_back(std::move(A));

the algorithm no longer worked because the matrices were empty.


Solution

  • You need to reverse the logic: Let the std::vector allocate the memory and create the matrices. Then you work directly with the elements in the vector. For example:

    std::vector<arma::mat> matrices;
    matrices.resize(2);
    arma::mat & A = matrices[0];
    arma::mat & B = matrices[1];
    // Initializing the values of A and B, and do stuff with them.
    

    Note: It is important to note here that the references to A and B will become invalid if you add more elements afterwards to the vector, i.e. if the vector grows. But since these matrices are so large, you want to avoid this anyway at all costs.

    If the container needs to grow, you might want to take a look at e.g. std::list.