在 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 在评论中提到的包确实很有意义。然而,这并不是绝对必要的。

  1. getNativeSymbolsPACKAGE参数实际上是可选的。如果省略则搜索所有已加载的 DLL。

  2. 编译您的示例会产生警告

    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 一起使用。