| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| """IMplicit FILtering (IMFIL) optimizer.""" |
| from __future__ import annotations |
|
|
| from collections.abc import Callable |
| from typing import Any |
|
|
| from qiskit_algorithms.utils import optionals as _optionals |
| from .optimizer import Optimizer, OptimizerSupportLevel, OptimizerResult, POINT |
|
|
|
|
| @_optionals.HAS_SKQUANT.require_in_instance |
| class IMFIL(Optimizer): |
| """IMplicit FILtering algorithm. |
| |
| Implicit filtering is a way to solve bound-constrained optimization problems for |
| which derivatives are not available. In comparison to methods that use interpolation to |
| reconstruct the function and its higher derivatives, implicit filtering builds upon |
| coordinate search followed by interpolation to get an approximate gradient. |
| |
| Uses skquant.opt installed with pip install scikit-quant. |
| For further detail, please refer to |
| https://github.com/scikit-quant/scikit-quant and https://qat4chem.lbl.gov/software. |
| """ |
|
|
| def __init__( |
| self, |
| maxiter: int = 1000, |
| ) -> None: |
| """ |
| Args: |
| maxiter: Maximum number of function evaluations. |
| |
| Raises: |
| MissingOptionalLibraryError: scikit-quant not installed |
| """ |
| super().__init__() |
| self._maxiter = maxiter |
|
|
| def get_support_level(self): |
| """Returns support level dictionary.""" |
| return { |
| "gradient": OptimizerSupportLevel.ignored, |
| "bounds": OptimizerSupportLevel.required, |
| "initial_point": OptimizerSupportLevel.required, |
| } |
|
|
| @property |
| def settings(self) -> dict[str, Any]: |
| return { |
| "maxiter": self._maxiter, |
| } |
|
|
| def minimize( |
| self, |
| fun: Callable[[POINT], float], |
| x0: POINT, |
| jac: Callable[[POINT], POINT] | None = None, |
| bounds: list[tuple[float, float]] | None = None, |
| ) -> OptimizerResult: |
| from skquant import opt as skq |
|
|
| res, history = skq.minimize( |
| func=fun, |
| x0=x0, |
| bounds=bounds, |
| budget=self._maxiter, |
| method="imfil", |
| ) |
|
|
| optimizer_result = OptimizerResult() |
| optimizer_result.x = res.optpar |
| optimizer_result.fun = res.optval |
| optimizer_result.nfev = len(history) |
| return optimizer_result |
|
|