Основываясь на примере здесь Parallel Worker в пространстве имен , я хотел бы использовать указатели функций с Parallel Worker.
Приведенный ниже код выдает ошибку в строках: «не может инициализировать новое значение типа (**) с возвращаемым значением (*)»
ExampleInternal.h
#ifndef ExampleInternal_H
#define ExampleInternal_H
namespace ExampleInternal{
#include <RcppArmadillo.h>
#include <RcppParallel.h>
#include <Rcpp.h>
#include <memory>
double myfuncA(arma::vec vec_in);
double myfuncB(arma::vec vec_in);
typedef double (*funcPtr)(arma::vec);
std::shared_ptr<funcPtr> selectfunc(std::string abc){
if(abc == "A"){
return std::make_shared<funcPtr>(new funcPtr(&ExampleInternal::myfuncA));
}else {
return std::make_shared<funcPtr>(new funcPtr(&ExampleInternal::myfuncB));
}
}
struct PARALLEL_WORKER : RcppParallel::Worker{
const arma::vec &input;
std::shared_ptr<funcPtr> &Ptr;
arma::vec &output;
PARALLEL_WORKER( const arma::vec &input, std::shared_ptr<funcPtr> &Ptr, arma::vec &output);
void operator()(std::size_t begin, std::size_t end);
};
}
#endif
myfuncA.cpp
#include <RcppArmadillo.h>
#include <RcppParallel.h>
#include "ExampleInternal.h"
using namespace arma;
namespace ExampleInternal{
double myfuncA(arma::vec vec_in){
int Len = arma::size(vec_in)[0];
return (vec_in[0] +vec_in[1])/Len;
}
} // Close namespace
myfuncB.cpp
#include <RcppArmadillo.h>
#include <RcppParallel.h>
#include "ExampleInternal.h"
using namespace arma;
namespace ExampleInternal{
double myfuncB(arma::vec vec_in){
int Len = arma::size(vec_in)[0];
return (vec_in[0] +vec_in[1])*Len;
}
} // Close namespace
Parallel_worker.cpp
#include <RcppArmadillo.h>
#include <RcppParallel.h>
#include <random>
#include <memory>
#include "ExampleInternal.h"
using namespace RcppParallel;
using namespace ExampleInternal;
namespace ExampleInternal{
PARALLEL_WORKER::PARALLEL_WORKER(const arma::vec &input, std::shared_ptr<ExampleInternal::funcPtr> &Ptr, arma::vec &output) : input(input), Ptr(Ptr), output(output) {}
void PARALLEL_WORKER::operator()(std::size_t begin, std::size_t end){
std::mt19937 engine(1);
// Create a loop that runs through a selected section of the total Boot_reps
for( int k = begin; k < end; k ++){
engine.seed(k);
arma::vec index = input;
std::shuffle( index.begin(), index.end(), engine);
output[k] = Ptr(index);
}
}
} //Close Namespace
Parallel_func.cpp
#include <RcppArmadillo.h>
#include <RcppParallel.h>
#include <memory>
#include "ExampleInternal.h"
using namespace ExampleInternal;
// [[Rcpp::export]]
arma::vec Parallelfunc(int Len_in, std::string func_letter){
std::shared_ptr<funcPtr> df = ExampleInternal::selectfunc(func_letter);
arma::vec input = arma::regspace(0, 500);
arma::vec output(Len_in);
ExampleInternal::PARALLEL_WORKER parallel_woker(input, df, output);
parallelFor( 0, Len_in, parallel_woker);
return output;
}
Вам также может понадобиться makevars для указания c ++ 11 на mac:
CXX_STD = CXX11
PKG_LIBS += $(shell ${R_HOME}/bin/Rscript -e "RcppParallel::RcppParallelLibs()")