假设我有一个名为A
的MatrixXcf
。我想用相对于每列的对应元素规范化替换每列的元素。我编写了以下代码,但是它是错误的!
for (int i = 0; i < A.cols(); i++)
A.col(i).real.array() = A.col(i).real().array()/A.col(i).real().norm();
还有一个问题,Eigen
中的 norm()
,normalize()
和normalized()
有什么区别?
首先,您可以使用 normalize
就地规范化,因此您的代码应该是:
for (int i = 0; i < A.cols(); i++)
A.col(i).normalize();
其次:
normalize
- 在原位置上对已知于编译时的向量(指在编译时就确定为向量的向量)进行归一化处理,不返回任何值。normalized
- 将归一化后的向量作为一个新构造的副本返回,不影响原向量。您可以使用它赋值 - Vector normCopy = vect.normalized()
。norm
- 返回矩阵的范数值。即所有矩阵条目平方和的平方根。所以它们之间的区别实际上是它们分别为您返回的内容。
您的问题的答案可以在手册中找到。简要总结如下:
norm()
是Frobenius范数,即各分量平方和的平方根。
.normalized()
返回原始对象除以此范数的副本(即原始对象未更改)。
.normalize()
将对象就地按此范数除以(即原始对象本身被修改)。
通过这个例子,您可以自行验证:
#include <Eigen/Eigen>
#include <iostream>
int main()
{
Eigen::VectorXd A(3);
A(0) = 1.;
A(1) = 2.;
A(2) = 3.;
std::cout << "A.norm() = " << std::endl;
std::cout << A.norm() << std::endl;
Eigen::VectorXd B = A.normalized();
std::cout << "B = " << std::endl;
std::cout << B << std::endl;
std::cout << "A = " << std::endl;
std::cout << A << std::endl;
A.normalize();
std::cout << "A = " << std::endl;
std::cout << A << std::endl;
}
我使用以下内容进行编译:
clang++ `pkg-config --cflags eigen3` so.cpp
但这因系统而异。
输出结果:
A.norm() =
3.74166
B =
0.267261
0.534522
0.801784
A =
1
2
3
A =
0.267261
0.534522
0.801784