Source code for glotaran.analysis.optimize

from typing import List
from warnings import warn

import numpy as np
from scipy.optimize import least_squares

from .problem import Problem
from .result import Result
from .scheme import Scheme

SUPPORTED_METHODS = {
    "TrustRegionReflection": "trf",
    "Dogbox": "dogbox",
    "Levenberg-Marquardt": "lm",
}


[docs]def optimize(scheme: Scheme, verbose: bool = True) -> Result: problem = Problem(scheme) return optimize_problem(problem, verbose=verbose)
[docs]def optimize_problem(problem: Problem, verbose: bool = True) -> Result: if problem.scheme.optimization_method not in SUPPORTED_METHODS: raise ValueError( f"Unsupported optimization method {problem.scheme.optimization_method}. " f"Supported methods are '{list(SUPPORTED_METHODS.keys())}'" ) ( labels, initial_parameter, lower_bounds, upper_bounds, ) = problem.scheme.parameters.get_label_value_and_bounds_arrays(exclude_non_vary=True) method = SUPPORTED_METHODS[problem.scheme.optimization_method] nfev = problem.scheme.maximum_number_function_evaluations ftol = problem.scheme.ftol gtol = problem.scheme.gtol xtol = problem.scheme.xtol verbose = 2 if verbose else 0 termination_reason = "" history_index = -1 try: ls_result = least_squares( _calculate_penalty, initial_parameter, bounds=(lower_bounds, upper_bounds), method=method, max_nfev=nfev, verbose=verbose, ftol=ftol, gtol=gtol, xtol=xtol, kwargs={"labels": labels, "problem": problem}, ) termination_reason = ls_result.message except Exception as e: warn(f"Optimization failed:\n\n{e}") termination_reason = str(e) ls_result = None history_index = -2 problem.save_parameters_for_history() return Result( problem.scheme, problem.create_result_data(history_index=history_index), problem.parameters, problem.additional_penalty, ls_result, labels, termination_reason, )
def _calculate_penalty(parameters: np.ndarray, labels: List[str] = None, problem: Problem = None): problem.save_parameters_for_history() problem.parameters.set_from_label_and_value_arrays(labels, parameters) problem.reset() return problem.full_penalty