57
57
58
58
"""
59
59
60
- from typing import Tuple
60
+ from typing import Tuple , Union , List
61
61
import logging
62
62
from math import fsum
63
63
64
64
import numpy as np
65
65
from docplex .mp .constants import ComparisonType
66
+ from docplex .mp .constr import LinearConstraint , QuadraticConstraint
67
+ from docplex .mp .linear import Var
66
68
from docplex .mp .model import Model
67
69
from qiskit .quantum_info import Pauli
68
70
@@ -113,7 +115,7 @@ def get_operator(mdl: Model, auto_penalty: bool = True,
113
115
# initialize Hamiltonian.
114
116
num_nodes = len (q_d )
115
117
pauli_list = []
116
- shift = 0
118
+ shift = 0.
117
119
zero = np .zeros (num_nodes , dtype = np .bool )
118
120
119
121
# convert a constant part of the object function into Hamiltonian.
@@ -157,13 +159,15 @@ def get_operator(mdl: Model, auto_penalty: bool = True,
157
159
158
160
# convert constraints into penalty terms.
159
161
for constraint in mdl .iter_constraints ():
160
- constant = constraint .cplex_num_rhs ()
162
+ right_cst = constraint .get_right_expr ().get_constant ()
163
+ left_cst = constraint .get_left_expr ().get_constant ()
164
+ constant = float (right_cst - left_cst )
161
165
162
166
# constant parts of penalty*(Constant-func)**2: penalty*(Constant**2)
163
167
shift += penalty * constant ** 2
164
168
165
169
# linear parts of penalty*(Constant-func)**2: penalty*(-2*Constant*func)
166
- for __l in constraint . iter_net_linear_coefs ( ):
170
+ for __l in _iter_net_linear_coeffs ( constraint ):
167
171
z_p = np .zeros (num_nodes , dtype = np .bool )
168
172
index = q_d [__l [0 ]]
169
173
weight = __l [1 ]
@@ -173,8 +177,8 @@ def get_operator(mdl: Model, auto_penalty: bool = True,
173
177
shift += - penalty * constant * weight
174
178
175
179
# quadratic parts of penalty*(Constant-func)**2: penalty*(func**2)
176
- for __l in constraint . iter_net_linear_coefs ( ):
177
- for l_2 in constraint . iter_net_linear_coefs ( ):
180
+ for __l in _iter_net_linear_coeffs ( constraint ):
181
+ for l_2 in _iter_net_linear_coeffs ( constraint ):
178
182
index1 = q_d [__l [0 ]]
179
183
index2 = q_d [l_2 [0 ]]
180
184
weight1 = __l [1 ]
@@ -205,6 +209,35 @@ def get_operator(mdl: Model, auto_penalty: bool = True,
205
209
return qubit_op , shift
206
210
207
211
212
+ def _iter_net_linear_coeffs (constraint : Union [LinearConstraint , QuadraticConstraint ]) \
213
+ -> List [Tuple [Var , float ]]:
214
+ """
215
+ Builds a list of tuples, where each tuple contains a decision variable and a
216
+ corresponding coefficient of this variable in the constraint.
217
+
218
+ Args:
219
+ constraint: A constraint to analyze.
220
+
221
+ Returns:
222
+ A list of tuples of variables and coefficients.
223
+ """
224
+ left_expr = constraint .get_left_expr ()
225
+ right_expr = constraint .get_right_expr ()
226
+ # for linear constraints we may get an instance of Var instead of expression,
227
+ # e.g. x + y = z
228
+ if isinstance (left_expr , Var ):
229
+ left_expr = left_expr + 0
230
+ if isinstance (right_expr , Var ):
231
+ right_expr = right_expr + 0
232
+
233
+ variables = {}
234
+ for var in left_expr .iter_variables ():
235
+ variables [var ] = left_expr .get_coef (var )
236
+ for var in right_expr .iter_variables ():
237
+ variables [var ] = variables .get (var , 0.0 ) - right_expr .get_coef (var )
238
+ return list (variables .items ())
239
+
240
+
208
241
def _validate_input_model (mdl : Model ) -> None :
209
242
"""Check whether an input model is valid. If not, raise an AquaError.
210
243
0 commit comments