2012-06-21 66 views
4

我想獲得一個未排序的變量 長度eigen C++ vectorXf對象的weighted_median。看來我可以使用boost的統計累加器 庫中的weighted_median函數來高效地執行[?]。boost ++ :: weighted_median和eigen :: vectorXf --newbie

從本質上講,我試圖做一些非常相似的事情 here。我不確定助推器的累加器是否適用於此任務(如果不是這樣的話,請指教!),但我還沒有找到另外一個 現成的O(n)加權中值。

我的問題在這一點上是否有一種方法來取代 「for(int i = 0; i < 100; i ++)」循環由更優雅的構造?

P.S.我見過this SO問題,但它不是 真的很清楚如何將答案轉到可操作的解決方案。

#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; 
} 

回答

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)); 

question您鏈接到不相關了在Eigen3最新發布的版本。給出的代碼運行得很好,併產生正確的結果。

+0

我不知道是否有與加權中位數有關的命名參數做同樣乾淨的方式。助力大師請加入。 –