4

我想获得未排序的可变长度特征 c++ vectorXf 对象的 weighted_median。看来我可以使用 boost 的统计累加器库中的 boost weighted_median 函数来有效地做到这一点[?]。

从本质上讲,我正在尝试做一些与 这里所做的非常相似的事情。我不确定 boost 的累加器是这个任务的正确框架(如果不是,请建议!),但我还没有找到另一个现成的 O(n) 加权中位数的实现。

我现在的问题是,是否有办法用更优雅的构造替换下面的“for(int i=0;i<100;i++)”循环?

PS我已经看到了这个SO question,但目前还不清楚如何将答案转化为可操作的解决方案。

#include <Eigen/Dense>
#include <iostream>
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics/stats.hpp>
#include <boost/accumulators/statistics/median.hpp>
#include <boost/accumulators/statistics/weighted_median.hpp>
using namespace boost::accumulators;    
using namespace Eigen;

int main(){
    accumulator_set<float, stats<tag::median > > acc1;
    accumulator_set<float, stats<tag::median >,int> acc2;

    VectorXi rw=VectorXi::Random(100);
    VectorXf rn=VectorXf::Random(100);

    rw=rw.cwiseAbs();
    for(int i=0;i<100;i++){
        acc1(rn(i));
        acc2(rn(i),weight=rw(i));
    }

  std::cout << "         Median: " << median(acc1) << std::endl;
  std::cout << "Weighted Median: " << median(acc2) << std::endl;

  return 0;
}
4

1 回答 1

2

您要做的是使用 boost 累加器在某种容器中累加值。您会注意到,即使传递std::vector<float>给累加器也行不通。累加器根本不应该以这种方式使用。当然,您可以使用累加器来累加向量值或矩阵值 - 但这不是您想要的。

您可以使用std::for_each来摆脱显式循环,仅此而已:

// median
using boost::bind;
using boost::ref;
std::for_each(rn.data(), rn.data()+rn.rows(), bind<void>( ref(acc1), _1 ) );

您链接到的问题在 Eigen3 的最新版本中不再相关。那里给出的代码运行良好并产生正确的结果。

于 2012-06-21T22:54:37.040 回答