簡體   English   中英

Rcpp 麻煩從 R package 'numDeriv' 導入 'hessian'

[英]Rcpp trouble importing 'hessian' from R package 'numDeriv'

我正在嘗試構建一個 package,它使用 package 'numDeriv' 中的 function 'hessian'。 但是,當我構建 package 並運行代碼時,出現錯誤

無法將 object 轉換為環境:[type=character; 目標 = ENVSXP]。

下面的示例簡化 Rcpp 代碼

#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
#include <stdio.h> 
#include<armadillo>
using namespace Rcpp;
using namespace std;


double testfunc(double X){

  return pow(X+1,2);

}


double hessian_rcpp(double X){

  Rcpp::Environment numDeriv("package:numDeriv");
  Rcpp::Function hessian = numDeriv["hessian"];

  Rcpp::List hessian_results = hessian(
  Rcpp::_["func"] = Rcpp::InternalFunction(testfunc), 
    Rcpp::_["x"] = X);

  arma::vec out = Rcpp::as<arma::vec>(hessian_results[0]);

  return out[0];
}

// [[Rcpp::export]]
double returnhess(double X){

  double out = hessian_rcpp(X);

  return out;

}

然后在構建 package 后運行以下 R 代碼導致錯誤。

library(test)
returnhess(X=3)
Error in returnhess(X = 3) : 
Cannot convert object to an environment: [type=character; target=ENVSXP].

我的命名空間是

useDynLib(test, .registration=TRUE)
importFrom(Rcpp, evalCpp)
exportPattern("^[[:alpha:]]+")

我的描述是

Package: test
Type: Package
Title: What the Package Does (Title Case)
Version: 0.1.0
Author: Who wrote it
Maintainer: The package maintainer <yourself@somewhere.net>
Description: More about what it does (maybe more than one line) Use four spaces when indenting paragraphs within the Description.
License: What license is it under?
Imports: Rcpp, RcppArmadillo, numDeriv
LinkingTo: Rcpp, RcppArmadillo, numDeriv
Encoding: UTF-8
LazyData: true

我的R版本是3.5.1,RStudio版本是1.1.456,Rcpp版本是0.12.19,RcppArmadillo版本是0.9.100.5.0,numDeriv版本是2016.8.1。 我的操作系統是 windows 10。

我能夠使用類似的方法從 R package 'stats' 成功導入 'optimize'。 下面的示例簡化代碼

#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
#include <stdio.h> 
#include<armadillo>
using namespace Rcpp;
using namespace std;

  double testfunc(double X){

  return pow(X+1,2);

}

double optim_rcpp(){

  Rcpp::Environment stats("package:stats");
  Rcpp::Function optimize = stats["optimize"];

  Rcpp::List opt_results = optimize(
  Rcpp::_["f"] = Rcpp::InternalFunction(testfunc), 
  Rcpp::_["lower"] = -10, 
  Rcpp::_["upper"] =  10);

  arma::vec out = Rcpp::as<arma::vec>(opt_results[0]);

  return out[0];
}

// [[Rcpp::export]]
double returnoptim(){

  double out = optim_rcpp();

  return out;

}

與上面相同的 NAMESPACE 和 DESCRIPTION

然后運行以下 R 代碼即可

returnoptim()
[1] -1

作為解決方法,您可以添加

 Depends:numDeriv

根據您的DESCRIPTION 這樣可以確保將numDeriv軟件包與您的軟件包一起加載。

順便說一句:我將避免using namespace Rcpp; 在一個包裝中。 而且我永遠也不會使用using namespace std; 我想不出使用#include <stdio.h>的充分理由,並且在使用RcppArmadilloRcppArmadillo使用#include<armadillo>

除了@RalfStubner 的回答,我還想指出以下幾點。 Rcpp::Environment 命名空間有一個 function namespace_env("the_package_name")。 這為您提供了與 R 的方法 packagename::package_functionX(...) 相同的功能。 結合您的 DESCRIPTION 文件中的 Depends 或 Imports,您就安全了。 基於它,您可以進行以下操作:

#include <iostream>
// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>


double testfunc(double X){
  
  return std::pow(X+1,2);
  
}

double optim_rcpp(){
  
  Rcpp::Environment stats =  Rcpp::Environment::namespace_env("stats");
  Rcpp::Function optimize = stats["optimize"];
  
  Rcpp::List opt_results = optimize(
    Rcpp::_["f"] = Rcpp::InternalFunction(testfunc), 
    Rcpp::_["lower"] = -10, 
    Rcpp::_["upper"] =  10);
  
  arma::vec out = Rcpp::as<arma::vec>(opt_results[0]);
  
  return out[0];
}

// [[Rcpp::export]]
double returnoptim(){
  
  return optim_rcpp();
}

/*** R
 returnoptim() # -1
*/

要直接回答@mike 的問題,您也可以這樣做:

#include <iostream>
// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>


double testfunc(double X){
  
  return std::pow(X+1,2);
  
}

double hessian_rcpp(double X){
  
  Rcpp::Environment numDeriv =  Rcpp::Environment::namespace_env("numDeriv");
  Rcpp::Function hessian = numDeriv["hessian"];
  
  Rcpp::List hessian_results = hessian(
    Rcpp::_["func"] = Rcpp::InternalFunction(testfunc), 
    Rcpp::_["x"] = X);
  
  arma::vec out = Rcpp::as<arma::vec>(hessian_results[0]);
  
  return out[0];
}


// [[Rcpp::export]]
double returnhess(double X){
  
  return hessian_rcpp(X);
}

/*** R
 returnhess(X=3) # 2
*/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM