我想使用特征做以下矩阵积:
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
所以我的问题是:
- 对于形状为 n x 1 的列向量,为什么转置仍然给出列向量而不是行向量? 调用 vector * vector.transpose((
- 是由于创建 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>
相同:它必须具有单个列。我相信这种"奇怪"的副本(行到列向量,反之亦然(意味着一种方便。