归约(reduction)就是把一堆数"压缩"成一个数:求和、平均、最大值、范数…… 本章讲所有常用归约,以及按行/列归约。
28.1 全局归约:把矩阵算成一个数
Eigen::MatrixXdm(3,3);m<<1,2,3,4,5,6,7,8,9;m.sum();// 所有元素之和 = 45m.mean();// 平均值 = 5m.prod();// 所有元素乘积 = 362880m.minCoeff();// 最小元素 = 1m.maxCoeff();// 最大元素 = 9m.trace();// 对角线之和 = 15std::cout<<"和 = "<<m.sum()<<std::endl;std::cout<<"平均 = "<<m.mean()<<std::endl;std::cout<<"最小 = "<<m.minCoeff()<<std::endl;std::cout<<"最大 = "<<m.maxCoeff()<<std::endl;28.2 同时拿到最大值和它的位置
Eigen::Index maxRow,maxCol;doublemaxVal=m.maxCoeff(&maxRow,&maxCol);std::cout<<"最大值 "<<maxVal<<" 在 ("<<maxRow<<", "<<maxCol<<")"<<std::endl;传两个索引的地址进去,就能同时得到最大值的位置。
28.3 范数 norm:衡量"大小"
向量的范数就是它的"长度":
Eigen::Vector3dv(3,4,0);v.norm();// L2 范数(长度)= 5v.squaredNorm();// 长度的平方 = 25norm():默认 L2 范数(欧几里得长度),√(3²+4²) = 5squaredNorm():长度的平方,更快(避免开方)
矩阵也有norm()(矩阵范数),但向量范数更常用。
28.4 按行 / 按列归约
colwise()对每一列分别归约,rowwise()对每一行分别归约:
m.colwise().sum();// 每列的和:12 15 18m.rowwise().sum();// 每行的和:6 15 24m.colwise().maxCoeff();// 每列最大值:7 8 9m.rowwise().mean();// 每行平均值std::cout<<"每列和 = "<<m.colwise().sum()<<std::endl;// 12 15 18std::cout<<"每行和 =\n"<<m.rowwise().sum()<<std::endl;// 6; 15; 24这相当于"按列/按行做归约",是数据分析里非常常用的操作。
28.5 逻辑归约:all / any / count
对布尔结果统计:
(m.array()>0).all();// 是否所有元素都 > 0(m.array()>0).any();// 是否存在元素 > 0(m.array()>5).count();// 元素 > 5 的个数std::cout<<"都 > 0? "<<(m.array()>0).all()<<std::endl;// 1std::cout<<"有 > 8? "<<(m.array()>8).any()<<std::endl;// 1std::cout<<"> 4 的个数 = "<<(m.array()>4).count()<<std::endl;// 528.6 完整示例
#include<Eigen/Dense>#include<iostream>intmain(){Eigen::MatrixXdm(3,3);m<<1,2,3,4,5,6,7,8,9;std::cout<<"总和 = "<<m.sum()<<std::endl;std::cout<<"平均 = "<<m.mean()<<std::endl;std::cout<<"最小值 = "<<m.minCoeff()<<std::endl;std::cout<<"最大值 = "<<m.maxCoeff()<<std::endl;std::cout<<"迹 = "<<m.trace()<<std::endl;Eigen::Vector3dv(3,4,0);std::cout<<"向量长度 = "<<v.norm()<<std::endl;// 5std::cout<<"每列和 = "<<m.colwise().sum()<<std::endl;return0;}存成ch28.cpp,按附录 C.3 编译运行,实际输出:
总和 = 45 平均 = 5 最小值 = 1 最大值 = 9 迹 = 15 向量长度 = 5 每列和 = 12 15 18总和 45、平均 5、迹 15(主对角线 1+5+9)都能手算核对;每列和 = 12 15 18对应第一列 1+4+7、第二列 2+5+8、第三列 3+6+9。注意colwise()是"每一列各自算一次",所以三列的和分别落在结果的三个位置上。
28.7 小结
- 全局归约:
sum/mean/prod/minCoeff/maxCoeff/trace。 - 范数:
norm()(长度)、squaredNorm()(长度平方)。 - 按行/列:
rowwise()、colwise()。 - 逻辑归约:
all()/any()/count()。
下一章,学习求解线性方程组——Eigen 最重要的应用之一。
练习题
- 求一个矩阵的总和、平均值、最小、最大、迹。
- 求向量 (3,4) 的 norm 和 squaredNorm。
- 用 colwise 和 rowwise 分别求每列、每行的和。
- 统计矩阵中大于某个阈值的元素个数。
- 用 maxCoeff 同时得到最大值和它的位置。