R'的MATLAB风格梯度;s最优

R'的MATLAB风格梯度;s最优,r,performance,optimization,R,Performance,Optimization,我使用Roptimx来优化我的功能。在MATLAB中,我总是写: function[f,g] = calculations(x,otherParameters) % some calculations f=someting g=somethingOther % Here f and g are function and gradient values that fmincon use for optimization 因此,将f和g值提供给fmincon。但是当我使用optimx时,我应该单独

我使用R
optimx
来优化我的功能。在MATLAB中,我总是写:

function[f,g] = calculations(x,otherParameters)
% some calculations
f=someting
g=somethingOther
% Here f and g are function and gradient values that fmincon use for optimization

因此,将
f
g
值提供给
fmincon
。但是当我使用
optimx
时,我应该单独提供梯度函数。这个要求的缺点是,我有许多计算f的值,然后需要估计g。所以为梯度做单独的函数迫使我计算一些值两次,这在计算上是低效的。请帮助我了解如何以最有效的方式避免R中的此问题(例如,在我看来,生成全局变量不是一个很好的方法)。

请查看
备忘录
包。为了更详细地解释,考虑一个小例子,您可以在R中优化一个函数,在这里您知道DVVIVIVION:

complex.function <- function(x){
  Sys.sleep(3)
}

f <- function(x){
  cat("f",x,"\n")
  complex.function(x)
  (x-1)^4+(x-1)^2+7
}

g <- function(x){
  cat("g",x,"\n")
  complex.function(x)
  4*(x-1)^3+2*(x-1)
}

system.time(optim(3.1, f, g,method="BFGS")) ##57.01sec
#f 3.1 
#g 3.1 
#f -38.144 
#f -5.1488 
#f 1.45024 
#g 1.45024 
#f 1.398015 
#g 1.398015 
#f 1.146116 
#g 1.146116 
#f 0.8414061 
#f 1.085174 
#g 1.085174 
#f 1.00532 
#g 1.00532 
#f 1.000081 
#g 1.000081 
#f 0.9999192 
#f 1.000048
并减少复杂函数的调用次数,因此我的计算机上的执行时间从57秒减少到36秒


查看
optim
的帮助文件,查看您感兴趣的方法是否实际使用了导数-如果没有,这一切都是一个没有实际意义的问题。

nloptr包允许您将目标函数和梯度作为两部分列表返回。请参见小插曲中的示例:此处重复:

library(nloptr)

eval_f_list <- function(x) {
  common <- x[2] - x[1] * x[1]
  return( list(objective = 100 * common^2 + (1 - x[1])^2,
               gradient = c(-400 * x[1] * common - 2 * (1 - x[1]), 200 * common)))
}
x0 <- c( -1.2, 1 )
opts <- list("algorithm" = "NLOPT_LD_LBFGS", "xtol_rel" = 1.0e-8)

res <- nloptr( x0=x0, eval_f=eval_f_list, opts=opts)
库(nloptr)
评估清单
library(nloptr)

eval_f_list <- function(x) {
  common <- x[2] - x[1] * x[1]
  return( list(objective = 100 * common^2 + (1 - x[1])^2,
               gradient = c(-400 * x[1] * common - 2 * (1 - x[1]), 200 * common)))
}
x0 <- c( -1.2, 1 )
opts <- list("algorithm" = "NLOPT_LD_LBFGS", "xtol_rel" = 1.0e-8)

res <- nloptr( x0=x0, eval_f=eval_f_list, opts=opts)