How to obtain local variables in functions for nlsolve or minimize

I was wondering what is the best practice to export local variables in a objective function for optimization or linear solvers. For example, I have a function that like:

function example(x)
    b = sum(x)
    return b * x' * x

then I send this function to a minimizer. Assume it converges. I would like to obtain the value of b in the last iteration. How can I achieve that?

I have several tentative solutions in mind:

  • globalize b with const affix (wrap it with an array container).
  • Add a flag argument to indicate whether to output b, then run the function again with the indicator.
  • Take a mutable container of b as an argument and modify it as the side effect of the function.

My understanding is, global variables have performance issues so I should try to avoid; the second approach is sure-fire, but it requires additional iteration, which doesn’t sound very efficient (though in most of my application the cost is low enough). I’m currently employing the third method and it works well so far. However, as I’m new to Julia, I’m not sure whether it has some hidden issues (e.g., compatibility with other packages like ForwardDiff?).

Thanks for any comment!

I would recommend coding it as

calculate_interim_values(x) = (xx = x' * x, b = sum(x))

calculate_objective(v) = v.xx * v.b

and then optimize the calculate_objective ∘ calculate_interim_values, and then call the latter on the optimal position.

This does require an extra function call, but for most optimization problems that’s not a big deal.

An ideal solution would be optimizer libraries accepting a return value that can carry some kind of extra payload, with the objective being available using an accessor, eg

get_value(x::Real) = x

with the user redefining the latter for arbitrary objects. But this does require a change in the optimization library.