def _get_model_instance(fmu_path, inputs, known_pars, est, output_names): model = Model(fmu_path) model.set_input(inputs) model.set_param(known_pars) model.set_param(estpars_2_df(est)) model.set_outputs(output_names) return model
def _get_model_instance(self, fmu_path, inputs, known_pars, est, output_names): self.logger.debug("Getting model instance...") self.logger.debug(f"inputs = {inputs}") self.logger.debug(f"known_pars = {known_pars}") self.logger.debug(f"est = {est}") self.logger.debug(f"estpars_2_df(est) = {estpars_2_df(est)}") self.logger.debug(f"output_names = {output_names}") model = Model(fmu_path) model.inputs_from_df(inputs) model.parameters_from_df(known_pars) model.parameters_from_df(estpars_2_df(est)) model.specify_outputs(output_names) self.logger.debug(f"Model instance initialized: {model}") self.logger.debug(f"Model instance initialized: {model.model}") res = model.simulate() self.logger.debug(f"test result: {res}") return model
def _search(self): """ Pattern _search loop. :return: DataFrame with estimates """ initial_estimates = copy.deepcopy(self.est) best_estimates = copy.deepcopy(initial_estimates) current_estimates = copy.deepcopy(initial_estimates) initial_result = self.model.simulate() self.res = initial_result initial_error = calc_err(initial_result, self.ideal, ftype=self.ftype)["tot"] best_err = initial_error # First line of the summary summary = estpars_2_df(current_estimates) summary[PS.ERR] = [initial_error] # Counters n_try = 0 iteration = 0 # Search loop while ((n_try < self.try_lim) and (iteration < self.max_iter) and (self.rel_step > self.tol)): iteration += 1 self.logger.info("Iteration no. {} " "=========================".format(iteration)) improved = False # Iterate over all parameters for par in current_estimates: for sign in ["+", "-"]: # Calculate new parameter new_par = self._get_new_estpar(par, self.rel_step, sign) # Simulate and calculate error self.model.set_param(estpars_2_df([new_par])) result = self.model.simulate() err = calc_err(result, self.ideal, ftype=self.ftype)["tot"] # Save point if solution improved if err < best_err: self.res = result best_err = err # Shortest path search # best_estimates = PS._replace_par(best_estimates, # new_par) # Orthogonal search best_estimates = PS._replace_par( current_estimates, new_par) improved = True # Reset model parameters self.model.set_param(estpars_2_df(current_estimates)) # Go to the new point current_estimates = copy.deepcopy(best_estimates) # Update summary current_estimates_df = estpars_2_df(current_estimates) current_estimates_df.index = [iteration] summary = pd.concat([summary, current_estimates_df]) summary[PS.ERR][iteration] = best_err if not improved: n_try += 1 self.rel_step /= PS.STEP_DEC self.logger.info("Solution did not improve...") self.logger.debug("Step reduced to {}".format(self.rel_step)) self.logger.debug("Tries left: {}".format(self.try_lim - n_try)) else: # Solution improved, reset n_try counter n_try = 0 self.rel_step *= PS.STEP_INC if self.rel_step > PS.STEP_CEILING: self.rel_step = PS.STEP_CEILING self.logger.info("Solution improved") self.logger.debug("Current step is {}".format(self.rel_step)) self.logger.info("New error: {}".format(best_err)) self.logger.debug("New estimates:\n{}".format( estpars_2_df(current_estimates))) # Reorder columns in summary s_cols = summary.columns.tolist() s_cols.remove(PS.ERR) s_cols.append(PS.ERR) summary = summary[s_cols] # Start iterations from 1 summary.index += 1 # Rename index in summary summary.index = summary.index.rename(PS.ITER) # Add column with method name summary[PS.METHOD] = PS.NAME # Print summary reason = "Unknown" if n_try >= self.try_lim: reason = "Maximum number of tries to decrease the step reached" elif iteration >= self.max_iter: reason = "Maximum number of iterations reached" elif self.rel_step <= self.tol: reason = "Relative step smaller than the stoping criterion" self.logger.info("Pattern search finished. Reason: {}".format(reason)) self.logger.info("Summary:\n{}".format(summary)) # Final assignments self.summary = summary final_estimates = estpars_2_df(best_estimates) return final_estimates