Reductions是什么?
Eigen中reductions是将matrix或array作为输入,返回一个单一的标量值。最常见的就是sum,他将所有的系数求和结果返回。
#include <iostream>
#include <Eigen/Dense>
using namespace std;
int main()
{
Eigen::Matrix2d mat;
mat << 1, 2,
3, 4;
cout << "Here is mat.sum(): " << mat.sum() << endl;
cout << "Here is mat.prod(): " << mat.prod() << endl;
cout << "Here is mat.mean(): " << mat.mean() << endl;
cout << "Here is mat.minCoeff(): " << mat.minCoeff() << endl;
cout << "Here is mat.maxCoeff(): " << mat.maxCoeff() << endl;
cout << "Here is mat.trace(): " << mat.trace() << endl;
}
Reductions方法 | 含义 |
---|---|
sum | 累加 |
prod | 累乘 |
mean | 均值 |
minCoeff | 最小值 |
maxCoeff | 最大值 |
trace | 矩阵的迹 |
Norm(范数)
关于范数的概念,可以参考这里这里。最常见的就是L1范数和L2范数:
L1范数
∣
∣
x
∣
∣
1
=
∑
i
=
1
n
∣
x
i
∣
||x||_1=\sum_{i=1}^{n}|x_i|
∣∣x∣∣1=i=1∑n∣xi∣
表示向量
x
1
x_1
x1的非零元素绝对值之和。L1范数有很多名字,例如我们熟悉的曼哈顿距离、最小绝对误差等。使用L1范数可以度量两个向量间的差异,如绝对误差和(Sum of Absolute Difference):
S
A
D
=
∑
i
=
1
n
∣
x
1
i
−
x
2
i
∣
SAD=\sum_{i=1}^{n}|x_{1i}-x_{2_i}|
SAD=i=1∑n∣x1i−x2i∣
L2范数
∣
∣
x
∣
∣
1
=
∑
i
=
1
n
(
x
i
2
)
||x||_1=\sqrt{\sum_{i=1}^{n}(x_i^2)}
∣∣x∣∣1=i=1∑n(xi2)
这个是最最最常见的了,表示欧式距离,它表示
x
1
x_1
x1的平方和后开平方。它也可用来表示两个向量之间的差异,如如平方差和(Sum of Squared Difference):
S
S
D
(
x
1
,
x
2
)
=
∑
i
=
1
n
(
x
1
−
x
2
)
2
SSD(x_1,x_2)=\sqrt{\sum_{i=1}^{n}{(x_{1}-x_{2})}^2}
SSD(x1,x2)=i=1∑n(x1−x2)2
回到Eigen,范数可以使用方法norm求得L2范数,比如说两个点之间的距离计算,或者平方和:
#include <Eigen/Dense>
#include <iostream>
using namespace Eigen;
using namespace std;
int main()
{
Vector3f a(0,0,0);
Vector3f b(1,1,1);
std::cout<<(a-b).norm()<<std::endl;
std::cout<<(a-b).squaredNorm()<<std::endl;
}
同样例子,可以计算平方和squaredNorm
使用pNorm<阶数>可以计算任意阶数范数,如阶数=1,求L1范数(绝对和):
#include <Eigen/Dense>
#include <iostream>
using namespace Eigen;
using namespace std;
int main()
{
Vector3f a(0,0,0);
std::cout<<(a-b).lpNorm<1>(a)<<std::endl;
}
三、布尔Reduction
用于比较时调用的方法:
方法 | 含义 |
---|---|
all() | returns true if all of the coefficients in a given Matrix or Array evaluate to true . |
any() | returns true if at least one of the coefficients in a given Matrix or Array evaluates to true . |
count() | returns the number of coefficients in a given Matrix or Array that evaluate to true. |
#include <Eigen/Dense>
#include <iostream>
using namespace std;
using namespace Eigen;
int main()
{
ArrayXXf a(2,2);
a << 1,2,
3,4;
cout << "(a > 0).all() = " << (a > 0).all() << endl;
cout << "(a > 0).any() = " << (a > 0).any() << endl;
cout << "(a > 0).count() = " << (a > 0).count() << endl;
cout << endl;
cout << "(a > 2).all() = " << (a > 2).all() << endl;
cout << "(a > 2).any() = " << (a > 2).any() << endl;
cout << "(a > 2).count() = " << (a > 2).count() << endl;
}
四、Visitor 获得Reduction下标
#include <iostream>
#include <Eigen/Dense>
using namespace std;
using namespace Eigen;
int main()
{
Eigen::MatrixXf m(2,2);
m << 1, 2,
3, 4;
//get location of maximum
MatrixXf::Index maxRow, maxCol;
float max = m.maxCoeff(&maxRow, &maxCol);
//get location of minimum
MatrixXf::Index minRow, minCol;
float min = m.minCoeff(&minRow, &minCol);
cout << "Max: " << max << ", at: " <<
maxRow << "," << maxCol << endl;
cout << "Min: " << min << ", at: " <<
minRow << "," << minCol << endl;
}
五、Partial reductions
Partial reductions就是矩阵的一部分进行reduction。其实就是两个方法:colwise() or rowwise() .
#include <iostream>
#include <Eigen/Dense>
using namespace std;
int main()
{
Eigen::MatrixXf mat(2,4);
mat << 1, 2, 6, 9,
3, 1, 7, 2;
std::cout << "Column's maximum: " << std::endl
<< mat.colwise().maxCoeff() << std::endl;
}
除了最值以外,还可和其他reduction结合:
#include <iostream>
#include <Eigen/Dense>
using namespace std;
using namespace Eigen;
int main()
{
MatrixXf mat(2,4);
mat << 1, 2, 6, 9,
3, 1, 7, 2;
MatrixXf::Index maxIndex;
float maxNorm = mat.colwise().sum().maxCoeff(&maxIndex);
std::cout << "Maximum sum at position " << maxIndex << std::endl;
std::cout << "The corresponding vector is: " << std::endl;
std::cout << mat.col( maxIndex ) << std::endl;
std::cout << "And its sum is is: " << maxNorm << std::endl;
}
六、Broadcasting
这个就是将一个向量应用到某个放下,下面这个例子,就将向量v,按行方向逐元素应用。
#include <iostream>
#include <Eigen/Dense>
using namespace std;
int main()
{
Eigen::MatrixXf mat(2,4);
Eigen::VectorXf v(2);
mat << 1, 2, 6, 9,
3, 1, 7, 2;
v << 0,
1;
//add v to each column of m
mat.colwise() += v;
std::cout << "Broadcasting result: " << std::endl;
std::cout << mat << std::endl;
}