受到文章的启发http://gallery.rcpp.org/articles/parallel-distance-matrix/ http://gallery.rcpp.org/articles/parallel-distance-matrix/,我尝试使用 RcppParallel 在高维参数空间中运行强力搜索,以便使用多线程进行回溯测试。我陷入了如何调用自定义函数的困境struct
部分。这个想法是这样的:
首先,创建参数矩阵NumericMatrix params_mat
首先在 R 中,并使用回测数据List, NumericVector, CharacterVector
数据类型,例如List Data_1, NumericVector Data_2, CharacterVector Data_3, ...
,对于每个参数场景都是静态的params_vec
(注意,这是一行params_mat
).
接下来,定义回测函数,输出由 3 个关键变量组成的向量来评估策略性能。
这是我的一个例子params_mat
and Backtesting_Fun
可以分别在 R 和 Rcpp 中运行。
//[[Rcpp::export]]
NumericMatrix data_frame_rcpp(const Rcpp::List& list_params)
{
NumericMatrix res = list_params[0];
return res;
}
# R codes to generate params_mat
params <- expand.grid (x_1=seq(1,100,1), x_2=seq(3,100,2), ..., x_n=seq(4,200,1));
list_params = list(ts(params));
tmp_params_data = data_frame_rcpp(list_params);
params_mat = matrix(tmp_params_data, ncol = ncol(tmp_params_data), dimnames = NULL);
params_vec = params_mat[ii,];
# User-defined Rcpp codes for backtesting
NumericVector Backtesting_Fun (List Data_1, NumericVector Data_2, CharacterVector Data_3, ..., NumericVector params_vec)
{
// Main function parts to run backtesting for each params_vec scenario.
... etc
// save 3 key result variables together with each params_vec (just a simple illustration).
NumericVector res = NumericVector::create(params_vec[0],...,params_vec[size-1],
key_1, key_2, key_3);
return res;
}
当然我们需要重写/修改原来的RcppBacktesting_Fun
与 RVector/RMatrix 类型,然后使用以下RcppParallel
调用代码Backtesting_Fun
in struct Backtest_parallel
:
// [[Rcpp::depends(RcppParallel)]]
#include <RcppParallel.h>
using namespace RcppParallel;
RVector<double> Backtesting_Fun (const RVector<double> Data_1, const RVector<double> Data_2,
const RVector<string> Data_3,..., const RVector<double> params_vec)
{
// Main function parts to run backtesting for each params_vec scenario.
... etc;
// save 3 key result variables together with each params_vec
... etc;
return res;
}
struct Backtest_parallel : public Worker
{
// input matrix to read from
const RVector<List> Data_1;
const RVector<double> Data_2;
const RVector<string> Data_3;
...
const RMatrix<double> params_mat;
// output matrix to write to
RMatrix<double> rmat;
// initialize from Rcpp input and output matrixes (the RMatrix class
// can be automatically converted to from the Rcpp matrix type)
Backtest_parallel(const List Data_1, const NumericVector Data_2,
const CharacterVector Data_3, ..., const NumericMatrix params_mat)
: Data_1(Data_1), Data_2(Data_2), Data_3(Data_3), ..., params_mat(params_mat) {}
// function call operator that work for the specified range (begin/end)
void operator()(std::size_t begin, std::size_t end)
{
for (std::size_t ii = begin; ii < end; i++)
{
// params rows that we will operate on
RMatrix<double>::Row params_row = params_mat.row(ii);
// Run the backtesting function defined above
RVector<double> res = Backtesting_Fun(Data_1, Data_2, ..., params_row)
for (std::size_t jj = 0; jj < res.length(); jj++)
{
// write to output matrix
rmat(ii,jj) = res[jj];
}
}
}
};
// [[Rcpp::export]]
NumericMatrix rcpp_parallel_backtest(List Data_1, NumericVector Data_2, CharacterVector Data_3,
..., NumericMatrix params_mat)
{
// allocate the matrix we will return
NumericMatrix rmat(params_mat.nrow(), params_mat.nrow()+3);
// create the worker
Backtest_parallel backtest_parallel(Data_1, Date_2, ..., params_mat);
// call it with parallelFor
parallelFor(0, rmat.nrow(), backtest_parallel);
return rmat;
}
这是我的问题:
Can RVector
包含List
数据类型,或者是否有任何特定的容器RcppParallel
包含装有List
;
In the Backtesting_Fun
,输入应该是RVector/RMatrix
类型,这是否意味着我们真的需要将原始 Rcpp 主代码转换为NumericVector
into RVector
?
或者有没有更好的方法可以在 RcppParallel 中为我的情况进行并行计算?提前致谢。
EDIT:
我查看了有关 RcppParallel 的其他示例http://gallery.rcpp.org/articles/parallel-matrix-transform/ http://gallery.rcpp.org/articles/parallel-matrix-transform/, http://gallery.rcpp.org/articles/parallel-inner-product/ http://gallery.rcpp.org/articles/parallel-inner-product/,共同的想法是struct operator()
是使用指针来操作数据输入operator()
,那么在我的例子中,有没有办法使用指针输入构建用户定义的函数?
如果以上方法不行的话是否可以使用wrap
转换RVector/RMatrix
返回 Rcpp 数据类型,即NumericVector..
in operator()
这样用户定义函数的输入类型Backtesting_Fun
可以保持不变。