DassHydro / smash

An open source, Python library interfacing the Fortran Spatially distributed Modelling and ASsimilation for Hydrology platform.
https://smash.recover.inrae.fr/
GNU General Public License v3.0
12 stars 6 forks source link

Functions to manipulate the control vector and compute cost/log-posterior #301

Open benRenard opened 1 month ago

benRenard commented 1 month ago

For many applications, one needs to pass a function that evaluates the cost (or the log-posterior) from the control vector. For instance:

  1. MCMC sampling: samples=MCMC(logpost_function, starting_point, MCMC_args, **logpost_function_args)
  2. Hessian computation: hess=Hessian(cost_function, evaluation_point, Hessian_args, **cost_function_args)
  3. Using a Python optimizer: optim(cost_function, starting_point, optim_args, **cost_function_args)
  4. etc.

To facilitate this, the following functions would be useful (interfaces are approximate, just to convey the idea):

  1. retrieve the control vector from model and optim/cost options: control=smash.get_control(model,mapping,optimize_options,cost_options)
  2. "unfold" a control vector into model parameters: model.set_control(control,mapping,optimize_options,cost_options)
  3. compute the cost using parameters currently in model: cost=smash.get_cost(model,mapping,optimize_options,cost_options)
  4. compute the jacobian vector dcost/dcontrol using parameters currently in model: jac=smash.get_jacobian(model,mapping,optimize_options,cost_options)
  5. make a forward run from the control vector, and (optionally) retrieve cost and jacobian: model,cost,jacobian=smash.forward_run_from_control(control,model,mapping,optimize_options,cost_options)
nghi-truyen commented 1 month ago
  1. The function to retrieve the control vector is already written in smash: https://smash.recover.inrae.fr/api_reference/principal_methods/smash/smash.optimize_control_info.html and https://smash.recover.inrae.fr/api_reference/principal_methods/smash/smash.bayesian_optimize_control_info.html . Recently dev is even enable to retrieve the intermediate optimization results (control, cost,...) of each iteration using a callback function.
  2. and 5. Yes, it is possible to add these features. For example, we can create a function that takes the control vector value and the same arguments as smash.optimize_control_info and smash.bayesian_optimize_control_info methods. Then standardize these arguments, apply wrap_parameters_to_control, set new control values (setattr(model._parameters.control, "x", x)), and finally run the forward model with the updated control vector.
  3. Yes, this is possible
  4. Addressing this point would resolve issue #211