Skip to content
This repository has been archived by the owner on Dec 7, 2021. It is now read-only.

Optimizers for noisy quantum devices (scikit-quant) #1240

Merged
merged 33 commits into from
Sep 28, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
35b3ff8
snobfit first
Brogis1 Jun 2, 2020
2ed65bb
bobyqa optimizer
Brogis1 Jun 2, 2020
b4be897
imfil optimizer
Brogis1 Jun 2, 2020
f7f30aa
orbit optimizer
Brogis1 Jun 2, 2020
d4daa2e
orbit added
Brogis1 Jul 7, 2020
e93e2f9
snobfit first
Brogis1 Jun 2, 2020
b24e411
bobyqa optimizer
Brogis1 Jun 2, 2020
8e7e850
imfil optimizer
Brogis1 Jun 2, 2020
d98664e
orbit optimizer
Brogis1 Jun 2, 2020
542e9c3
orbit added
Brogis1 Jul 7, 2020
074f8d9
Merge branch 'optimizers' of https://github.com/Brogis1/qiskit-aqua i…
Brogis1 Sep 9, 2020
d34e472
snobfit first
Brogis1 Jun 2, 2020
8ea4122
bobyqa optimizer
Brogis1 Jun 2, 2020
28fa5d7
imfil optimizer
Brogis1 Jun 2, 2020
a6609b5
orbit optimizer
Brogis1 Jun 2, 2020
6d470e2
orbit added
Brogis1 Jul 7, 2020
11c2bce
Merge branch 'optimizers' of https://github.com/Brogis1/qiskit-aqua i…
Brogis1 Sep 9, 2020
2141d23
final pre-pull
Brogis1 Sep 9, 2020
f37e78d
final pre-pull 2
Brogis1 Sep 9, 2020
60592b8
added req and docstrings
Brogis1 Sep 9, 2020
c2b83b3
copyright corrected
Brogis1 Sep 9, 2020
da80f87
utf-8 supressed
Brogis1 Sep 9, 2020
a668765
missing commas, docstrings.
adekusar-drl Sep 10, 2020
e32eb2e
Merge branch 'master' into optimizers
pbark Sep 10, 2020
884d45b
Merge branch 'master' into optimizers
manoelmarques Sep 10, 2020
03107db
Merge branch 'master' into optimizers
manoelmarques Sep 11, 2020
22a310d
Merge branch 'master' into optimizers
manoelmarques Sep 12, 2020
9a3e84e
Merge branch 'master' into optimizers
manoelmarques Sep 23, 2020
f6005de
Merge branch 'master' into optimizers
woodsp-ibm Sep 25, 2020
3ce4aca
Merge branch 'master' into optimizers
manoelmarques Sep 26, 2020
510c885
make scikit-quant optional
manoelmarques Sep 26, 2020
8c05e02
Add to optimizers documentation
woodsp-ibm Sep 27, 2020
d4e1b0d
Spelling: licences (UK variant) to licenses
woodsp-ibm Sep 27, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,9 @@ jobs:
if: ${{ !startsWith(github.ref, 'refs/heads/stable') }}
- uses: ./.github/actions/install-aqua
- name: Install Dependencies
run: pip install "cvxpy>1.0.0"
run: |
pip install "cvxpy>1.0.0"
pip install scikit-quant
shell: bash
- name: Install cplex
run: pip install cplex
Expand Down
7 changes: 7 additions & 0 deletions .pylintdict
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ bitstring
bitstrings
bksf
bmod
bobyqa
bohr
bool
boolean
Expand Down Expand Up @@ -275,6 +276,7 @@ ij
ijkl
ik
imag
imfil
imode
implicant
implicants
Expand Down Expand Up @@ -365,11 +367,13 @@ matlab
matmul
maxcut
maxdepth
maxfail
maxfev
maxfun
maxima
maxiter
maxiters
maxmp
McArdle
mccluskey
mct
Expand Down Expand Up @@ -536,6 +540,7 @@ quadratically
quadraticconstraint
quadraticprogram
quandl
quant
quantile
quantized
quantumcircuit
Expand Down Expand Up @@ -606,8 +611,10 @@ sigmoid
simonetto
sj
sklearn
skquant
slsqp
smode
snobfit
spsa
sqrt
srange
Expand Down
21 changes: 20 additions & 1 deletion qiskit/aqua/components/optimizers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,21 @@
SPSA
TNC

Qiskit Aqua also provides the following optimizers, which are built-out using the optimizers from
the `scikit-quant` package. The `scikit-quant` package is not installed by default but must be
explicitly installed, if desired, by the user - the optimizers therein are provided under various
licenses so it has been made an optional install for the end user to choose whether to do so or
not. To install the `scikit-quant` dependent package you can use
`pip install qiskit-aqua[skquant]`.

.. autosummary::
:toctree: ../stubs/
:nosignatures:

BOBYQA
IMFIL
SNOBFIT

Global Optimizers
=================
The global optimizers here all use NLopt for their core function and can only be
Expand Down Expand Up @@ -101,6 +116,9 @@
from .nlopts.direct_l_rand import DIRECT_L_RAND
from .nlopts.esch import ESCH
from .nlopts.isres import ISRES
from .snobfit import SNOBFIT
from .bobyqa import BOBYQA
from .imfil import IMFIL

__all__ = ['Optimizer',
'OptimizerSupportLevel',
Expand All @@ -117,4 +135,5 @@
'SLSQP',
'SPSA',
'TNC',
'CRS', 'DIRECT_L', 'DIRECT_L_RAND', 'ESCH', 'ISRES']
'CRS', 'DIRECT_L', 'DIRECT_L_RAND', 'ESCH', 'ISRES',
'SNOBFIT', 'BOBYQA', 'IMFIL']
76 changes: 76 additions & 0 deletions qiskit/aqua/components/optimizers/bobyqa.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# This code is part of Qiskit.
#
# (C) Copyright IBM 2019, 2020.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.

"""Bound Optimization BY Quadratic Approximation (BOBYQA) optimizer."""


import logging
import numpy as np
from qiskit.aqua import MissingOptionalLibraryError
from .optimizer import Optimizer, OptimizerSupportLevel

logger = logging.getLogger(__name__)

try:
import skquant.opt as skq
_HAS_SKQUANT = True
except ImportError:
_HAS_SKQUANT = False


class BOBYQA(Optimizer):
""" Bound Optimization BY Quadratic Approximation algorithm.

BOBYQA finds local solutions to nonlinear, non-convex minimization problems with optional
bound constraints, without requirement of derivatives of the objective function.

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.
"""

# pylint: disable=unused-argument
def __init__(self,
maxiter: int = 1000,
) -> None:
"""
Args:
maxiter: Maximum number of function evaluations.

Raises:
MissingOptionalLibraryError: scikit-quant not installed
"""
if not _HAS_SKQUANT:
raise MissingOptionalLibraryError(
libname='scikit-quant',
name='BOBYQA',
pip_install='pip install qiskit-aqua[skquant]')
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
}

def optimize(self, num_vars, objective_function, gradient_function=None,
variable_bounds=None, initial_point=None):
""" Runs the optimization. """
super().optimize(num_vars, objective_function, gradient_function,
variable_bounds, initial_point)
res, history = skq.minimize(objective_function, np.array(initial_point),
bounds=np.array(variable_bounds), budget=self._maxiter,
method="bobyqa")
return res.optpar, res.optval, len(history)
76 changes: 76 additions & 0 deletions qiskit/aqua/components/optimizers/imfil.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# This code is part of Qiskit.
#
# (C) Copyright IBM 2019, 2020.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.

"""IMplicit FILtering (IMFIL) optimizer."""

import logging
from qiskit.aqua import MissingOptionalLibraryError
from .optimizer import Optimizer, OptimizerSupportLevel

logger = logging.getLogger(__name__)

try:
import skquant.opt as skq
_HAS_SKQUANT = True
except ImportError:
_HAS_SKQUANT = False


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.
"""

# pylint: disable=unused-argument
def __init__(self,
maxiter: int = 1000,
) -> None:
"""
Args:
maxiter: Maximum number of function evaluations.

Raises:
MissingOptionalLibraryError: scikit-quant not installed
"""
if not _HAS_SKQUANT:
raise MissingOptionalLibraryError(
libname='scikit-quant',
name='IMFIL',
pip_install='pip install qiskit-aqua[skquant]')
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
}

def optimize(self, num_vars, objective_function, gradient_function=None, variable_bounds=None,
initial_point=None):
""" Runs the optimization. """
super().optimize(num_vars, objective_function, gradient_function, variable_bounds,
initial_point)
res, history = skq.minimize(func=objective_function, x0=initial_point,
bounds=variable_bounds, budget=self._maxiter,
method="imfil")
return res.optpar, res.optval, len(history)
109 changes: 109 additions & 0 deletions qiskit/aqua/components/optimizers/snobfit.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# This code is part of Qiskit.
#
# (C) Copyright IBM 2019, 2020.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.

"""Stable Noisy Optimization by Branch and FIT algorithm (SNOBFIT) optimizer."""

import logging
import numpy as np
from qiskit.aqua import MissingOptionalLibraryError
from .optimizer import Optimizer, OptimizerSupportLevel

logger = logging.getLogger(__name__)

try:
import skquant.opt as skq
_HAS_SKQUANT = True
except ImportError:
_HAS_SKQUANT = False

try:
from SQSnobFit import optset
_HAS_SKSNOBFIT = True
except ImportError:
_HAS_SKSNOBFIT = False


class SNOBFIT(Optimizer):
"""Stable Noisy Optimization by Branch and FIT algorithm.

SnobFit is used for the optimization of derivative-free, noisy objective functions providing
robust and fast solutions of problems with continuous variables varying within bound.

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.
"""

# pylint: disable=unused-argument
def __init__(self,
maxiter: int = 1000,
maxfail: int = 10,
maxmp: int = None,
verbose: bool = False,
) -> None:
"""
Args:
maxiter: Maximum number of function evaluations.
maxmp: Maximum number of model points requested for the local fit.
Default = 2 * number of parameters + 6 set to this value when None.
maxfail: Maximum number of failures to improve the solution. Stops the algorithm
after maxfail is reached.
verbose: Provide verbose (debugging) output.

Raises:
MissingOptionalLibraryError: scikit-quant or SQSnobFit not installed
"""
if not _HAS_SKQUANT:
raise MissingOptionalLibraryError(
libname='scikit-quant',
name='SNOBFIT',
pip_install='pip install qiskit-aqua[skquant]')
if not _HAS_SKSNOBFIT:
raise MissingOptionalLibraryError(
libname='SQSnobFit',
name='SNOBFIT',
pip_install='pip install SQSnobFit')
super().__init__()
self._maxiter = maxiter
self._maxfail = maxfail
self._maxmp = maxmp
self._verbose = verbose

def get_support_level(self):
""" Returns support level dictionary. """
return {
'gradient': OptimizerSupportLevel.ignored,
'bounds': OptimizerSupportLevel.required,
'initial_point': OptimizerSupportLevel.required
}

def optimize(self, num_vars, objective_function, gradient_function=None,
variable_bounds=None, initial_point=None):
""" Runs the optimization. """
super().optimize(num_vars, objective_function, gradient_function,
variable_bounds, initial_point)
snobfit_settings = {
'maxmp': self._maxmp,
'maxfail': self._maxfail,
'verbose': self._verbose,
}
options = optset(optin=snobfit_settings)
# counters the error when initial point is outside the acceptable bounds
for idx, theta in enumerate(initial_point):
if abs(theta) > variable_bounds[idx][0]:
initial_point[idx] = initial_point[idx] % variable_bounds[idx][0]
elif abs(theta) > variable_bounds[idx][1]:
initial_point[idx] = initial_point[idx] % variable_bounds[idx][1]
res, history = skq.minimize(objective_function, np.array(initial_point, dtype=float),
bounds=variable_bounds, budget=self._maxiter,
method="snobfit", options=options)
return res.optpar, res.optval, len(history)
2 changes: 1 addition & 1 deletion requirements-dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ qiskit-aer
qiskit-ibmq-provider
mypy>=0.780
mypy-extensions>=0.4.3
networkx>=2.2
networkx>=2.2
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
'cplex': ["cplex; python_version >= '3.6' and python_version < '3.8'"],
'cvx': ['cvxpy>1.0.0,!=1.1.0,!=1.1.1,!=1.1.2'],
'pyscf': ["pyscf; sys_platform != 'win32'"],
'skquant': ["scikit-quant"],
},
zip_safe=False
)
Loading