0
votes

I'd like to call a function that allocates, compute, and then returns to the calling function several Eigen matrixes.

The output size of each matrix is not known before hand, ergo we cannot allocate such matrices in the calling function.

Here is what I though was the way (passing Matrices in by Ref class, and resize inside):

FromImageToAb(image, 
Eigen::Ref<Eigen::SparseMatrix<double>> Aout, Eigen::Ref<Eigen::VectorXd> bout){

    ... // determine what size matrixes must have: int equationcounter, numberofunknowns

    // Allocate matrixes of the correct size
    SparseMatrix<double> A(equationcounter, numberofunknowns);
    SparseMatrix<double> bM(equationcounter, 1);

    ... // fill A and bM 

    VectorXd b(bM); // Now we have successfully created a dense vector of the correct size that cannot be known before hand

    Aout = A;
    bout = b;
}


main(){
    SparseMatrix<double> Aout(1,1); // Creating matrix with token size
    VectorXd bout(1); // Creating matrix with token size
    FromImageToAb(image, Aout, bout);

}

but Aout = A; doesn't allocate memory and copy the values so it's usable outside and bout = b; doesn't compile, as dense matrices cannot be resized to increase memory

What's the correct way to go about this?

1
Your function doesn't take any parameter by reference, also there's a return type (at least void) missing from the definition.πάντα ῥεῖ
"... returns to the calling function several Eigen matrixes..." - So, return a std::vector of matrices. Why wouldn't you?Jesper Juhl
Because the matrices will be of different typesWurmD

1 Answers

0
votes

Why not return a value that contains both?

std::tuple<Eigen::SparseMatrix<double>, Eigen::VectorXd> FromImageToAb(image_t image)
{
    ... // determine what size matrixes must have: int equationcounter, numberofunknowns

    // Allocate matrixes of the correct size
    SparseMatrix<double> A(equationcounter, numberofunknowns);
    SparseMatrix<double> bM(equationcounter, 1);

    ... // fill A and bM 

    return { a, bM }; // Uses implicit conversion of SparseMatrix<double> -> VectorXd
}

If you have a C++17 compiler, you can avoid default constructing the values with structured bindings

int main(){
    auto [a, b] = FromImageToAb(image);
    // use a and b
}

Otherwise you can assign multiple things with std::tie

int main(){
    SparseMatrix<double> a; // Default construct
    VectorXd b; // Default construct
    std::tie(a, b) = FromImageToAb(image);
    // use a and b
}