Hi All,
I am looking for some ideas about how others have often handled this issue. Often, I have to solve an optimization problem and then pass out return some additional arguments. In the MWE example below, y is the component to minimized. But I would also like to make a, b, c available outside of the function. How have you folks typically handled this.
using Optim
function test(x)
x = x[]
a = 1
b = 2
c = 3
y = x^2 - 4
#return y^2, a, b, c
return y^2
end
optimize(x -> test(x), [0.5]).minimizer
Edit: was using "pass out arguments" which turned out to be confusing, now using the more accurate "return".
If you have a function test(x,a,b,c), then just do:
optimize(x -> test(x,a,b,c), [0.5]).minimizer
(This is “capturing” the values a,b,c in the closurex -> ... via lexical scoping.)
Or maybe I’m misunderstanding you. Do you want to pass a,b,cintotest, or do you want to return them out of test (e.g. at the location of the optimum x)? As @abraemer says, one option for the latter is just to return additional values and then discard them during optimization; then, after optimization, you can call your function again with the optimum x and get the additional return values.
Thanks this works too! For posterity here is an approach I have used previously.
using Optim
function test(x; run = "solve")
x = x[]
a = 1
b = 2
c = 3
y = x^2 - 4
return run == "solve" ? y^2 : (y^2, a, b, c)
end
# Finding the solution run.
x = optimize(x -> test(x), [0.5]).minimizer
# the simulation run to return additional arguments. note that this simply MWE.
test(x; run = "simulate")
I would recommend against this because it is type-unstable and will slow things down considerably. Just returning extra values and discarding them at the call site should be efficient.