Пример #1
0
 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
Пример #2
0
 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
Пример #3
0
    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