Source code for pybop.optimisers.nlopt_optimize

import nlopt
from .base_optimiser import BaseOptimiser
import numpy as np


[docs] class NLoptOptimize(BaseOptimiser): """ Extends BaseOptimiser to utilize the NLopt library for nonlinear optimization. This class serves as an interface to the NLopt optimization algorithms. It allows the user to define an optimization problem with bounds, initial guesses, and to select an optimization method provided by NLopt. Parameters ---------- n_param : int Number of parameters to optimize. xtol : float, optional The relative tolerance for optimization (stopping criteria). If not provided, a default of 1e-5 is used. method : nlopt.algorithm, optional The NLopt algorithm to use for optimization. If not provided, LN_BOBYQA is used by default. maxiter : int, optional The maximum number of iterations to perform during optimization. If not provided, NLopt's default is used. """ def __init__(self, n_param, xtol=None, method=None, maxiter=None): super().__init__() self.n_param = n_param self._max_iterations = maxiter if method is not None: self.optim = nlopt.opt(method, self.n_param) else: self.optim = nlopt.opt(nlopt.LN_BOBYQA, self.n_param) if xtol is not None: self.optim.set_xtol_rel(xtol) else: self.optim.set_xtol_rel(1e-5)
[docs] def _runoptimise(self, cost_function, x0, bounds): """ Runs the optimization process using the NLopt library. Parameters ---------- cost_function : callable The objective function to minimize. It should take an array of parameter values and return the scalar cost. x0 : array_like The initial guess for the parameters. bounds : dict A dictionary containing the 'lower' and 'upper' bounds arrays for the parameters. Returns ------- tuple A tuple containing the optimized parameter values and the final cost. """ # Add callback storing history of parameter values self.log = [[x0]] def cost_wrapper(x, grad): self.log.append([np.array(x)]) return cost_function(x, grad) # Pass settings to the optimiser self.optim.set_min_objective(cost_wrapper) self.optim.set_lower_bounds(bounds["lower"]) self.optim.set_upper_bounds(bounds["upper"]) # Set max iterations if self._max_iterations is not None: self.optim.set_maxeval(self._max_iterations) # Run the optimser x = self.optim.optimize(x0) # Get performance statistics final_cost = self.optim.last_optimum_value() return x, final_cost
[docs] def needs_sensitivities(self): """ Indicates if the optimiser requires gradient information for the cost function. Returns ------- bool False, as the default NLopt algorithms do not require gradient information. """ return False
[docs] def name(self): """ Returns the name of this optimiser instance. Returns ------- str The name 'NLoptOptimize' representing this NLopt optimization class. """ return "NLoptOptimize"