在 R 中调用 Rcpp 函数
call Rcpp function in R
下面是 R 代码,其中引用了 dll 中的函数 stl_example_model 和 stl_example_jacobian。
library(RcppSundials)
library(microbenchmark)
stl_example_model = getNativeSymbolInfo(name = "example_model_stl",
PACKAGE = "RcppSundials")$address
stl_example_jacobian = getNativeSymbolInfo(name = "example_jacobian_stl",
PACKAGE = "RcppSundials")$address
simulationstl = wrap_cvodes(times = 1:5,
states_ = rep(1.0,5),
parameters_ = 0.1,
forcings_data_ =list(cbind(1:3600,1:3600)),
...,
model_ = example_model, jacobian_ = example_jacobian)
我使用 Rcpp::sourceCpp 获取了另一个函数 (test.cpp)。如何使用 Rcpp 引用此函数(类似于 stl_example_model)?
Test.cpp
#define ARMA_DONT_USE_CXX11
#include <RcppArmadillo.h>
#include <Rcpp.h>
#include <array>
#include <vector>
using namespace std;
using namespace Rcpp;
extern "C" {
array<vector<double>, 2> example_model_stl(const double& t, const vector<double>& states,
const vector<double>& parameters, const vector<double>& forcings) {
vector<double> derivatives(states.size());
for(int i = 0; i < states.size(); i++) {
derivatives[i] = -states[i]*parameters[0];
}
vector<double> observed{forcings[0]};
array<vector<double>, 2> output{derivatives, observed};
return output;
}
arma::mat example_jacobian_stl(const double& t, const vector<double>& states,
const vector<double>& parameters, const vector<double>& forcings) {
arma::mat output = arma::eye(states.size(), states.size());
output = -parameters[0]*output;
return output;
}
array<vector<double>, 2> example_dae_stl(const double& t, const vector<double>& states,
const vector<double>& derivatives, const vector<double>& parameters,
const vector<double>& forcings) {
vector<double> residues(states.size());
residues[0] = -0.04*states[0] + 1e4*states[1]*states[2];
residues[1] = -residues[0] - 3e7*states[1]*states[1] - derivatives[1];
residues[0] = residues[0] - derivatives[0];
residues[2] = states[0] + states[1] + states[2] - 1.0;
vector<double> observed{forcings[0]};
array<vector<double>, 2> output{residues, observed};
return output;
}
};
使用 Dirk 在评论中提到的包确实很有意义。然而,这并不是绝对必要的。
getNativeSymbols
的PACKAGE
参数实际上是可选的。如果省略则搜索所有已加载的 DLL。
编译您的示例会产生警告
No Rcpp::export attributes or RCPP_MODULE declarations found in source
因此,生成的 DLL 未加载到 R 的内存中。您可以通过添加导出的虚拟函数来更改此设置。
示例:
// [[Rcpp::depends("RcppArmadillo")]]
#define ARMA_DONT_USE_CXX11
#include <RcppArmadillo.h>
#include <array>
#include <vector>
using namespace std;
using namespace Rcpp;
extern "C" {
array<vector<double>, 2> example_model_stl(const double& t, const vector<double>& states,
const vector<double>& parameters, const vector<double>& forcings) {
vector<double> derivatives(states.size());
for(int i = 0; i < states.size(); i++) {
derivatives[i] = -states[i]*parameters[0];
}
vector<double> observed{forcings[0]};
array<vector<double>, 2> output{derivatives, observed};
return output;
}
arma::mat example_jacobian_stl(const double& t, const vector<double>& states,
const vector<double>& parameters, const vector<double>& forcings) {
arma::mat output = arma::eye(states.size(), states.size());
output = -parameters[0]*output;
return output;
}
array<vector<double>, 2> example_dae_stl(const double& t, const vector<double>& states,
const vector<double>& derivatives, const vector<double>& parameters,
const vector<double>& forcings) {
vector<double> residues(states.size());
residues[0] = -0.04*states[0] + 1e4*states[1]*states[2];
residues[1] = -residues[0] - 3e7*states[1]*states[1] - derivatives[1];
residues[0] = residues[0] - derivatives[0];
residues[2] = states[0] + states[1] + states[2] - 1.0;
vector<double> observed{forcings[0]};
array<vector<double>, 2> output{residues, observed};
return output;
}
};
// [[Rcpp::export]]
void dummy() {}
/***R
getNativeSymbolInfo("example_model_stl")$address
*/
输出:
> Rcpp::sourceCpp('58881676.cpp')
> getNativeSymbolInfo("example_model_stl")$address
<pointer: 0x7fd438ed5f80>
attr(,"class")
[1] "NativeSymbol"
这样应该可以将这些函数与 RcppSundials 一起使用。
下面是 R 代码,其中引用了 dll 中的函数 stl_example_model 和 stl_example_jacobian。
library(RcppSundials)
library(microbenchmark)
stl_example_model = getNativeSymbolInfo(name = "example_model_stl",
PACKAGE = "RcppSundials")$address
stl_example_jacobian = getNativeSymbolInfo(name = "example_jacobian_stl",
PACKAGE = "RcppSundials")$address
simulationstl = wrap_cvodes(times = 1:5,
states_ = rep(1.0,5),
parameters_ = 0.1,
forcings_data_ =list(cbind(1:3600,1:3600)),
...,
model_ = example_model, jacobian_ = example_jacobian)
我使用 Rcpp::sourceCpp 获取了另一个函数 (test.cpp)。如何使用 Rcpp 引用此函数(类似于 stl_example_model)?
Test.cpp
#define ARMA_DONT_USE_CXX11
#include <RcppArmadillo.h>
#include <Rcpp.h>
#include <array>
#include <vector>
using namespace std;
using namespace Rcpp;
extern "C" {
array<vector<double>, 2> example_model_stl(const double& t, const vector<double>& states,
const vector<double>& parameters, const vector<double>& forcings) {
vector<double> derivatives(states.size());
for(int i = 0; i < states.size(); i++) {
derivatives[i] = -states[i]*parameters[0];
}
vector<double> observed{forcings[0]};
array<vector<double>, 2> output{derivatives, observed};
return output;
}
arma::mat example_jacobian_stl(const double& t, const vector<double>& states,
const vector<double>& parameters, const vector<double>& forcings) {
arma::mat output = arma::eye(states.size(), states.size());
output = -parameters[0]*output;
return output;
}
array<vector<double>, 2> example_dae_stl(const double& t, const vector<double>& states,
const vector<double>& derivatives, const vector<double>& parameters,
const vector<double>& forcings) {
vector<double> residues(states.size());
residues[0] = -0.04*states[0] + 1e4*states[1]*states[2];
residues[1] = -residues[0] - 3e7*states[1]*states[1] - derivatives[1];
residues[0] = residues[0] - derivatives[0];
residues[2] = states[0] + states[1] + states[2] - 1.0;
vector<double> observed{forcings[0]};
array<vector<double>, 2> output{residues, observed};
return output;
}
};
使用 Dirk 在评论中提到的包确实很有意义。然而,这并不是绝对必要的。
getNativeSymbols
的PACKAGE
参数实际上是可选的。如果省略则搜索所有已加载的 DLL。编译您的示例会产生警告
No Rcpp::export attributes or RCPP_MODULE declarations found in source
因此,生成的 DLL 未加载到 R 的内存中。您可以通过添加导出的虚拟函数来更改此设置。
示例:
// [[Rcpp::depends("RcppArmadillo")]]
#define ARMA_DONT_USE_CXX11
#include <RcppArmadillo.h>
#include <array>
#include <vector>
using namespace std;
using namespace Rcpp;
extern "C" {
array<vector<double>, 2> example_model_stl(const double& t, const vector<double>& states,
const vector<double>& parameters, const vector<double>& forcings) {
vector<double> derivatives(states.size());
for(int i = 0; i < states.size(); i++) {
derivatives[i] = -states[i]*parameters[0];
}
vector<double> observed{forcings[0]};
array<vector<double>, 2> output{derivatives, observed};
return output;
}
arma::mat example_jacobian_stl(const double& t, const vector<double>& states,
const vector<double>& parameters, const vector<double>& forcings) {
arma::mat output = arma::eye(states.size(), states.size());
output = -parameters[0]*output;
return output;
}
array<vector<double>, 2> example_dae_stl(const double& t, const vector<double>& states,
const vector<double>& derivatives, const vector<double>& parameters,
const vector<double>& forcings) {
vector<double> residues(states.size());
residues[0] = -0.04*states[0] + 1e4*states[1]*states[2];
residues[1] = -residues[0] - 3e7*states[1]*states[1] - derivatives[1];
residues[0] = residues[0] - derivatives[0];
residues[2] = states[0] + states[1] + states[2] - 1.0;
vector<double> observed{forcings[0]};
array<vector<double>, 2> output{residues, observed};
return output;
}
};
// [[Rcpp::export]]
void dummy() {}
/***R
getNativeSymbolInfo("example_model_stl")$address
*/
输出:
> Rcpp::sourceCpp('58881676.cpp')
> getNativeSymbolInfo("example_model_stl")$address
<pointer: 0x7fd438ed5f80>
attr(,"class")
[1] "NativeSymbol"
这样应该可以将这些函数与 RcppSundials 一起使用。