qoro-divi 0.2.0b1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. divi/__init__.py +8 -0
  2. divi/_pbar.py +73 -0
  3. divi/circuits.py +139 -0
  4. divi/exp/cirq/__init__.py +7 -0
  5. divi/exp/cirq/_lexer.py +126 -0
  6. divi/exp/cirq/_parser.py +889 -0
  7. divi/exp/cirq/_qasm_export.py +37 -0
  8. divi/exp/cirq/_qasm_import.py +35 -0
  9. divi/exp/cirq/exception.py +21 -0
  10. divi/exp/scipy/_cobyla.py +342 -0
  11. divi/exp/scipy/pyprima/LICENCE.txt +28 -0
  12. divi/exp/scipy/pyprima/__init__.py +263 -0
  13. divi/exp/scipy/pyprima/cobyla/__init__.py +0 -0
  14. divi/exp/scipy/pyprima/cobyla/cobyla.py +599 -0
  15. divi/exp/scipy/pyprima/cobyla/cobylb.py +849 -0
  16. divi/exp/scipy/pyprima/cobyla/geometry.py +240 -0
  17. divi/exp/scipy/pyprima/cobyla/initialize.py +269 -0
  18. divi/exp/scipy/pyprima/cobyla/trustregion.py +540 -0
  19. divi/exp/scipy/pyprima/cobyla/update.py +331 -0
  20. divi/exp/scipy/pyprima/common/__init__.py +0 -0
  21. divi/exp/scipy/pyprima/common/_bounds.py +41 -0
  22. divi/exp/scipy/pyprima/common/_linear_constraints.py +46 -0
  23. divi/exp/scipy/pyprima/common/_nonlinear_constraints.py +64 -0
  24. divi/exp/scipy/pyprima/common/_project.py +224 -0
  25. divi/exp/scipy/pyprima/common/checkbreak.py +107 -0
  26. divi/exp/scipy/pyprima/common/consts.py +48 -0
  27. divi/exp/scipy/pyprima/common/evaluate.py +101 -0
  28. divi/exp/scipy/pyprima/common/history.py +39 -0
  29. divi/exp/scipy/pyprima/common/infos.py +30 -0
  30. divi/exp/scipy/pyprima/common/linalg.py +452 -0
  31. divi/exp/scipy/pyprima/common/message.py +336 -0
  32. divi/exp/scipy/pyprima/common/powalg.py +131 -0
  33. divi/exp/scipy/pyprima/common/preproc.py +393 -0
  34. divi/exp/scipy/pyprima/common/present.py +5 -0
  35. divi/exp/scipy/pyprima/common/ratio.py +56 -0
  36. divi/exp/scipy/pyprima/common/redrho.py +49 -0
  37. divi/exp/scipy/pyprima/common/selectx.py +346 -0
  38. divi/interfaces.py +25 -0
  39. divi/parallel_simulator.py +258 -0
  40. divi/qasm.py +220 -0
  41. divi/qem.py +191 -0
  42. divi/qlogger.py +119 -0
  43. divi/qoro_service.py +343 -0
  44. divi/qprog/__init__.py +13 -0
  45. divi/qprog/_graph_partitioning.py +619 -0
  46. divi/qprog/_mlae.py +182 -0
  47. divi/qprog/_qaoa.py +440 -0
  48. divi/qprog/_vqe.py +275 -0
  49. divi/qprog/_vqe_sweep.py +144 -0
  50. divi/qprog/batch.py +235 -0
  51. divi/qprog/optimizers.py +75 -0
  52. divi/qprog/quantum_program.py +493 -0
  53. divi/utils.py +116 -0
  54. qoro_divi-0.2.0b1.dist-info/LICENSE +190 -0
  55. qoro_divi-0.2.0b1.dist-info/LICENSES/Apache-2.0.txt +73 -0
  56. qoro_divi-0.2.0b1.dist-info/METADATA +57 -0
  57. qoro_divi-0.2.0b1.dist-info/RECORD +58 -0
  58. qoro_divi-0.2.0b1.dist-info/WHEEL +4 -0
@@ -0,0 +1,263 @@
1
+ # Bounds may appear unused in this file but we need to import it to make it available to the user
2
+ from collections.abc import Iterable
3
+ from enum import Enum
4
+
5
+ import numpy as np
6
+ from scipy.optimize import Bounds, LinearConstraint, NonlinearConstraint
7
+
8
+ from .cobyla.cobyla import cobyla
9
+ from .common._bounds import process_bounds
10
+ from .common._linear_constraints import (
11
+ combine_multiple_linear_constraints,
12
+ separate_LC_into_eq_and_ineq,
13
+ )
14
+ from .common._nonlinear_constraints import process_nl_constraints
15
+ from .common._project import _project
16
+ from .common.linalg import get_arrays_tol
17
+
18
+
19
+ class ConstraintType(Enum):
20
+ LINEAR_OBJECT = 5
21
+ NONLINEAR_OBJECT = 10
22
+ LINEAR_DICT = 15
23
+ NONLINEAR_DICT = 20
24
+
25
+
26
+ def get_constraint_type(constraint):
27
+ if (
28
+ isinstance(constraint, dict)
29
+ and ("A" in constraint)
30
+ and ("lb" in constraint)
31
+ and ("ub" in constraint)
32
+ ):
33
+ return ConstraintType.LINEAR_DICT
34
+ elif (
35
+ isinstance(constraint, dict)
36
+ and ("fun" in constraint)
37
+ and ("lb" in constraint)
38
+ and ("ub" in constraint)
39
+ ):
40
+ return ConstraintType.NONLINEAR_DICT
41
+ elif (
42
+ hasattr(constraint, "A")
43
+ and hasattr(constraint, "lb")
44
+ and hasattr(constraint, "ub")
45
+ ):
46
+ return ConstraintType.LINEAR_OBJECT
47
+ elif (
48
+ hasattr(constraint, "fun")
49
+ and hasattr(constraint, "lb")
50
+ and hasattr(constraint, "ub")
51
+ ):
52
+ return ConstraintType.NONLINEAR_OBJECT
53
+ else:
54
+ raise ValueError(f"Constraint type {type(constraint)} not recognized")
55
+
56
+
57
+ def process_constraints(constraints):
58
+ # First throw it back if it's an empty tuple
59
+ if not constraints:
60
+ return None, None
61
+ # Next figure out if it's a list of constraints or a single constraint
62
+ # If it's a single constraint, make it a list, and then the remaining logic
63
+ # doesn't have to change
64
+ if not isinstance(constraints, Iterable):
65
+ constraints = [constraints]
66
+
67
+ # Separate out the linear and nonlinear constraints
68
+ linear_constraints = []
69
+ nonlinear_constraints = []
70
+ for constraint in constraints:
71
+ constraint_type = get_constraint_type(constraint)
72
+ if constraint_type is ConstraintType.LINEAR_OBJECT:
73
+ linear_constraints.append(constraint)
74
+ elif constraint_type is ConstraintType.NONLINEAR_OBJECT:
75
+ nonlinear_constraints.append(constraint)
76
+ elif constraint_type == ConstraintType.LINEAR_DICT:
77
+ linear_constraints.append(
78
+ LinearConstraint(constraint["A"], constraint["lb"], constraint["ub"])
79
+ )
80
+ elif constraint_type == ConstraintType.NONLINEAR_DICT:
81
+ nonlinear_constraints.append(
82
+ NonlinearConstraint(
83
+ constraint["fun"], constraint["lb"], constraint["ub"]
84
+ )
85
+ )
86
+ else:
87
+ raise ValueError("Constraint type not recognized")
88
+
89
+ if len(nonlinear_constraints) > 0:
90
+ nonlinear_constraint_function = process_nl_constraints(nonlinear_constraints)
91
+ else:
92
+ nonlinear_constraint_function = None
93
+
94
+ # Determine if we have multiple linear constraints, just 1, or none, and process accordingly
95
+ if len(linear_constraints) > 1:
96
+ linear_constraint = combine_multiple_linear_constraints(linear_constraints)
97
+ elif len(linear_constraints) == 1:
98
+ linear_constraint = linear_constraints[0]
99
+ else:
100
+ linear_constraint = None
101
+
102
+ return linear_constraint, nonlinear_constraint_function
103
+
104
+
105
+ def minimize(
106
+ fun,
107
+ x0,
108
+ args=(),
109
+ method=None,
110
+ bounds=None,
111
+ constraints=(),
112
+ callback=None,
113
+ options=None,
114
+ ):
115
+
116
+ linear_constraint, nonlinear_constraint_function = process_constraints(constraints)
117
+
118
+ options = {"quiet": True} if options is None else options
119
+ quiet = options.get("quiet", True)
120
+
121
+ if method is None:
122
+ if nonlinear_constraint_function is not None:
123
+ if not quiet:
124
+ print("Nonlinear constraints detected, applying COBYLA")
125
+ method = "cobyla"
126
+ elif linear_constraint is not None:
127
+ if not quiet:
128
+ print(
129
+ "Linear constraints detected without nonlinear constraints, applying LINCOA"
130
+ )
131
+ method = "lincoa"
132
+ elif bounds is not None:
133
+ if not quiet:
134
+ print(
135
+ "Bounds without linear or nonlinear constraints detected, applying BOBYQA"
136
+ )
137
+ method = "bobyqa"
138
+ else:
139
+ if not quiet:
140
+ print("No bounds or constraints detected, applying NEWUOA")
141
+ method = "newuoa"
142
+ else:
143
+ # Raise some errors if methods were called with inappropriate options
144
+ method = method.lower()
145
+ if method not in ("newuoa", "uobyqa", "bobyqa", "cobyla", "lincoa"):
146
+ raise ValueError(
147
+ f"Method must be one of NEWUOA, UOBYQA, BOBYQA, COBYLA, or LINCOA, not '{method}'"
148
+ )
149
+ if method != "cobyla" and nonlinear_constraint_function is not None:
150
+ raise ValueError(
151
+ "Nonlinear constraints were provided for an algorithm that cannot handle them"
152
+ )
153
+ if method not in ("cobyla", "lincoa") and linear_constraint is not None:
154
+ raise ValueError(
155
+ "Linear constraints were provided for an algorithm that cannot handle them"
156
+ )
157
+ if method not in ("cobyla", "bobyqa", "lincoa") and bounds is not None:
158
+ raise ValueError(
159
+ "Bounds were provided for an algorithm that cannot handle them"
160
+ )
161
+
162
+ # Try to get the length of x0. If we can't that likely means it's a scalar, and
163
+ # in that case we turn it into an array and wrap the original function so that it
164
+ # can accept an array and return a scalar.
165
+ try:
166
+ lenx0 = len(x0)
167
+ except TypeError:
168
+ x0 = np.array([x0])
169
+ original_scalar_fun = fun
170
+
171
+ def scalar_fun(x):
172
+ return original_scalar_fun(x[0], *args)
173
+
174
+ fun = scalar_fun
175
+ lenx0 = 1
176
+
177
+ lb, ub = process_bounds(bounds, lenx0)
178
+
179
+ # Check which variables are fixed and eliminate them from the problem.
180
+ # Save the indices and values so that we can call the original function with
181
+ # an array of the appropriate size, and so that we can add the fixed values to the
182
+ # result when COBYLA returns.
183
+ tol = get_arrays_tol(lb, ub)
184
+ _fixed_idx = (lb <= ub) & (np.abs(lb - ub) < tol)
185
+ if any(_fixed_idx):
186
+ _fixed_values = 0.5 * (lb[_fixed_idx] + ub[_fixed_idx])
187
+ _fixed_values = np.clip(
188
+ _fixed_values,
189
+ lb[_fixed_idx],
190
+ ub[_fixed_idx],
191
+ )
192
+ x0 = x0[~_fixed_idx]
193
+ lb = lb[~_fixed_idx]
194
+ ub = ub[~_fixed_idx]
195
+ original_fun = fun
196
+
197
+ def fixed_fun(x):
198
+ newx = np.zeros(lenx0)
199
+ newx[_fixed_idx] = _fixed_values
200
+ newx[~_fixed_idx] = x
201
+ return original_fun(newx, *args)
202
+
203
+ fun = fixed_fun
204
+
205
+ # Project x0 onto the feasible set
206
+ if nonlinear_constraint_function is None:
207
+ result = _project(x0, lb, ub, {"linear": linear_constraint, "nonlinear": None})
208
+ x0 = result.x
209
+
210
+ if linear_constraint is not None:
211
+ A_eq, b_eq, A_ineq, b_ineq = separate_LC_into_eq_and_ineq(linear_constraint)
212
+ else:
213
+ A_eq, b_eq, A_ineq, b_ineq = None, None, None, None
214
+
215
+ if nonlinear_constraint_function is not None:
216
+ # If there is a nonlinear constraint function, we will call COBYLA, which needs the number of nonlinear
217
+ # constraints (m_nlcon). In order to get this number we need to evaluate the constraint function at x0.
218
+ # The constraint value at x0 (nlconstr0) is not discarded but passed down to the Fortran backend, as its
219
+ # evaluation is assumed to be expensive. We also evaluate the objective function at x0 and pass the result
220
+ # (f0) down to the Fortran backend, which expects nlconstr0 and f0 to be provided in sync.
221
+ def calcfc(x):
222
+ f = fun(x, *args)
223
+ nlconstr = nonlinear_constraint_function(x)
224
+ return f, nlconstr
225
+
226
+ else:
227
+
228
+ def calcfc(x):
229
+ f = fun(x, *args)
230
+ constr = np.zeros(0)
231
+ return f, constr
232
+
233
+ f0, nlconstr0 = calcfc(x0)
234
+
235
+ if "quiet" in options:
236
+ del options["quiet"]
237
+
238
+ if "maxfev" in options:
239
+ options["maxfun"] = options["maxfev"]
240
+ del options["maxfev"]
241
+
242
+ result = cobyla(
243
+ calcfc,
244
+ len(nlconstr0),
245
+ x0,
246
+ A_ineq,
247
+ b_ineq,
248
+ A_eq,
249
+ b_eq,
250
+ lb,
251
+ ub,
252
+ f0=f0,
253
+ nlconstr0=nlconstr0,
254
+ callback=callback,
255
+ **options,
256
+ )
257
+
258
+ if any(_fixed_idx):
259
+ newx = np.zeros(lenx0)
260
+ newx[_fixed_idx] = _fixed_values
261
+ newx[~_fixed_idx] = result.x
262
+ result.x = newx
263
+ return result
File without changes