Hi everyone,
I try to solve a model and would like to update the parameters of the model with each iteration.
For instance, I have a function like this:
function solve_GE(par::Pars)
res = zeros(2)
f!(x) = residuals_GE(x, res; par)
initial_x = [1., 1.]
sol = nlsolve(f!, initial_x)
return sol
end
The function residuals_GE
takes two parameters, updates the struct par
, and solves the model given the parameters. Afterward, two residuals are computed that follow from the model’s solution.
My question is whether I can keep the struct par that was computed inside residuals_GE
and reuse it? Intuitively, the previous solution to the model should be closer to the next iteration than the solution that I fed into the model in the very beginning.
Thanks for any pointers!
I think we cannot answer this without knowing more. residuals_GE
is not called directly inside solve_GE
but (I assume) it is called inside nlsolve
. If par
is mutable struct
and residuals_GE
changes par
, then these changes will reflect wherever you have the par
object stored (i.e., you are already updating the parameters). However, if par
is immutable (plain struct
), or residuals_GE
do not mutate it, then things complicate. In this case, if residuals_GE
do not mutate the old par
neither return an updated par
, then there is nothing to do. The new par
value do not escape residuals_GE
. If it returns an updated copy, then nlsolve
would need to be able to deal with this extra return and keep the last par
returned by f!
to return it too.
1 Like
Thank you for your reply and your understanding is accurate. I was using par as an immutable struct combined with the package Setfield.jl
to update variables that are related to the solution. However, using @set! par.x = new_x
withing residuals_GE
did not actually affect par.x
for the next iteration run through nlsolve!
. Then I tried declaring par
as a mutable struct
and instead used par.x = new_x
, which indeed updated the field for the next iteration run through nlsolve!
. Thanks!
Only question: Is that difference in behavior expected between immutable struct + Setfield
or mutable struct + direct assignment
or is that a bug?
That’s expected. Setfield will create a new struct with a changed field, it cannot modify the original struct – you declared that to be immutable after all.
2 Likes
Thanks for the great explanation! Did not think much about how Setfield works, just thought immutable plus Setfield makes it less likely that I mess with the struct by accident.