我在R中使用nloptr包进行非线性优化。我正在尝试设置一些通用的包装函数,可以根据某些字符在不同的优化问题之间轻松切换。
我试图创建一个我正在解决的问题的简单示例。考虑以下函数(生成包含目标和渐变值的列表),
f_quadratic <- function(x, a1=0) {
list("objective" = a1 * x^2, "gradient" = a1 * 2 * x)
}
f_cubic <- function(x, a1=0, a2=1) {
list("objective" = a1 + a2 * x^3, "gradient" = a2 * 3 * x ^ 2)
}
在它们之间切换的一种方法是(coutresy of @alexis_laz)
f_test <- function(f, ...) {
function(x) {
match.fun(f)(x, ...)
}
}
所以给出
x <- 2
a1 <- 4
a2 <- 3
我可以跑
f <- "f_quadratic"
g <- f_test(f, a1=a1)
g(x)
或
f <- "f_cubic"
g <- f_test(f, a1=a1, a2=a2)
g(x)
并获得结果。 g函数最终会传递给nloptr中的eval_f参数。但是,这不起作用
f <- "f_quadratic"
g <- f_test(f, a1=a1, a2=a2)
g(x)
因为f_quadratic不需要a2。
如何以一种仍与nloptr一起使用的方式对任意输入进行调整?
答案 0 :(得分:1)
另一种方法是创建一个新功能
f_test_2 <- function(f, arg_f) {
function(x) {
do.call(f, c(list(x), arg_f))
}
}
然后运行
arg_f0 <- list(a1 = a1, a2 = a2)
f <- "f_quadratic"
arg_f <- arg_f0[names(arg_f0) %in% names(formals(f))]
g <- f_test_2(f, arg_f)
g(x)
采用这种方法可以获得适度的性能影响,但我的估计显示,对于更复杂的样本问题,它大约为3%。