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

feat/get_weights method on optimizer #127

Merged
merged 13 commits into from
May 17, 2023
4 changes: 3 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ RUN mkdir /root/mne_data
RUN mkdir /home/mne_data

## Workaround for firestore
RUN pip install protobuf==4.23.0
RUN pip install google_cloud_firestore==2.11.1
### Missing __init__ file in protobuf
RUN touch /usr/local/lib/python3.8/site-packages/protobuf-4.23.0rc3-py3.8.egg/google/__init__.py
RUN touch /usr/local/lib/python3.8/site-packages/protobuf-4.23.0-py3.8.egg/google/__init__.py
## google.cloud.location is never used in these files, and is missing in path.
RUN sed -i 's/from google.cloud.location import locations_pb2//g' '/usr/local/lib/python3.8/site-packages/google_cloud_firestore-2.11.1-py3.8.egg/google/cloud/firestore_v1/services/firestore/client.py'
RUN sed -i 's/from google.cloud.location import locations_pb2//g' '/usr/local/lib/python3.8/site-packages/google_cloud_firestore-2.11.1-py3.8.egg/google/cloud/firestore_v1/services/firestore/transports/base.py'
Expand Down
105 changes: 96 additions & 9 deletions pyriemann_qiskit/utils/docplex.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ class pyQiskitOptimizer():
Notes
-----
.. versionadded:: 0.0.2
.. versionchanged:: 0.0.4
"""
def __init__(self):
pass
Expand Down Expand Up @@ -206,7 +207,7 @@ def convert_covmat(self, covmat):
def covmat_var(self, prob, channels, name):
raise NotImplementedError()

def _solve_qp(self, qp):
def _solve_qp(self, qp, reshape=True):
raise NotImplementedError()

"""Solve the docplex problem.
Expand All @@ -224,16 +225,41 @@ def _solve_qp(self, qp):
Notes
-----
.. versionadded:: 0.0.2
.. versionchanged:: 0.0.4

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

"""
def solve(self, prob):
def solve(self, prob, reshape=True):
qp = from_docplex_mp(prob)
return self._solve_qp(qp)
return self._solve_qp(qp, reshape)

"""Helper to create a docplex representation of a
weight vector.

Parameters
----------
prob : Model
An instance of the docplex model [1]_
classes : list
The classes.

Returns
-------
docplex_weights : dict
A vector of decision variables representing
our weights.

Notes
-----
.. versionadded:: 0.0.4

"""
def get_weights(self, prob, classes):
raise NotImplementedError()


class ClassicalOptimizer(pyQiskitOptimizer):
Expand All @@ -243,6 +269,7 @@ class ClassicalOptimizer(pyQiskitOptimizer):
Notes
-----
.. versionadded:: 0.0.2
.. versionchanged:: 0.0.4

See Also
--------
Expand Down Expand Up @@ -289,10 +316,40 @@ def __init__(self):
def covmat_var(self, prob, channels, name):
return square_cont_mat_var(prob, channels, name)

def _solve_qp(self, qp):
def _solve_qp(self, qp, reshape=True):
result = CobylaOptimizer(rhobeg=0.01, rhoend=0.0001).solve(qp).x
n_channels = int(math.sqrt(result.shape[0]))
return np.reshape(result, (n_channels, n_channels))
if reshape:
n_channels = int(math.sqrt(result.shape[0]))
return np.reshape(result, (n_channels, n_channels))
return result

"""Helper to create a docplex representation of a
weight vector.

Parameters
----------
prob : Model
An instance of the docplex model [1]_
classes : list
The classes.

Returns
-------
docplex_weights : dict
A vector of continuous decision variables representing
our weights.

Notes
-----
.. versionadded:: 0.0.4

"""
def get_weights(self, prob, classes):
w = prob.continuous_var_matrix(keys1=[1], keys2=classes,
name="weight",
b=0, ub=1)
w = np.array([w[key] for key in w])
return w


class NaiveQAOAOptimizer(pyQiskitOptimizer):
Expand All @@ -307,6 +364,7 @@ class NaiveQAOAOptimizer(pyQiskitOptimizer):
Notes
-----
.. versionadded:: 0.0.2
.. versionchanged:: 0.0.4

See Also
--------
Expand Down Expand Up @@ -378,7 +436,7 @@ def convert_covmat(self, covmat):
def covmat_var(self, prob, channels, name):
return square_int_mat_var(prob, channels, self.upper_bound, name)

def _solve_qp(self, qp):
def _solve_qp(self, qp, reshape=True):
conv = IntegerToBinary()
qubo = conv.convert(qp)
backend = get_simulator()
Expand All @@ -387,5 +445,34 @@ def _solve_qp(self, qp):
initial_point=[0., 0.])
qaoa = MinimumEigenOptimizer(qaoa_mes)
result = conv.interpret(qaoa.solve(qubo))
n_channels = int(math.sqrt(result.shape[0]))
return np.reshape(result, (n_channels, n_channels))
if reshape:
n_channels = int(math.sqrt(result.shape[0]))
return np.reshape(result, (n_channels, n_channels))
return result

"""Helper to create a docplex representation of a
weight vector.

Parameters
----------
prob : Model
An instance of the docplex model [1]_
classes : list
The classes.

Returns
-------
docplex_weights : dict
A vector of integer decision variables representing
our weights.

Notes
-----
.. versionadded:: 0.0.4

"""
def get_weights(self, prob, classes):
w = prob.integer_var_matrix(keys1=[1], keys2=classes,
name="weight", lb=0, ub=self.upper_bound)
w = np.array([w[key] for key in w])
return w