Eigen 是一个不错的线性代数库,提供了一般的矩阵和向量操作,以及诸多数值线性代数的算法。但是,我找了很久没有类似于Matlab的sort函数那样对向量进行排序函数。这里,借助于标准库算法sort,可以实现排序功能。
std::sort的用法有两种:
sort(beg,end)
sort(beg,end,comp)
其中beg表示指向首元素的指针或迭代器,end表示“尾后迭代器”(指向最后一个元素的下一个位置的迭代器)或指向最后一个元素的下一个位置的指针。comp表示一个返回bool值的表达式或者"可调用对象",即谓词。对于sort(beg,end)
版本,默认采用<运算符进行比较。对于sort(beg,end,comp)
,则采用comp中定义的行为规则进行比较。
#include<iostream>
#include<algorithm>
#include<Eigen/Eigen>
using namespace std;
using namespace Eigen;
/**对向量进行排序,从大到小
* vec: 待排序的向量
* sorted_vec: 排序的结果
* ind: 排序结果中各个元素在原始向量的位置
*/
void sort_vec(const VectorXd& vec, VectorXd& sorted_vec, VectorXi& ind){
ind=VectorXi::LinSpaced(vec.size(),0,vec.size()-1);//[0 1 2 3 ... N-1]
auto rule=[vec](int i, int j)->bool{
return vec(i)>vec(j);
};//正则表达式,作为sort的谓词
std::sort(ind.data(),ind.data()+ind.size(),rule);
//data成员函数返回VectorXd的第一个元素的指针,类似于begin()
sorted_vec.resize(vec.size());
for(int i=0;i<vec.size();i++){
sorted_vec(i)=vec(ind(i));
}
}
//测试
int main(){
VectorXd x(5);
x<<3,4,1,5,6;
VectorXi ind;
VectorXd sorted_vec;
sort_vec(x,sorted_vec,ind);
cout<<"原始向量:\n";
cout<<x<<endl<<endl;
cout<<"排序后:\n";
cout<<sorted_vec<<endl<<endl;
cout<<"排序后向量各元素对应的原始向量中的位置"<<endl;
cout<<ind<<endl;
return 0;
}
编译时加上选项: -std=c++11
输出结果为
原始向量:
3
4
1
5
6
排序后:
6
5
4
3
1
排序后向量各元素对应的原始向量中的位置
4
3
1
0
2
References