【问题标题】:Environment in Rcpp [closed]Rcpp中的环境[关闭]
【发布时间】:2015-11-27 17:17:59
【问题描述】:

我正在处理一个涉及使用似然函数 (lik) 及其梯度 (grad) 的优化问题。这两个函数都使用Rcpp 库进行编码,并被馈送到R 中的optim(...,method="BFGS") 优化函数。

在计算似然性的过程中,会产生很多变量,这些变量对于以后的梯度计算也很有用。为了避免每次需要梯度评估时都重新计算这些变量,我想出了创建一个环境 (env) 的想法,lik 使用该环境与grad 进行“通信”。换句话说,每次评估 lik 时,它都会将所需的变量存储到环境 env

likelihoodscript<-
using Rcpp::Environment; 
Environment e(env);
// likelihood function is computed
//var1 to varK are created
//they can be MatrixXd, SparseMatrix, double, etc.
e.assign("namevar1",var1);
e.assign("namevar2",var2);
...
e.assign("namevarK",varK);
return wrap(likvalue);

然后,当需要grad 评估时,我从grad 函数中搜索环境中所需的变量:

gradientscript<-
using Rcpp::Environment; 
Environment e(env);
//var1 to varK are recovered from the environment
SEXP input_var1 = e.get("var1");
int var1 = as<int>(var1);
SEXP input_var2= e.get("var2");
MatrixXd var2 = as<MatrixXd>(var2);
...
SEXP input_varK = e.get("varK");
double varK = as<double>(varK);
// gradient function is computed
return wrap(gradvector);

理论上,如果我用相同的初始参数集开始优化问题,我应该每次都得到相同的结果(likgradoptim() 内部没有随机操作),但碰巧结果有时会有所不同。可以这么说,如果我用完全相同的参数重复优化 20 次,15 次我有很好的结果,但其中 5 次我有一些不同(或非常不同)的东西。我在这些错误中搜索了“模式”,但它们看起来完全是随机的。

据我所知,这可能是由于环境哈希表中的键值识别错误,因此我尝试在 R 中使用 hash 包。一些改进(可能是好结果的 18 倍,而不是15),但还不是问题的确切解决方案。

如果有人知道问题出在哪里,请回答。 非常感谢。

P.D.我尝试了同样的事情,但使用list 而不是Environment:同样的问题,甚至更糟。

【问题讨论】:

  • 您应该提供一个可重现的示例来证明您的问题。

标签: r hash hashtable environment rcpp


【解决方案1】:

如果没有您身边的具体示例,很难说出问题所在。这是我发现的可能是您的代码。也许这对您有所帮助,或者它可以帮助您指出与我的示例不同的地方。 我的代码有效,并且所有使用 cpp 函数的 optim 不同运行都给出了相同的结果。

library(inline)

#Rosenbrock Banana function as in optim examples
#it stores two values in the provided environment
fun_str='using Rcpp::Environment; 
Environment e(env);
NumericVector xx(x);
double a=(xx[1] - xx[0] * xx[0]);
double b=(1.0 - xx[0]);
e.assign("a",a);
e.assign("b",b);
return(wrap(100.0 * pow(a,2.0) + pow(b,2.0)));'

#corresponding gradient
#it accesses the two variables that we have stored above
grad_str='using Rcpp::Environment; 
Environment e(env);
double a=e["a"];
double b=e["b"];
NumericVector xx(x);
NumericVector res(2);
res[0]= -400.0 * xx[0] * a - 2.0 * b;
res[1]=200.0*a;
return(wrap(res));'

#define rcpp functions
fun_cpp=cxxfunction(signature(x="numeric",env = "environment"),
                    fun_str,
                    plugin = "Rcpp")
grad_cpp=cxxfunction(signature(x="numeric",env = "environment"),
                     grad_str,
                     plugin = "Rcpp")

res_vec=list()

#loop through 100 runs of the same BFGS optimization and store results
for (i in 1:100) {
  container_env=new.env()
  res_vec[[length(res_vec)+1]]=optim(par=c(-1.2,1),fn=fun_cpp,gr=grad_cpp,method="BFGS",env=container_env)
}

#compare all results
sum_var=0
for (i in 2:length(res_vec)) sum_var=sum_var+all.equal(res_vec[[i]],res_vec[[i-1]])
sum_var
#99

如您所见,它们都给出了相同的结果。 此外,结果与optim 示例部分中给出的纯 R 代码的结果一致。

【讨论】:

  • 非常感谢cryo111!!我解决了这个问题。最后,出现了一个影响梯度函数评估的问题。与环境、哈希或其他无关。无论如何,谢谢你的代码。证明我走在正确的道路上是有用的,并且应该在其他地方搜索问题。我将报告梯度评估的问题。我现在正在更仔细地检查,但这似乎是一个错误。
猜你喜欢
  • 1970-01-01
  • 2021-08-27
  • 1970-01-01
  • 1970-01-01
  • 2010-12-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-13
相关资源
最近更新 更多