Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docplex optimizers #57

Merged
merged 14 commits into from
Jul 18, 2022
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ Full documentation, including API description, is available at <https://pyrieman
To run a specific example on your local machine, you should install first dependencies for the documentation:

```
pip install .[doc]
pip install .[docs]
```

Then you can run the python example of your choice like:
Expand Down Expand Up @@ -121,7 +121,7 @@ Code contribution (pull request) can be either on core functionalities, document
- Automation is based on `GitHub Action` and `pytest`. It consists in two automated workflows for running the example and the tests. To run the tests on your local machine, you should first install the dependencies for testing:

```
pip install .[test]
pip install .[tests]
```

and then type `pytest` from the root repository. You can also specify a file like:
Expand Down
3 changes: 3 additions & 0 deletions doc/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ Docplex
square_cont_mat_var
square_int_mat_var
square_bin_mat_var
pyQiskitOptimizer
ClassicalOptimizer
NaiveQAOAOptimizer

Datasets
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Expand Down
3 changes: 2 additions & 1 deletion doc/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ pandas
cvxpy==1.1.12
qiskit_machine_learning==0.4.0
qiskit-ibmq-provider==0.19.1
qiskit-optimization==0.4.0
scipy==1.7.3
moabb>=0.4.6
git+https://github.com/pyRiemann/pyRiemann#egg=pyriemann
docplex
docplex>=2.21.207
8 changes: 6 additions & 2 deletions pyriemann_qiskit/utils/__init__.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
from . import hyper_params_factory, filtering
from .docplex import (square_cont_mat_var,
square_int_mat_var,
square_bin_mat_var)
square_bin_mat_var,
ClassicalOptimizer,
NaiveQAOAOptimizer)

__all__ = [
'hyper_params_factory',
'filtering',
'square_cont_mat_var',
'square_int_mat_var',
'square_bin_mat_var'
'square_bin_mat_var',
'ClassicalOptimizer',
'NaiveQAOAOptimizer'
]
282 changes: 282 additions & 0 deletions pyriemann_qiskit/utils/docplex.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,19 @@
"""This module contains both classic and quantum optimizers, and some helper
functions. The quantum optimizer allows an optimization problem with
constraints (in the form of docplex model) to be run on a quantum computer.
It is for example suitable for:
- MDM optimization problem;
- computation of matrices mean.
"""
from docplex.mp.vartype import ContinuousVarType, IntegerVarType, BinaryVarType
from qiskit import BasicAer
from qiskit.utils import QuantumInstance
from qiskit.algorithms import QAOA
from qiskit_optimization.algorithms import (CobylaOptimizer,
MinimumEigenOptimizer)
from qiskit_optimization.converters import IntegerToBinary
from qiskit_optimization.problems import QuadraticProgram
import numpy as np


def square_cont_mat_var(prob, channels,
Expand All @@ -16,6 +31,9 @@ def square_cont_mat_var(prob, channels,
channels : list
The list of channels. A channel can be any Python object,
such as channels'name or number but None.
name : string
An custom name for the variable. The name is used internally by docplex
and may appear if your print the model to a file for example.

Returns
-------
Expand All @@ -24,6 +42,10 @@ def square_cont_mat_var(prob, channels,
Access element (i, j) with square_mat[(i, j)].
Indices start with 0.

Notes
-----
.. versionadded:: 0.0.2

References
----------
.. [1] \
Expand All @@ -49,6 +71,9 @@ def square_int_mat_var(prob, channels,
channels : list
The list of channels. A channel can be any Python object,
such as channels'name or number but None.
name : string
An custom name for the variable. The name is used internally by docplex
and may appear if your print the model to a file for example.

Returns
-------
Expand All @@ -57,6 +82,10 @@ def square_int_mat_var(prob, channels,
Access element (i, j) with square_mat[(i, j)].
Indices start with 0.

Notes
-----
.. versionadded:: 0.0.2

References
----------
.. [1] \
Expand All @@ -82,6 +111,9 @@ def square_bin_mat_var(prob, channels,
channels : list
The list of channels. A channel can be any Python object,
such as channels'name or number but None.
name : string
An custom name for the variable. The name is used internally by docplex
and may appear if your print the model to a file for example.

Returns
-------
Expand All @@ -90,6 +122,10 @@ def square_bin_mat_var(prob, channels,
Access element (i, j) with square_mat[(i, j)].
Indices start with 0.

Notes
-----
.. versionadded:: 0.0.2

References
----------
.. [1] \
Expand All @@ -98,3 +134,249 @@ def square_bin_mat_var(prob, channels,
BinaryVarType.one_letter_symbol = lambda _: 'B'
return prob.binary_var_matrix(keys1=channels, keys2=channels,
name=name)


class pyQiskitOptimizer():

"""Wrapper for Qiskit optimizer.

This class is an abstract class which provides an interface
for running our docplex model independently of the optimizer type
(such as classical or quantum optimizer).

Notes
-----
.. versionadded:: 0.0.2
"""
def __init__(self):
pass

"""Hook to apply some transformation on a covariance matrix.

Parameters
----------
covmat : ndarray, shape (n_features, n_features)
The covariance matrix.
precision : float
Additional parameter for the transformation.

Returns
-------
transformed_covmat : ndarray, shape (n_features, n_features)
A transformation of the covariance matrix.

Notes
-----
.. versionadded:: 0.0.2
"""
def convert_covmat(self, covmat, precision=None):
return covmat

"""Helper to create a docplex representation of a
covariance matrix variable.

Parameters
----------
prob : Model
An instance of the docplex model [1]_
channels : list
The list of channels. A channel can be any Python object,
such as channels'name or number but None.
name : string
An custom name for the variable. The name is used internally by docplex
and may appear if your print the model to a file for example.

Returns
-------
docplex_covmat : dict
A square matrix of decision variables representing
our covariance matrix.

Notes
-----
.. versionadded:: 0.0.2

References
----------
.. [1] \
http://ibmdecisionoptimization.github.io/docplex-doc/mp/_modules/docplex/mp/model.html#Model

"""
def covmat_var(self, prob, channels, name):
raise NotImplementedError()

def _solve_qp(self, qp):
raise NotImplementedError()

"""Solve the docplex problem.

Parameters
----------
prob : Model
An instance of the docplex model [1]_

Returns
-------
result : OptimizationResult
The result of the optimization.

Notes
-----
.. versionadded:: 0.0.2

References
----------
.. [1] \
http://ibmdecisionoptimization.github.io/docplex-doc/mp/_modules/docplex/mp/model.html#Model

"""
def solve(self, prob):
qp = QuadraticProgram()
qp.from_docplex(prob)
return self._solve_qp(qp)


class ClassicalOptimizer(pyQiskitOptimizer):

"""Wrapper for the classical Cobyla optimizer.

Notes
-----
.. versionadded:: 0.0.2

See Also
--------
pyQiskitOptimizer

"""
def __init__(self):
pass

"""Helper to create a docplex representation of a
covariance matrix variable.

Parameters
----------
prob : Model
An instance of the docplex model [1]_
channels : list
The list of channels. A channel can be any Python object,
such as channels'name or number but None.
name : string
An custom name for the variable. The name is used internally by docplex
and may appear if your print the model to a file for example.

Returns
-------
docplex_covmat : dict
A square matrix of continuous decision variables representing
our covariance matrix.

See Also
-----
square_cont_mat_var

Notes
-----
.. versionadded:: 0.0.2

References
----------
.. [1] \
http://ibmdecisionoptimization.github.io/docplex-doc/mp/_modules/docplex/mp/model.html#Model

"""
def covmat_var(self, prob, channels, name):
return square_cont_mat_var(prob, channels, name)

def _solve_qp(self, qp):
return CobylaOptimizer(rhobeg=0.01, rhoend=0.0001).solve(qp)


class NaiveQAOAOptimizer(pyQiskitOptimizer):

"""Wrapper for the quantum optimizer QAOA.

Notes
-----
.. versionadded:: 0.0.2

See Also
--------
pyQiskitOptimizer
"""
def __init__(self):
pass

"""Transform all values in the covariance matrix
to integers.

Example:
0.123 -> 1230

Parameters
----------
covmat : ndarray, shape (n_features, n_features)
The covariance matrix.
precision : float (default: 10**4)
new_value = round(value * `precision`)

Returns
-------
transformed_covmat : ndarray, shape (n_features, n_features)
A transformation of the covariance matrix.

Notes
-----
.. versionadded:: 0.0.2

"""
def convert_covmat(self, covmat, precision=10**4):
return np.round(covmat * precision, 0)

"""Helper to create a docplex representation of a
covariance matrix variable.

Parameters
----------
prob : Model
An instance of the docplex model [1]_
channels : list
The list of channels. A channel can be any Python object,
such as channels'name or number but None.
name : string
An custom name for the variable. The name is used internally by docplex
and may appear if your print the model to a file for example.

Returns
-------
docplex_covmat : dict
A square matrix of integer decision variables representing
our covariance matrix.

See Also
-----
square_int_mat_var

Notes
-----
.. versionadded:: 0.0.2

References
----------
.. [1] \
http://ibmdecisionoptimization.github.io/docplex-doc/mp/_modules/docplex/mp/model.html#Model

"""
def covmat_var(self, prob, channels, name):
return square_int_mat_var(prob, channels, name)

def _solve_qp(self, qp):
conv = IntegerToBinary()
qubo = conv.convert(qp)
backend = BasicAer.get_backend('statevector_simulator')
quantum_instance = QuantumInstance(backend)
qaoa_mes = QAOA(quantum_instance=quantum_instance,
initial_point=[0., 0.])
qaoa = MinimumEigenOptimizer(qaoa_mes)
return qaoa.solve(qubo)
4 changes: 3 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@ cython
git+https://github.com/pyRiemann/pyRiemann#egg=pyriemann
qiskit_machine_learning==0.4.0
qiskit-ibmq-provider==0.19.1
cvxpy==1.1.12
qiskit-optimization==0.4.0
cvxpy==1.1.12
docplex>=2.21.207
Loading