r - Sum in groups with RcppParallel -
i have written function desirably sums values in groups. takes 2 vectors of same length: v , g , should return vector of length same unique elements in g. groups encoded integers starting zero. using rcpp::sourcecpp code compiles when called r (sg(runif(6), rep(0:1,each = 3)) example) returns numeric(0).
// [[rcpp::depends(rcppparallel)]] #include <rcpp.h> #include <rcppparallel.h> using namespace rcpp; using namespace rcppparallel; struct sumsingroups: public worker { const rvector<double> v; const rvector<int> g; rvector<double> s; sumsingroups(const numericvector v, const integervector g, numericvector s): v(v), g(g), s(s) {} sumsingroups(const sumsingroups& p, split): v(p.v), g(p.g), s(p.s) {} void operator()(std::size_t begin, std::size_t end) { (std::size_t = begin; < end; ++i) { if (s[g[i]] != s[g[i]]) s[g[i]] = v[i]; else s[g[i]] += v[i]; } } void join(const sumsingroups& rhs) { for(std::size_t = 0; < s.length(); i++) { s[i] += rhs.s[i]; } } }; // [[rcpp::export]] rvector<double> sg(numericvector v, integervector g) { numericvector s; sumsingroups p(v, g, s); parallelreduce(0, v.length(), p); return p.s; } i new rcppparallel comments , suggestions welcomed.
you need initialize s. suggest initializing zeroes. here code worked me. note since initialize zeroes, not need checking in operator ().
#include <rcpp.h> using namespace rcpp; // [[rcpp::depends(rcppparallel)]] #include <rcppparallel.h> using namespace rcpp; using namespace rcppparallel; struct sumsingroups: public worker { const rvector<double> v; const rvector<int> g; rvector<double> s; sumsingroups(const numericvector v, const integervector g, numericvector s): v(v), g(g), s(s) {} sumsingroups(const sumsingroups& p, split): v(p.v), g(p.g), s(p.s) {} void operator()(std::size_t begin, std::size_t end) { (std::size_t = begin; < end; ++i) { s[g[i]] += v[i]; } } void join(const sumsingroups& rhs) { for(std::size_t = 0; < s.length(); i++) { s[i] += rhs.s[i]; } } }; // [[rcpp::export]] rvector<double> sg(numericvector v, integervector g) { numericvector s(*std::max_element(g.begin(), g.end()) + 1); sumsingroups p(v, g, s); parallelreduce(0, v.length(), p); return p.s; } /*** r set.seed(101) o <- runif(15) <-sample(0:3,15, rep = true) sg(o, i) tapply(o, i, sum) */
Comments
Post a Comment