我使用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中的这个问题(例如,使全局变量看起来不是一个非常好的方法)。
答案 0 :(得分:2)
nloptr包允许将目标函数和渐变作为双组件列表返回。请参阅插图中的示例:https://cran.r-project.org/web/packages/nloptr/vignettes/nloptr.pdf,重复此处:
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)
答案 1 :(得分:1)
查看public async Task help(IDialogContext context, LuisResult result)
{
await Conversation.SendAsync(activity, () => SimpleFacebookAuthDialog.dialog);
}
包。为了更详细地解释,请考虑一个简单的例子,说明如何在R中优化一个你知道存在的函数:
memoise
因为该方法在大多数相同的点评估f和g,所以有可能进行优化。
现在,如果您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
具有复杂计算的函数,它会缓存输出,因此您可以执行以下操作:
memoise()
并减少调用复杂函数的次数,因此我的计算机上的执行时间从57秒减少到36秒。
检查library(memoise)
complex.function2 <- memoise(function(x){
Sys.sleep(3)
list(fun=(x-1)^4+(x-1)^2+7,deriv=4*(x-1)^3+2*(x-1))
})
f2 <- function(x){
cat("f2",x,"\n")
complex.function2(x)$fun
}
g2 <- function(x){
cat("g2",x,"\n")
complex.function2(x)$deriv
}
system.time(optim(3.1, f2, g2,method="BFGS")) ##36.02sec
的帮助文件,看看您感兴趣使用的方法是否实际使用了衍生产品 - 如果没有,这一切都是没有实际意义的。