C++ Armadillo:获取向量中元素的等级
C++ Armadillo: Get the ranks of the elements in a vector
假设我有一个向量,我想获取元素排序后的排名。
所以如果我有向量:
0.5
1.5
3.5
0.1
我需要返回每个元素的行列:
2
3
4
1
有没有办法在犰狳中做到这一点?这与之前的 post 不同,因为我们在排序之前获得排名而不是索引。
在这里,检查一下:
#include<iostream>
#include<vector> // std:: vector
#include <algorithm> // std::sort
#include <map> // std::map
using namespace std;
int main() {
vector<double> myVector = { 0.5, 1.5, 3.5, 0.1 };
vector<double> Sorted = myVector;
std::sort(Sorted.begin(), Sorted.end());
map<double, int> myMap;
for (int i = 0; i < Sorted.size() ; i++)
{
myMap.insert(make_pair(Sorted[i],i));
}
for (int i = 0; i < myVector.size() ; i++)
{
auto it = myMap.find(myVector[i]);
cout << it->second + 1 << endl;
}
return 0;
};
输出:
这是我使用STL以简洁的方式获得排名的代码
template <typename T>
vector<size_t> calRank(const vector<T> & var) {
vector<size_t> result(var.size());
//sorted index
vector<size_t> indx(var.size());
iota(indx.begin(),indx.end(),0);
sort(indx.begin(),indx.end(),[&var](int i1, int i2){return var[i1]<var[i2];});
//return ranking
for(size_t iter=0;iter<var.size();++iter){
//it may cause overflow for a really long vector, in practice it should be ok.
result[indx[iter]]=iter+1;
}
return result;
}
这是纯 Armadillo 代码的解决方案,使用函数 arma::sort_index()
。
函数arma::sort_index()
计算排列索引以将给定向量按升序排序。
应用函数arma::sort_index()
两次:
arma::sort_index(arma::sort_index())}
,计算 reverse 置换索引,将向量从升序排序回其原始未排序顺序。元素的秩等于 reverse 排列索引。
下面是 Armadillo 封装在 RcppArmadillo 中的代码,它定义了函数 calc_ranks()
。函数 calc_ranks()
计算向量元素的秩,可以从 R 调用。
#include <RcppArmadillo.h>
using namespace Rcpp;
using namespace arma;
// [[Rcpp::depends(RcppArmadillo)]]
// Define the function calc_ranks(), to calculate
// the ranks of the elements of a vector.
//
// [[Rcpp::export]]
arma::uvec calc_ranks(const arma::vec& da_ta) {
return (arma::sort_index(arma::sort_index(da_ta)) + 1);
} // end calc_ranks
以上代码可以保存到文件calc_ranks.cpp,所以可以在R中使用函数编译Rcpp::sourceCpp()
。
下面是 R 测试函数 calc_ranks()
的代码(在 R 中编译后):
# Compile Rcpp functions
Rcpp::sourceCpp(file="C:/Develop/R/Rcpp/calc_ranks.cpp")
# Create a vector of random data
da_ta <- runif(7)
# Calculate the ranks of the elements
calc_ranks(da_ta)
# Compare with the R function rank()
all.equal(rank(da_ta), drop(calc_ranks(da_ta)))
假设我有一个向量,我想获取元素排序后的排名。
所以如果我有向量:
0.5
1.5
3.5
0.1
我需要返回每个元素的行列:
2
3
4
1
有没有办法在犰狳中做到这一点?这与之前的 post 不同,因为我们在排序之前获得排名而不是索引。
在这里,检查一下:
#include<iostream>
#include<vector> // std:: vector
#include <algorithm> // std::sort
#include <map> // std::map
using namespace std;
int main() {
vector<double> myVector = { 0.5, 1.5, 3.5, 0.1 };
vector<double> Sorted = myVector;
std::sort(Sorted.begin(), Sorted.end());
map<double, int> myMap;
for (int i = 0; i < Sorted.size() ; i++)
{
myMap.insert(make_pair(Sorted[i],i));
}
for (int i = 0; i < myVector.size() ; i++)
{
auto it = myMap.find(myVector[i]);
cout << it->second + 1 << endl;
}
return 0;
};
输出:
这是我使用STL以简洁的方式获得排名的代码
template <typename T>
vector<size_t> calRank(const vector<T> & var) {
vector<size_t> result(var.size());
//sorted index
vector<size_t> indx(var.size());
iota(indx.begin(),indx.end(),0);
sort(indx.begin(),indx.end(),[&var](int i1, int i2){return var[i1]<var[i2];});
//return ranking
for(size_t iter=0;iter<var.size();++iter){
//it may cause overflow for a really long vector, in practice it should be ok.
result[indx[iter]]=iter+1;
}
return result;
}
这是纯 Armadillo 代码的解决方案,使用函数 arma::sort_index()
。
函数arma::sort_index()
计算排列索引以将给定向量按升序排序。
应用函数arma::sort_index()
两次:
arma::sort_index(arma::sort_index())}
,计算 reverse 置换索引,将向量从升序排序回其原始未排序顺序。元素的秩等于 reverse 排列索引。
下面是 Armadillo 封装在 RcppArmadillo 中的代码,它定义了函数 calc_ranks()
。函数 calc_ranks()
计算向量元素的秩,可以从 R 调用。
#include <RcppArmadillo.h>
using namespace Rcpp;
using namespace arma;
// [[Rcpp::depends(RcppArmadillo)]]
// Define the function calc_ranks(), to calculate
// the ranks of the elements of a vector.
//
// [[Rcpp::export]]
arma::uvec calc_ranks(const arma::vec& da_ta) {
return (arma::sort_index(arma::sort_index(da_ta)) + 1);
} // end calc_ranks
以上代码可以保存到文件calc_ranks.cpp,所以可以在R中使用函数编译Rcpp::sourceCpp()
。
下面是 R 测试函数 calc_ranks()
的代码(在 R 中编译后):
# Compile Rcpp functions
Rcpp::sourceCpp(file="C:/Develop/R/Rcpp/calc_ranks.cpp")
# Create a vector of random data
da_ta <- runif(7)
# Calculate the ranks of the elements
calc_ranks(da_ta)
# Compare with the R function rank()
all.equal(rank(da_ta), drop(calc_ranks(da_ta)))