我遇到这样的情况:
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>
}
我认为以上内容在构造svd.matrixU()
和svd.matrixV()
时创建了matrixU
和matrixV
的副本。这是真的吗,有什么办法可以避免?
谢谢!
答案 0 :(得分:4)
在构造matrixU
和matrixV
时不会创建任何临时副本。 Eigen::JacobiSVD
继承自Eigen::SVDBase
,后者定义了成员函数matrixU()
和matrixV()
,它们只是向受{{1 }},其中包含实际矩阵。
但是,您仍在复制数据,但要明确地:将两个矩阵从局部变量Eigen::SVDBase
复制到svd
的成员变量中。如果不需要就地修改U和V矩阵,则可以将整个Foo
存储在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
}
的成员变量。因此,如果您确实需要修改它们,并且不需要原始值,那么您的代码就可以了。