Search code examples
c++matrixeigen

Avoid Matrix copy constructor


I have a situation like this:

using JacobiSVD = Eigen::JacobiSVD<MatrixXcd, Eigen::FullPivHouseholderQRPreconditioner>;

class Foo {
    public:
        MatrixXcd matrixU;
        MatrixXcd matrixV;

        Foo(const Ref<const MatrixXcd>& mat);
}

Foo::Foo(const Ref<const MatrixXcd>& mat) {
    JacobiSVD svd(mat, Eigen::ComputeFullU | Eigen::ComputeFullV);
    matrixU = svd.matrixU();
    matrixV = svd.matrixV();

    // <proceed to mutate computeU and computeV>
}

I think the above creates a copy of svd.matrixU() and svd.matrixV() during construction of matrixU and matrixV. Is this true, and is there some way to avoid it?

Thanks!


Solution

  • No temporary copies are created during the construction of matrixU and matrixV. Eigen::JacobiSVD inherits from Eigen::SVDBase, which defines the member functions matrixU() and matrixV() which just return a reference to the protected member variables of Eigen::SVDBase that hold the actual matrices.

    However, you are still copying data, but explicitly: you copy the two matrices from the local variable svd into member variables of Foo. If you do not need to modify the U and V matrices in-place, you could store the whole svd in Foo, like so:

    class Foo {
        public:
            JacobiSVD svd;
            Foo(const Ref<const MatrixXcd>& mat);
    };
    
    Foo::Foo(const Ref<const MatrixXcd>& mat):
        svd(mat,  Eigen::ComputeFullU | Eigen::ComputeFullV) {
        // proceed to do other things
    }
    

    Unfortunately, you can't modify the member variables of svd. So if you really need to modify them, and don't need the original values, then your code is fine as it is.