Source code for buzzard.interfaces.scipy

# -*- coding: utf-8 -*-
#  ---------------------------------------------------------------------
#
#  ____                             _
# | __ ) _   _ __________ _ _ __ __| |
# |  _ \| | | |_  /_  / _` | '__/ _` |
# | |_) | |_| |/ / / / (_| | | | (_| |
# |____/ \__,_/___/___\__,_|_|  \__,_|
#
#
#  Unit of Strength of Materials and Structural Analysis
#  University of Innsbruck,
#  2021 - today
#
#  Alexander Dummer alexander.dummer@uibk.ac.at
#
#  This file is part of Buzzard.
#
#  This library is free software; you can redistribute it and/or
#  modify it under the terms of the GNU Lesser General Public
#  License as published by the Free Software Foundation; either
#  version 2.1 of the License, or (at your option) any later version.
#
#  The full text of the license can be found in the file LICENSE.md at
#  the top level directory of Buzzard.
#  ---------------------------------------------------------------------

from typing import Callable, Sequence

import numpy as np
from optimparallel import minimize_parallel
from scipy import optimize

from buzzard.core.identification import Identification
from buzzard.utils.journal import infoMessage, message, printLine

availableOptimizationMethods = {
    "global": ["brute", "differential_evolution", "shgo", "dual_annealing"],
    "local": [
        "Nelder-Mead",
        "Powell",
        "L-BFGS-B",
        "L-BFGS-B-parallel",
        "TNC",
        "SLSQP",
        "trust-constr",
    ],
}


[docs]def callSciPyMinimize( f: Callable, initialParameters: np.ndarray, bounds: optimize.Bounds, method: str, options: dict, ): if method == "L-BFGS-B-parallel": return minimize_parallel( f, initialParameters, bounds=bounds, options=options, callback=minimizerCallbackFunction, ) elif method == "TNC": return optimize.minimize( f, initialParameters, bounds=bounds, method=method, options=options, callback=minimizerCallbackFunction, jac="2-point", ) else: return optimize.minimize( f, initialParameters, bounds=bounds, method=method, options=options, callback=minimizerCallbackFunction, )
[docs]def callSciPyGlobalOptimization(f: Callable, bounds: Sequence, method: str, options: dict): if method == "differential_evolution": return optimize.differential_evolution( f, bounds=bounds, callback=differentialEvolutionCallbackFunction, **options ) elif method == "dual_annealing": return optimize.dual_annealing(f, bounds, callback=dualAnnealingCallbackFunction, **options) elif method == "brute": res = optimize.OptimizeResult() res.x = optimize.brute(f, bounds, **options) return res elif method == "shgo": return optimize.shgo(f, bounds, callback=minimizerCallbackFunction, **options) else: raise Exception("global optimization method {:} not available!".format(method))
[docs]def minimizerCallbackFunction(x: np.ndarray, *args): printLine() infoMessage("current parameters ...") for i, val in enumerate(x): message(" -->", Identification.active_identifications[i].name, "= {:e}".format(val)) printLine()
[docs]def differentialEvolutionCallbackFunction(x: np.ndarray, convergence=0): printLine() infoMessage("current parameters ...") for i, val in enumerate(x): message(" -->", Identification.active_identifications[i].name, "= {:e}".format(val)) printLine()
[docs]def dualAnnealingCallbackFunction(x: np.ndarray, f: float, context: int): printLine() infoMessage("f = {:}".format(f)) infoMessage("current parameters ...") for i, val in enumerate(x): message(" -->", Identification.active_identifications[i].name, "= {:e}".format(val)) printLine()