避免矩阵复制构造函数

Avoid Matrix copy constructor

我遇到这样的情况:

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>
}

我认为上面在 matrixUmatrixV 的构造过程中创建了 svd.matrixU()svd.matrixV() 的副本。这是真的吗,有什么办法可以避免吗?

谢谢!

matrixUmatrixV 的构建过程中没有创建临时副本。 Eigen::JacobiSVD 继承自 Eigen::SVDBase,它定义了成员函数 matrixU()matrixV() 只是 return 对 的引用 保存实际矩阵的 Eigen::SVDBase 的受保护成员变量。

但是,你还是在拷贝数据,但是显式的:你将局部变量svd中的两个矩阵拷贝到Foo的成员变量中。如果您不需要就地修改 U 和 V 矩阵,您可以将整个 svd 存储在 Foo 中,如下所示:

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
}

很遗憾,您不能修改svd的成员变量。所以如果你真的需要修改它们,而不需要原始值,那么你的代码就可以了。