Source code for pymecht.ParamFitter

import numpy as np
from scipy.optimize import least_squares

[docs]class ParamFitter: ''' A class to fit parameters of a simulation function to a given output Parameters ---------- sim_func : function A function that takes in a dictionary of parameters and returns a numpy array of the same shape as the output output : numpy array A numpy array of the same shape as the output of the sim_func to be fitted params : ParamDict A dictionary of parameters to be varied ''' def __init__(self,sim_func,output,params=None): self._sim_func = sim_func self._output = output self.params = params self._keys = self.params.keys() #Test that the sim_func gives the same sized result as the "output" sim_result = self._sim_func(self.params._val()) if sim_result.shape != self._output.shape: raise ValueError("Output and simulation results are of different shape", sim_result.shape, self._output.shape) print("Parameter fitting instance created with the following settings") print(self.params) print(self.params._n(),"parameters will be fitted.") def _residual(self,cval): assert(len(cval)==self.params._n()) p = self.params._dict(cval) return (self._sim_func(p) - self._output).flatten()
[docs] def fit(self): ''' Perform the fitting Returns ------- scipy.optimize.OptimizeResult The result of the fitting ''' self.c0 = self.params._vec() result = least_squares(self._residual,x0=self.c0,bounds=self.params._bounds_vec(),verbose=2) p = self.params._dict(result.x) for k in p: self.params[k].set(p[k]) print("Fitting completed, with the following results") print(self.params) return result