简体   繁体   English

在 R 中调用 Rcpp function

[英]call Rcpp function in R

below is the R code where functions stl_example_model and stl_example_jacobian in a dll are referenced.下面是 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) 

I have sourced another function (test.cpp) using the Rcpp::sourceCpp.我使用 Rcpp::sourceCpp 采购了另一个 function (test.cpp)。 How do I a make a reference to this function (similar to stl_example_model) using Rcpp?如何使用 Rcpp 引用此 function(类似于 stl_example_model)?

Test.cpp测试.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;
  }

};

It does make a lot of sense to use a package as mentioned by Dirk in the comments.正如 Dirk 在评论中提到的那样,使用 package 确实很有意义。 However, it is not strictly necessary.但是,这不是绝对必要的。

  1. The PACKAGE argument of getNativeSymbols is actually optional. getNativeSymbolsPACKAGE参数实际上是可选的。 All loaded DLLs are searched if it is omitted.如果省略,则搜索所有加载的 DLL。

  2. Compiling your example produces the warning编译您的示例会产生警告

    No Rcpp::export attributes or RCPP_MODULE declarations found in source在源代码中找不到 Rcpp::export 属性或 RCPP_MODULE 声明

    As a consequence the produced DLL is not loaded into R's memory.因此,生成的 DLL 未加载到 R 的 memory 中。 You can change this by adding an exported dummy function.您可以通过添加导出的虚拟 function 来更改此设置。

Example:例子:

// [[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
*/

Output: Output:

> Rcpp::sourceCpp('58881676.cpp')

> getNativeSymbolInfo("example_model_stl")$address
<pointer: 0x7fd438ed5f80>
attr(,"class")
[1] "NativeSymbol"

This way it should be possible to use such functions together with RcppSundials.这样,应该可以将这些功能与 RcppSundials 一起使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM