Eigen - matrix.transpose 会创建矩阵的副本吗?

Eigen - does matrix.transpose create a copy of the matrix?

本文关键字:副本 创建 matrix transpose Eigen      更新时间:2023-10-16

我想使用特征做以下矩阵积:

Eigen::VectorXd vector = Eigen::VectorXd::Random(1000000); // a given long vector
Eigen::MatrixXd product = vector * vector.transpose();

我不确定 Eigen 在调用vector.transpose()或只是视图时会创建矢量的副本。我通过创建一个向量及其转置然后修改原始向量的值来尝试:

Eigen::VectorXd vector(3);
vector << 1, 2, 3;
Eigen::VectorXd vectorTranspose = vector.transpose();
vector(0) = 10;
std::cout << vector << "n"; // shows col vector [10, 2, 3]
std::cout << vectorTranspose << "n"; // still shows col vector [1, 2, 3]
std::cout << vector * vectorTranspose << "n"; // this gives the error of "invalid matrix product"
std::cout << vector * vector.transpose() << "n"; // this gives the correct behavior

所以我的问题是:

  1. 对于形状为 n x 1 的列向量,为什么转置仍然给出列向量而不是行向量?
  2. 调用 vector * vector.transpose((
  3. 是由于创建 vector.transpose(( 而导致浪费还是 Eigen 对此做了一些聪明的事情?

我只想回答第一部分(没有足够的声誉来简单地评论(。

问题是vectorTranspose被声明为VectorXd,它表示一个向量。动态大小行向量代替类型RowVectorXd。请尝试以下操作:

Eigen::VectorXd v(3);
v << 1,2,3;
Eigen::VectorXd wrong = v.transpose();
Eigen::RowVectorXd correct = v.transpose();
std::cout << "v: " << v.rows() << "x" << v.cols() << std::endl;
std::cout << "wrong: " << wrong.rows() << "x" << wrong.cols() << std::endl;
std::cout << "correct: " << correct.rows() << "x" << correct.cols() << std::endl;

应该打印:

v: 3x1
wrong: 3x1
correct: 1x3

Eigen 允许将向量复制到其他向量中,即使它们具有不同的布局,即colVec = rowVec通过将行向量的元素复制到列向量中来工作,而无需更改列向量的布局。列向量的布局不能改变的原因是VectorXd实际上与Matrix<double,Dynamic,1>相同:它必须具有单个列。我相信这种"奇怪"的副本(行到列向量,反之亦然(意味着一种方便。