diff --git a/deerlab/classes.py b/deerlab/classes.py index d41e4482..49a6ec46 100644 --- a/deerlab/classes.py +++ b/deerlab/classes.py @@ -583,7 +583,7 @@ def propagate(self,model,lb=None,ub=None,samples=None): # Get the parameter uncertainty distribution values,pdf = self.pardist(n) # Random sampling form the uncertainty distribution - sampled_parameters[n] = [np.random.choice(values, p=pdf/sum(pdf)) for _ in range(Nsamples)] + sampled_parameters[n] = np.random.choice(values, p=pdf/sum(pdf),size=Nsamples) # Convert to matrix sampled_parameters = np.atleast_2d(sampled_parameters) diff --git a/deerlab/fit.py b/deerlab/fit.py index 0c516c15..a1b5e8bc 100644 --- a/deerlab/fit.py +++ b/deerlab/fit.py @@ -543,8 +543,8 @@ def _scale(x): FitResult_param_[f'{key}_scale'] = _scale(FitResult_param_[key]) # Normalization factor FitResult_param_[key] = param.normalization(FitResult_param_[key]) # Normalized value - FitResult_paramuq_[f'{key}_scaleUncert'] = FitResult_paramuq_[f'{key}Uncert'].propagate(_scale,samples=bootstrap) - FitResult_paramuq_[f'{key}Uncert'] = FitResult_paramuq_[f'{key}Uncert'].propagate(lambda x: x/FitResult_param_[f'{key}_scale'], lb=param.lb, ub=param.ub,samples=bootstrap) # Normalization of the uncertainty + FitResult_paramuq_[f'{key}_scaleUncert'] = FitResult_paramuq_[f'{key}Uncert'].propagate(_scale,samples=bootstrap+1) + FitResult_paramuq_[f'{key}Uncert'] = FitResult_paramuq_[f'{key}Uncert'].propagate(lambda x: x/FitResult_param_[f'{key}_scale'], lb=param.lb, ub=param.ub,samples=bootstrap+1) # Normalization of the uncertainty if len(noiselvl)==1: noiselvl = noiselvl[0] diff --git a/deerlab/fitresult.py b/deerlab/fitresult.py index 6980c626..c1a552b0 100644 --- a/deerlab/fitresult.py +++ b/deerlab/fitresult.py @@ -97,20 +97,21 @@ def _extarct_params_from_model(self, model): if not hasattr(self,'param'): raise ValueError('The fit object does not contain any fitted parameters.') - # # Enforce model normalization - # normfactor_keys = [] - # for key in modelparam: - # param = getattr(model,key) - # if np.all(param.linear): - # if param.normalization is not None: - # normfactor_key = f'{key}_scale' - # normfactor_keys.append(normfactor_key) - # try: - # model.addnonlinear(normfactor_key,lb=-np.inf,ub=np.inf,par0=1,description=f'Normalization factor of {key}') - # getattr(model,normfactor_key).freeze(1) - # except KeyError: - # pass - + # Enforce model normalization + normfactor_keys = [] + for key in modelparam: + param = getattr(model,key) + if np.all(param.linear): + if param.normalization is not None: + normfactor_key = f'{key}_scale' + normfactor_keys.append(normfactor_key) + try: + model.addnonlinear(normfactor_key,lb=-np.inf,ub=np.inf,par0=1,description=f'Normalization factor of {key}') + getattr(model,normfactor_key).freeze(1) + except KeyError: + pass + modelparam += normfactor_keys + # # Get some basic information on the parameter vector # modelparam = model._parameter_list(order='vector') @@ -187,6 +188,7 @@ def evaluate(self, model, *constants): Model response at the fitted parameter values. """ try: + model = model.copy() modelparam = model._parameter_list('vector') modelparam, fitparams, fitparam_idx = self._extarct_params_from_model(model) except AttributeError: @@ -234,6 +236,7 @@ def propagate(self, model, *constants, lb=None, ub=None,samples=None): responseUncert : :ref:`UQResult` Uncertainty quantification of the model's response. """ + model = model.copy() try: modelparam = model._parameter_list('vector')