Source code for cratepy.optimization.optimizer

"""Optimization algorithms.

This module includes the interface to implement any optimization algorithm as
well as several wrappers over optimization algorithms available on open-source
libraries (e.g., `SciPy <https://docs.scipy.org/doc/scipy/reference/generated/
scipy.optimize.minimize.html>`_) and others.

Classes
-------
Optimizer
    Optimization algorithm interface.
SciPyMinimizer
    SciPy minimization optimizer (wrapper).
"""
#
#                                                                       Modules
# =============================================================================
# Standard
from abc import ABC, abstractmethod
# Third-party
import numpy as np
import scipy.optimize
#
#                                                          Authorship & Credits
# =============================================================================
__author__ = 'Bernardo Ferreira (bernardo_ferreira@brown.edu)'
__credits__ = ['Bernardo Ferreira', ]
__status__ = 'Alpha'
# =============================================================================
#
# =============================================================================
#
#                                             Interface: Optimization algorithm
# =============================================================================
[docs]class Optimizer(ABC): """Optimization algorithm interface. Methods ------- solve_optimization(self, optimization_function, max_n_iter=None, \ verbose=False): *abstract*: Solve optimization problem. """
[docs] @abstractmethod def __init__(self): """Constructor.""" pass
# -------------------------------------------------------------------------
[docs] @abstractmethod def solve_optimization(self, optimization_function, max_n_iter=None, verbose=False): """Solve optimization problem. Parameters ---------- optimization_function : OptimizationFunction Instance of OptimizationFunction class. max_n_iter : int, default=None Maximum number of iterations. verbose : bool, default=False Enable verbose output. Returns ------- parameters : dict Optimization parameters names (key, str) and values (item, float). """ pass
# # Optimization algorithms # =============================================================================
[docs]class SciPyMinimizer(Optimizer): """SciPy minimization optimizer (wrapper). Documentation: see `here <https://docs.scipy.org/doc/scipy/reference/ generated/scipy.optimize.minimize.html>`_. Methods ------- solve_optimization(self, optimization_function, max_n_iter=None, \ verbose=False) Solve optimization problem. """
[docs] def __init__(self, method='Powell'): """Constructor. Parameters ---------- method : {'Nelder-Mead', 'Powell', 'CG', 'BFGS'}, default='Powell' Optimization method. """ self._method = method
# -------------------------------------------------------------------------
[docs] def solve_optimization(self, optimization_function, max_n_iter=1, verbose=False): """Solve optimization problem. Parameters ---------- optimization_function : OptimizationFunction Instance of OptimizationFunction class. max_n_iter : int, default=1 Maximum number of iterations. verbose : bool, default=False Enable verbose output. Returns ------- parameters : dict Optimization parameters names (key, str) and values (item, float). """ # Get optimization function with normalized parameters provided as # sequence norm_opt_function_seq = optimization_function.norm_opt_function_seq # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Get optimization function parameters names parameters_names = optimization_function.get_parameters_names() # Set number of optimization parameters dimension = len(parameters_names) # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Get optimization parameters initial guess init_shot = optimization_function.get_init_shot(is_normalized=True) x0 = np.array([init_shot[str(param)] for param in parameters_names]) # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Get optimization parameters lower and upper bounds lower_bounds, upper_bounds = \ optimization_function.get_bounds(is_normalized=True) # Build optimization parameters bounds array bounds = np.array([(lower_bounds[str(param)], upper_bounds[str(param)]) for param in parameters_names]).reshape(dimension, 2) # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Set algorithmic parameters options = {'maxiter': max_n_iter, } # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Solve optimization problem result = scipy.optimize.minimize(fun=norm_opt_function_seq, x0=x0, method=self._method, bounds=bounds, options=options) # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Get optimization solution parameters = {str(param): result.x[i] for i, param in enumerate(parameters_names)} # optimum = result.fun # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Return return parameters