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,393 @@
1
+ """
2
+ This is a module that preprocesses the inputs.
3
+
4
+ Translated from Zaikun Zhang's modern-Fortran reference implementation in PRIMA.
5
+
6
+ Dedicated to late Professor M. J. D. Powell FRS (1936--2015).
7
+
8
+ Python translation by Nickolai Belakovski.
9
+ """
10
+
11
+ from warnings import warn
12
+
13
+ import numpy as np
14
+
15
+ from .consts import (
16
+ CTOL_DEFAULT,
17
+ CWEIGHT_DEFAULT,
18
+ DEBUGGING,
19
+ EPS,
20
+ ETA1_DEFAULT,
21
+ ETA2_DEFAULT,
22
+ FTARGET_DEFAULT,
23
+ GAMMA1_DEFAULT,
24
+ GAMMA2_DEFAULT,
25
+ IPRINT_DEFAULT,
26
+ MAXFILT_DEFAULT,
27
+ MAXHISTMEM,
28
+ MIN_MAXFILT,
29
+ RHOBEG_DEFAULT,
30
+ RHOEND_DEFAULT,
31
+ )
32
+ from .present import present
33
+
34
+
35
+ def preproc(
36
+ solver,
37
+ num_vars,
38
+ iprint,
39
+ maxfun,
40
+ maxhist,
41
+ ftarget,
42
+ rhobeg,
43
+ rhoend,
44
+ num_constraints=None,
45
+ npt=None,
46
+ maxfilt=None,
47
+ ctol=None,
48
+ cweight=None,
49
+ eta1=None,
50
+ eta2=None,
51
+ gamma1=None,
52
+ gamma2=None,
53
+ is_constrained=None,
54
+ has_rhobeg=None,
55
+ honour_x0=None,
56
+ xl=None,
57
+ xu=None,
58
+ x0=None,
59
+ ):
60
+ """
61
+ This subroutine preprocesses the inputs. It does nothing to the inputs that are valid.
62
+ """
63
+ # Preconditions
64
+ if DEBUGGING:
65
+ assert num_vars >= 1
66
+ if present(num_constraints):
67
+ assert num_constraints >= 0
68
+ assert num_constraints == 0 or solver.lower() == "cobyla"
69
+ if (
70
+ solver.lower() == "cobyla"
71
+ and present(num_constraints)
72
+ and present(is_constrained)
73
+ ):
74
+ assert num_constraints == 0 or is_constrained
75
+ if solver.lower() == "bobyqa":
76
+ assert present(xl) and present(xu)
77
+ assert all(xu - xl >= 2 * EPS)
78
+ if present(honour_x0):
79
+ assert (
80
+ solver.lower() == "bobyqa"
81
+ and present(has_rhobeg)
82
+ and present(xl)
83
+ and present(xu)
84
+ and present(x0)
85
+ )
86
+
87
+ # ====================#
88
+ # Calculation starts #
89
+ # ====================#
90
+
91
+ # Read num_constraints, if necessary
92
+ num_constraints = (
93
+ num_constraints
94
+ if (present(num_constraints) and solver.lower() == "cobyla")
95
+ else 0
96
+ )
97
+
98
+ # Decide whether the problem is truly constrained
99
+ is_constrained = (
100
+ is_constrained if (present(is_constrained)) else num_constraints > 0
101
+ )
102
+
103
+ # Validate IPRINT
104
+ if np.abs(iprint) > 3:
105
+ iprint = IPRINT_DEFAULT
106
+ warn(
107
+ f"{solver}: Invalid IPRINT; it should be 0, 1, -1, 2, -2, 3, or -3; it is set to {iprint}"
108
+ )
109
+
110
+ # Validate MAXFUN
111
+ if solver.lower() == "uobyqa":
112
+ min_maxfun = (num_vars + 1) * (num_vars + 2) / 2 + 1
113
+ min_maxfun_str = "(N+1)(N+2)/2 + 1"
114
+ elif solver.lower() == "cobyla":
115
+ min_maxfun = num_vars + 2
116
+ min_maxfun_str = "num_vars + 2"
117
+ else: # CASE ('NEWUOA', 'BOBYQA', 'LINCOA')
118
+ min_maxfun = num_vars + 3
119
+ min_maxfun_str = "num_vars + 3"
120
+ if maxfun < min_maxfun:
121
+ maxfun = min_maxfun
122
+ warn(
123
+ f"{solver}: Invalid MAXFUN; it should be at least {min_maxfun_str}; it is set to {maxfun}"
124
+ )
125
+
126
+ # Validate MAXHIST
127
+ if maxhist < 0:
128
+ maxhist = maxfun
129
+ warn(
130
+ f"{solver}: Invalid MAXHIST; it should be a nonnegative integer; it is set to {maxhist}"
131
+ )
132
+ maxhist = min(maxhist, maxfun) # MAXHIST > MAXFUN is never needed.
133
+
134
+ # Validate FTARGET
135
+ if np.isnan(ftarget):
136
+ ftarget = FTARGET_DEFAULT
137
+ warn(
138
+ f"{solver}: Invalid FTARGET; it should be a real number; it is set to {ftarget}"
139
+ )
140
+
141
+ # Validate NPT
142
+ if (
143
+ solver.lower() == "newuoa"
144
+ or solver.lower() == "bobyqa"
145
+ or solver.lower() == "lincoa"
146
+ ) and present(npt):
147
+ if npt < num_vars + 2 or npt > min(
148
+ maxfun - 1, ((num_vars + 2) * (num_vars + 1)) / 2
149
+ ):
150
+ npt = int(min(maxfun - 1, 2 * num_vars + 1))
151
+ warn(
152
+ f"{solver}: Invalid NPT; it should be an integer in the interval [N+2, (N+1)(N+2)/2] and less than MAXFUN; it is set to {npt}"
153
+ )
154
+
155
+ # Validate MAXFILT
156
+ if present(maxfilt) and (solver.lower() == "lincoa" or solver.lower() == "cobyla"):
157
+ maxfilt_in = maxfilt
158
+ if maxfilt < 1:
159
+ maxfilt = MAXFILT_DEFAULT # The inputted MAXFILT is obviously wrong.
160
+ else:
161
+ maxfilt = max(MIN_MAXFILT, maxfilt) # The inputted MAXFILT is too small.
162
+ # Further revise MAXFILT according to MAXHISTMEM.
163
+ if solver.lower() == "lincoa":
164
+ unit_memo = (num_vars + 2) * np.dtype(float).itemsize
165
+ elif solver.lower() == "cobyla":
166
+ unit_memo = (num_constraints + num_vars + 2) * np.dtype(float).itemsize
167
+ else:
168
+ unit_memo = 1
169
+ # We cannot simply set MAXFILT = MIN(MAXFILT, MAXHISTMEM/...), as they may not have
170
+ # the same kind, and compilers may complain. We may convert them, but overflow may occur.
171
+ if maxfilt > MAXHISTMEM / unit_memo:
172
+ maxfilt = int(MAXHISTMEM / unit_memo) # Integer division.
173
+ maxfilt = min(maxfun, max(MIN_MAXFILT, maxfilt))
174
+ if is_constrained:
175
+ if maxfilt_in < 1:
176
+ warn(
177
+ f"{solver}: Invalid MAXFILT; it should be a positive integer; it is set to {maxfilt}"
178
+ )
179
+ elif maxfilt_in < min(maxfun, MIN_MAXFILT):
180
+ warn(f"{solver}: MAXFILT is too small; it is set to {maxfilt}")
181
+ elif maxfilt < min(maxfilt_in, maxfun):
182
+ warn(f"{solver}: MAXFILT is set to {maxfilt} due to memory limit")
183
+
184
+ # Validate ETA1 and ETA2
185
+ eta1_local = eta1 if present(eta1) else ETA1_DEFAULT
186
+ eta2_local = eta2 if present(eta2) else ETA2_DEFAULT
187
+
188
+ # When the difference between ETA1 and ETA2 is tiny, we force them to equal.
189
+ # See the explanation around RHOBEG and RHOEND for the reason.
190
+ if present(eta1) and present(eta2):
191
+ if np.abs(eta1 - eta2) < 1.0e2 * EPS * max(np.abs(eta1), 1):
192
+ eta2 = eta1
193
+
194
+ if present(eta1):
195
+ if np.isnan(eta1):
196
+ # In this case, we take the value hard coded in Powell's original code
197
+ # without any warning. It is useful when interfacing with MATLAB/Python.
198
+ eta1 = ETA1_DEFAULT
199
+ elif eta1 < 0 or eta1 >= 1:
200
+ # Take ETA2 into account if it has a valid value.
201
+ if present(eta2) and eta2_local > 0 and eta2_local <= 1:
202
+ eta1 = max(EPS, eta2 / 7.0)
203
+ else:
204
+ eta1 = ETA1_DEFAULT
205
+ warn(
206
+ f"{solver}: Invalid ETA1; it should be in the interval [0, 1) and not more than ETA2; it is set to {eta1}"
207
+ )
208
+
209
+ if present(eta2):
210
+ if np.isnan(eta2):
211
+ # In this case, we take the value hard coded in Powell's original code
212
+ # without any warning. It is useful when interfacing with MATLAB/Python.
213
+ eta2 = ETA2_DEFAULT
214
+ elif present(eta1) and (eta2 < eta1_local or eta2 > 1):
215
+ eta2 = (eta1 + 2) / 3.0
216
+ warn(
217
+ f"{solver}: Invalid ETA2; it should be in the interval [0, 1) and not less than ETA1; it is set to {eta2}"
218
+ )
219
+
220
+ # Validate GAMMA1 and GAMMA2
221
+ if present(gamma1):
222
+ if np.isnan(gamma1):
223
+ # In this case, we take the value hard coded in Powell's original code
224
+ # without any warning. It is useful when interfacing with MATLAB/Python.
225
+ gamma1 = GAMMA1_DEFAULT
226
+ elif gamma1 <= 0 or gamma1 >= 1:
227
+ gamma1 = GAMMA1_DEFAULT
228
+ warn(
229
+ f"{solver}: Invalid GAMMA1; it should in the interval (0, 1); it is set to {gamma1}"
230
+ )
231
+
232
+ if present(gamma2):
233
+ if np.isnan(gamma2):
234
+ # In this case, we take the value hard coded in Powell's original code
235
+ # without any warning. It is useful when interfacing with MATLAB/Python.
236
+ gamma2 = GAMMA2_DEFAULT
237
+ elif gamma2 < 1 or np.isinf(gamma2):
238
+ gamma2 = GAMMA2_DEFAULT
239
+ warn(
240
+ f"{solver}: Invalid GAMMA2; it should be a real number not less than 1; it is set to {gamma2}"
241
+ )
242
+
243
+ # Validate RHOBEG and RHOEND
244
+
245
+ if np.abs(rhobeg - rhoend) < 1.0e2 * EPS * np.maximum(np.abs(rhobeg), 1):
246
+ # When the data is passed from the interfaces (e.g., MEX) to the Fortran code, RHOBEG, and RHOEND
247
+ # may change a bit. It was observed in a MATLAB test that MEX passed 1 to Fortran as
248
+ # 0.99999999999999978. Therefore, if we set RHOEND = RHOBEG in the interfaces, then it may happen
249
+ # that RHOEND > RHOBEG, which is considered as an invalid input. To avoid this situation, we
250
+ # force RHOBEG and RHOEND to equal when the difference is tiny.
251
+ rhoend = rhobeg
252
+
253
+ # Revise the default values for RHOBEG/RHOEND according to the solver.
254
+ if solver.lower() == "bobyqa":
255
+ rhobeg_default = np.maximum(EPS, np.min(RHOBEG_DEFAULT, np.min(xu - xl) / 4.0))
256
+ rhoend_default = np.maximum(EPS, np.min(0.1 * rhobeg_default, RHOEND_DEFAULT))
257
+ else:
258
+ rhobeg_default = RHOBEG_DEFAULT
259
+ rhoend_default = RHOEND_DEFAULT
260
+
261
+ if solver.lower() == "bobyqa":
262
+ # Do NOT merge the IF below into the ELIF above! Otherwise, XU and XL may be accessed even if
263
+ # the solver is not BOBYQA, because the logical evaluation is not short-circuit.
264
+ if rhobeg > np.min(xu - xl) / 2:
265
+ # Do NOT make this revision if RHOBEG not positive or not finite, because otherwise RHOBEG
266
+ # will get a huge value when XU or XL contains huge values that indicate unbounded variables.
267
+ rhobeg = np.min(xu - xl) / 4.0 # Here, we do not take RHOBEG_DEFAULT.
268
+ warn(
269
+ f"{solver}: Invalid RHOBEG; {solver} requires 0 < RHOBEG <= np.min(XU-XL)/2; it is set to np.min(XU-XL)/4"
270
+ )
271
+ if rhobeg <= 0 or np.isnan(rhobeg) or np.isinf(rhobeg):
272
+ # Take RHOEND into account if it has a valid value. We do not do this if the solver is BOBYQA,
273
+ # which requires that RHOBEG <= (XU-XL)/2.
274
+ if np.isfinite(rhoend) and rhoend > 0 and solver.lower() != "bobyqa":
275
+ rhobeg = max(10 * rhoend, rhobeg_default)
276
+ else:
277
+ rhobeg = rhobeg_default
278
+ warn(
279
+ f"{solver}: Invalid RHOBEG; it should be a positive number; it is set to {rhobeg}"
280
+ )
281
+
282
+ if rhoend <= 0 or rhobeg < rhoend or np.isnan(rhoend) or np.isinf(rhoend):
283
+ rhoend = max(EPS, min(0.1 * rhobeg, rhoend_default))
284
+ warn(
285
+ f"{solver}: Invalid RHOEND; it should be a positive number and RHOEND <= RHOBEG; it is set to {rhoend}"
286
+ )
287
+
288
+ # For BOBYQA, revise X0 or RHOBEG so that the distance between X0 and the inactive bounds is at
289
+ # least RHOBEG. If HONOUR_X0 == TRUE, revise RHOBEG if needed; otherwise, revise HONOUR_X0 if needed.
290
+ if present(honour_x0):
291
+ if honour_x0:
292
+ rhobeg_old = rhobeg
293
+ lbx = np.isfinite(xl) & (
294
+ x0 - xl <= EPS * np.maximum(1, np.abs(xl))
295
+ ) # X0 essentially equals XL
296
+ ubx = np.isfinite(xu) & (
297
+ x0 - xu >= -EPS * np.maximum(1, np.abs(xu))
298
+ ) # X0 essentially equals XU
299
+ x0[lbx] = xl[lbx]
300
+ x0[ubx] = xu[ubx]
301
+ rhobeg = max(
302
+ EPS, np.min([rhobeg, x0[~lbx] - xl[~lbx], xu[~ubx] - x0[~ubx]])
303
+ )
304
+ if rhobeg_old - rhobeg > EPS * max(1, rhobeg_old):
305
+ rhoend = max(
306
+ EPS, min(0.1 * rhobeg, rhoend)
307
+ ) # We do not revise RHOEND unless RHOBEG is truly revised.
308
+ if has_rhobeg:
309
+ warn(
310
+ f"{solver}: RHOBEG is revised to {rhobeg} and RHOEND to at most 0.1*RHOBEG so that the distance between X0 and the inactive bounds is at least RHOBEG"
311
+ )
312
+ else:
313
+ rhoend = np.minimum(rhoend, rhobeg) # This may update RHOEND slightly.
314
+ else:
315
+ x0_old = x0 # Recorded to see whether X0 is really revised.
316
+ # N.B.: The following revision is valid only if XL <= X0 <= XU and RHOBEG <= MINVAL(XU-XL)/2,
317
+ # which should hold at this point due to the revision of RHOBEG and moderation of X0.
318
+ # The cases below are mutually exclusive in precise arithmetic as MINVAL(XU-XL) >= 2*RHOBEG.
319
+ lbx = x0 <= xl + 0.5 * rhobeg
320
+ lbx_plus = (x0 > xl + 0.5 * rhobeg) & (x0 < xl + rhobeg)
321
+ ubx = x0 >= xu - 0.5 * rhobeg
322
+ ubx_minus = (x0 < xu - 0.5 * rhobeg) & (x0 > xu - rhobeg)
323
+ x0[lbx] = xl[lbx]
324
+ x0[lbx_plus] = xl[lbx_plus] + rhobeg
325
+ x0[ubx] = xu[ubx]
326
+ x0[ubx_minus] = xu[ubx_minus] - rhobeg
327
+
328
+ if any(np.abs(x0_old - x0) > 0):
329
+ warn(
330
+ f"{solver}: X0 is revised so that the distance between X0 and the inactive bounds is at least RHOBEG set HONOUR_X0 to .TRUE. if you prefer to keep X0 unchanged"
331
+ )
332
+
333
+ # Validate CTOL (it can be 0)
334
+ if present(ctol):
335
+ if np.isnan(ctol) or ctol < 0:
336
+ ctol = CTOL_DEFAULT
337
+ if is_constrained:
338
+ warn(
339
+ f"{solver}: Invalid CTOL; it should be a nonnegative number; it is set to {ctol}"
340
+ )
341
+
342
+ # Validate CWEIGHT (it can be +Inf)
343
+ if present(cweight):
344
+ if np.isnan(cweight) or cweight < 0:
345
+ cweight = CWEIGHT_DEFAULT
346
+ if is_constrained:
347
+ warn(
348
+ f"{solver}: Invalid CWEIGHT; it should be a nonnegative number; it is set to {cweight}"
349
+ )
350
+
351
+ # ====================#
352
+ # Calculation ends #
353
+ # ====================#
354
+
355
+ # Postconditions
356
+ if DEBUGGING:
357
+ assert abs(iprint) <= 3
358
+ assert maxhist >= 0 and maxhist <= maxfun
359
+ if present(npt):
360
+ assert maxfun >= npt + 1
361
+ assert npt >= 3
362
+ if present(maxfilt):
363
+ assert maxfilt >= np.minimum(MIN_MAXFILT, maxfun) and maxfilt <= maxfun
364
+ if present(eta1) and present(eta2):
365
+ assert eta1 >= 0 and eta1 <= eta2 and eta2 < 1
366
+ if present(gamma1) and present(gamma2):
367
+ assert gamma1 > 0 and gamma1 < 1 and gamma2 > 1
368
+ assert rhobeg >= rhoend and rhoend > 0
369
+ if solver.lower() == "bobyqa":
370
+ assert all(rhobeg <= (xu - xl) / 2)
371
+ assert all(np.isfinite(x0))
372
+ assert all(x0 >= xl and (x0 <= xl or x0 >= xl + rhobeg))
373
+ assert all(x0 <= xu and (x0 >= xu or x0 <= xu - rhobeg))
374
+ if present(ctol):
375
+ assert ctol >= 0
376
+
377
+ return (
378
+ iprint,
379
+ maxfun,
380
+ maxhist,
381
+ ftarget,
382
+ rhobeg,
383
+ rhoend,
384
+ npt,
385
+ maxfilt,
386
+ ctol,
387
+ cweight,
388
+ eta1,
389
+ eta2,
390
+ gamma1,
391
+ gamma2,
392
+ x0,
393
+ )
@@ -0,0 +1,5 @@
1
+ def present(x):
2
+ """
3
+ This is a Python equivalent of the Fortran 'present' function for optional arguments.
4
+ """
5
+ return x is not None
@@ -0,0 +1,56 @@
1
+ """
2
+ This module calculates the reduction ratio for trust-region methods.
3
+
4
+ Translated from Zaikun Zhang's modern-Fortran reference implementation in PRIMA.
5
+
6
+ Dedicated to late Professor M. J. D. Powell FRS (1936--2015).
7
+
8
+ Python translation by Nickolai Belakovski.
9
+ """
10
+
11
+ import numpy as np
12
+
13
+ from .consts import DEBUGGING, REALMAX
14
+
15
+
16
+ def redrat(ared, pred, rshrink):
17
+ """
18
+ This function evaluates the reduction ratio of a trust-region step, handling inf/nan properly.
19
+ """
20
+
21
+ # Preconditions
22
+ if DEBUGGING:
23
+ assert rshrink >= 0
24
+
25
+ # ====================#
26
+ # Calculation starts #
27
+ # ====================#
28
+
29
+ if np.isnan(ared):
30
+ # This should not happen in unconstrained problems due to the moderated extreme barrier.
31
+ ratio = -REALMAX
32
+ elif np.isnan(pred) or pred <= 0:
33
+ # The trust-region subproblem solver fails in this rare case. Instead of terminating as Powell's
34
+ # original code does, we set ratio as follows so that the solver may continue to progress.
35
+ if ared > 0:
36
+ # The trial point will be accepted, but the trust-region radius will be shrunk if rshrink>0
37
+ ratio = rshrink / 2
38
+ else:
39
+ # Set the ration to a large negative number to signify a bad trust-region step, so that the
40
+ # solver will check whether to take a geometry step or reduce rho.
41
+ ratio = -REALMAX
42
+ elif np.isposinf(pred) and np.isposinf(ared):
43
+ ratio = 1 # ared/pred = NaN if calculated directly
44
+ elif np.isposinf(pred) and np.isneginf(ared):
45
+ ratio = -REALMAX # ared/pred = NaN if calculated directly
46
+ else:
47
+ ratio = ared / pred
48
+
49
+ # ==================#
50
+ # Calculation ends #
51
+ # ==================#
52
+
53
+ # Postconditions
54
+ if DEBUGGING:
55
+ assert not np.isnan(ratio)
56
+ return ratio
@@ -0,0 +1,49 @@
1
+ """
2
+ This module provides a function that calculates RHO when it needs to be reduced.
3
+
4
+ Translated from Zaikun Zhang's modern-Fortran reference implementation in PRIMA.
5
+
6
+ Dedicated to late Professor M. J. D. Powell FRS (1936--2015).
7
+
8
+ Python translation by Nickolai Belakovski.
9
+ """
10
+
11
+ import numpy as np
12
+
13
+ from .consts import DEBUGGING
14
+
15
+
16
+ def redrho(rho_in, rhoend):
17
+ """
18
+ This function calculates RHO when it needs to be reduced.
19
+ The scheme is shared by UOBYQA, NEWUOA, BOBYQA, LINCOA. For COBYLA, Powell's code reduces RHO by
20
+ 'RHO *= 0.5; if RHO <= 1.5 * RHOEND: RHO = RHOEND' as specified in (11) of the COBYLA
21
+ paper. However, this scheme seems to work better, especially after we introduce DELTA.
22
+ """
23
+
24
+ # Preconditions
25
+ if DEBUGGING:
26
+ assert rho_in > rhoend > 0
27
+
28
+ # ====================#
29
+ # Calculation starts #
30
+ # ====================#
31
+
32
+ rho_ratio = rho_in / rhoend
33
+
34
+ if rho_ratio > 250:
35
+ rho = 0.1 * rho_in
36
+ elif rho_ratio <= 16:
37
+ rho = rhoend
38
+ else:
39
+ rho = np.sqrt(rho_ratio) * rhoend # rho = np.sqrt(rho * rhoend)
40
+
41
+ # ==================#
42
+ # Calculation ends #
43
+ # ==================#
44
+
45
+ # Postconditions
46
+ if DEBUGGING:
47
+ assert rho_in > rho >= rhoend
48
+
49
+ return rho