I need to find a way to write an independent routine to add a particular constraint to a minimization problem in solnl()
With a concrete example, one has this
##### for optimization
library(MASS)
library(NlcOptim)
##############################
###objective function to minimize
objfun=function(x){
return(x[1]^2+x[2]^2+1)
}
### our initial constraint to be improved
constraint = function(x){
f = NULL
f = rbind(f, x[2] - 2)
return(list(ceq = f, c= NULL))
}
#### solve now
x0 = c(1,1)
solnl(x0,objfun=objfun,confun=constraint)
Say that we want to add the new constraint
h(x) = x[1] - 1
which makes the problem easy to solve.
I would like to have a function named add_constraint(h) that would generate the same usable output as
constraint = function(x){
f = NULL
f = rbind(f, x[2] - 2)
f = rbind(f,x[1] - 1 )
return(list(ceq = f, c= NULL))
}
I have tried the following without success
f = paste0("x[1] - 1")
h = paste0("x[2] - 2")
local = rbind(f,h)
# then the routine
add_constraint = function(local){
function(x){
f= NULL
for( i in 1:2)
f = rbind(f, local[i])
return(list(ceq=f, c= NULL))
}
}
constraint = add_constraint(local)
You could add sth in the body
, using str2lang()
since you have strings, and move the return one forward.
> constraint ## old FUN
function(x) {
f <- NULL
f <- rbind(f, x[2] - 2)
return(list(ceq=f, c=NULL))
}
> add_constraint <- \(x) {
+ bd <- body(constraint)
+ rt <- bd[[length(bd)]]
+ bd[[length(bd)]] <- str2lang(x)
+ bd[[length(bd) + 1]] <- rt
+ body(constraint) <- bd
+ constraint
+ }
> constraint <- add_constraint('f <- rbind(f, x[1] - 1)')
> constraint ## new FUN
function (x)
{
f <- NULL
f <- rbind(f, x[2] - 2)
f <- rbind(f, x[1] - 1)
return(list(ceq = f, c = NULL))
}