luna-quantum 1.0.0__cp313-cp313-win_amd64.whl → 1.0.1rc9__cp313-cp313-win_amd64.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.
Potentially problematic release.
This version of luna-quantum might be problematic. Click here for more details.
- luna_quantum/__init__.py +31 -17
- luna_quantum/__init__.pyi +22 -14
- luna_quantum/_core.cp313-win_amd64.pyd +0 -0
- luna_quantum/_core.pyi +1040 -375
- luna_quantum/algorithms/__init__.py +1 -0
- luna_quantum/backends/__init__.py +1 -0
- luna_quantum/client/rest_client/qpu_token_rest_client.py +7 -3
- luna_quantum/client/schemas/circuit.py +5 -6
- luna_quantum/client/schemas/create/__init__.py +10 -1
- luna_quantum/client/schemas/create/circuit.py +5 -6
- luna_quantum/client/schemas/create/qpu_token.py +2 -5
- luna_quantum/client/schemas/create/qpu_token_time_quota.py +3 -6
- luna_quantum/client/schemas/create/qpu_token_time_quota_update.py +15 -0
- luna_quantum/client/schemas/create/solve_job_create.py +1 -1
- luna_quantum/client/schemas/qpu_token/qpu_token.py +9 -16
- luna_quantum/client/schemas/qpu_token/token_provider.py +3 -6
- luna_quantum/errors.py +34 -1
- luna_quantum/errors.pyi +77 -26
- luna_quantum/solve/domain/solve_job.py +2 -2
- luna_quantum/solve/parameters/algorithms/base_params/quantum_annealing_params.py +1 -0
- luna_quantum/solve/parameters/algorithms/base_params/scipy_optimizer.py +4 -2
- luna_quantum/solve/parameters/algorithms/quantum_annealing/quantum_annealing.py +38 -22
- luna_quantum/solve/parameters/algorithms/quantum_gate/flex_qaoa/optimizers.py +4 -2
- luna_quantum/solve/parameters/algorithms/quantum_gate/qaoa.py +1 -3
- luna_quantum/solve/parameters/algorithms/quantum_gate/vqe.py +2 -3
- luna_quantum/solve/parameters/algorithms/search_algorithms/dialectic_search.py +0 -16
- luna_quantum/solve/parameters/backends/__init__.py +1 -1
- luna_quantum/solve/parameters/backends/dwave_qpu.py +4 -2
- luna_quantum/solve/parameters/backends/ibm.py +8 -2
- luna_quantum/solve/parameters/backends/qctrl.py +4 -3
- luna_quantum/solve/use_cases/hamiltonian_cycle.py +2 -2
- luna_quantum/solve/usecases/solve_job_get_result_usecase.py +1 -3
- luna_quantum/translator.py +23 -1
- luna_quantum/translator.pyi +76 -43
- luna_quantum/utils.py +29 -11
- {luna_quantum-1.0.0.dist-info → luna_quantum-1.0.1rc9.dist-info}/METADATA +2 -4
- {luna_quantum-1.0.0.dist-info → luna_quantum-1.0.1rc9.dist-info}/RECORD +40 -37
- {luna_quantum-1.0.0.dist-info → luna_quantum-1.0.1rc9.dist-info}/WHEEL +1 -1
- {luna_quantum-1.0.0.dist-info → luna_quantum-1.0.1rc9.dist-info}/licenses/LICENSE +1 -1
- {luna_quantum-1.0.0.dist-info → luna_quantum-1.0.1rc9.dist-info}/licenses/NOTICE +0 -0
luna_quantum/_core.pyi
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
from datetime import datetime, timedelta
|
|
2
2
|
from enum import Enum
|
|
3
|
-
from
|
|
4
|
-
|
|
3
|
+
from types import TracebackType
|
|
4
|
+
from typing import Literal, Self, overload
|
|
5
5
|
from numpy.typing import NDArray
|
|
6
|
+
from . import errors, translator
|
|
7
|
+
from luna_quantum.client.interfaces.services.luna_solve_i import ILunaSolve
|
|
8
|
+
from luna_quantum.solve.domain.model_metadata import ModelMetadata
|
|
9
|
+
from luna_quantum.solve.domain.solve_job import SolveJob
|
|
6
10
|
|
|
7
|
-
from . import exceptions, translator
|
|
8
|
-
from .client.interfaces.services.luna_solve_i import ILunaSolve
|
|
9
|
-
from .solve import ModelMetadata
|
|
10
|
-
from .solve.domain.solve_job import SolveJob
|
|
11
|
-
|
|
12
|
-
# _variable.pyi
|
|
13
11
|
class Vtype(Enum):
|
|
14
12
|
"""
|
|
15
13
|
Enumeration of variable types supported by the optimization system.
|
|
@@ -45,10 +43,12 @@ class Vtype(Enum):
|
|
|
45
43
|
"""Discrete integer-valued variable. Takes integer values within bounds."""
|
|
46
44
|
Binary = ...
|
|
47
45
|
"""Binary variable. Can only take values 0 or 1."""
|
|
48
|
-
|
|
49
46
|
Spin = ...
|
|
50
47
|
"""Spin variable. Can only take values -1 or +1."""
|
|
51
48
|
|
|
49
|
+
def __str__(self, /) -> str: ...
|
|
50
|
+
def __repr__(self, /) -> str: ...
|
|
51
|
+
|
|
52
52
|
class Unbounded: ...
|
|
53
53
|
|
|
54
54
|
class Bounds:
|
|
@@ -85,33 +85,38 @@ class Bounds:
|
|
|
85
85
|
"""
|
|
86
86
|
|
|
87
87
|
@overload
|
|
88
|
-
def __init__(self, /, *, lower: float | Unbounded) -> None: ...
|
|
88
|
+
def __init__(self, /, *, lower: (float | type[Unbounded])) -> None: ...
|
|
89
89
|
@overload
|
|
90
|
-
def __init__(self, /, *, upper: float | type[Unbounded]) -> None: ...
|
|
90
|
+
def __init__(self, /, *, upper: (float | type[Unbounded])) -> None: ...
|
|
91
91
|
@overload
|
|
92
92
|
def __init__(
|
|
93
|
-
self, /, lower: float | type[Unbounded], upper: float | type[Unbounded]
|
|
93
|
+
self, /, lower: (float | type[Unbounded]), upper: (float | type[Unbounded])
|
|
94
94
|
) -> None: ...
|
|
95
|
-
@overload
|
|
96
95
|
def __init__(
|
|
97
96
|
self,
|
|
98
97
|
/,
|
|
99
|
-
lower: float | type[Unbounded] | None = ...,
|
|
100
|
-
upper: float | type[Unbounded] | None = ...,
|
|
98
|
+
lower: (float | type[Unbounded] | None) = ...,
|
|
99
|
+
upper: (float | type[Unbounded] | None) = ...,
|
|
101
100
|
) -> None:
|
|
102
101
|
"""
|
|
103
102
|
Create bounds for a variable.
|
|
104
103
|
|
|
105
104
|
See class-level docstring for full documentation.
|
|
106
105
|
"""
|
|
106
|
+
...
|
|
107
107
|
|
|
108
108
|
@property
|
|
109
109
|
def lower(self, /) -> float | Unbounded | None:
|
|
110
|
-
"""Get the lower bound"""
|
|
110
|
+
"""Get the lower bound."""
|
|
111
|
+
...
|
|
111
112
|
|
|
112
113
|
@property
|
|
113
114
|
def upper(self, /) -> float | Unbounded | None:
|
|
114
|
-
"""Get the upper bound"""
|
|
115
|
+
"""Get the upper bound."""
|
|
116
|
+
...
|
|
117
|
+
|
|
118
|
+
def __str__(self, /) -> str: ...
|
|
119
|
+
def __repr__(self, /) -> str: ...
|
|
115
120
|
|
|
116
121
|
class Variable:
|
|
117
122
|
"""
|
|
@@ -166,6 +171,8 @@ class Variable:
|
|
|
166
171
|
@overload
|
|
167
172
|
def __init__(self, /, name: str, *, env: Environment) -> None: ...
|
|
168
173
|
@overload
|
|
174
|
+
def __init__(self, /, name: str, *, env: Environment, vtype: Vtype) -> None: ...
|
|
175
|
+
@overload
|
|
169
176
|
def __init__(self, /, name: str, *, vtype: Vtype) -> None: ...
|
|
170
177
|
@overload
|
|
171
178
|
def __init__(self, /, name: str, *, vtype: Vtype, bounds: Bounds) -> None: ...
|
|
@@ -178,9 +185,9 @@ class Variable:
|
|
|
178
185
|
/,
|
|
179
186
|
name: str,
|
|
180
187
|
*,
|
|
181
|
-
vtype: Vtype | None = ...,
|
|
182
|
-
bounds: Bounds | None = ...,
|
|
183
|
-
env: Environment | None = ...,
|
|
188
|
+
vtype: (Vtype | None) = ...,
|
|
189
|
+
bounds: (Bounds | None) = ...,
|
|
190
|
+
env: (Environment | None) = ...,
|
|
184
191
|
) -> None:
|
|
185
192
|
"""
|
|
186
193
|
Initialize a new Variable.
|
|
@@ -196,14 +203,22 @@ class Variable:
|
|
|
196
203
|
VariableCreationError
|
|
197
204
|
If the variable is tried to be created with incompatible bounds.
|
|
198
205
|
"""
|
|
206
|
+
...
|
|
199
207
|
|
|
200
208
|
@property
|
|
201
209
|
def name(self, /) -> str:
|
|
202
210
|
"""Get the name of the variable."""
|
|
211
|
+
...
|
|
203
212
|
|
|
204
213
|
@property
|
|
205
214
|
def bounds(self, /) -> Bounds:
|
|
206
215
|
"""Get the bounds of the variable."""
|
|
216
|
+
...
|
|
217
|
+
|
|
218
|
+
@property
|
|
219
|
+
def vtype(self, /) -> Vtype:
|
|
220
|
+
"""Get the vtype of the variable."""
|
|
221
|
+
...
|
|
207
222
|
|
|
208
223
|
@overload
|
|
209
224
|
def __add__(self, other: int, /) -> Expression: ...
|
|
@@ -213,7 +228,7 @@ class Variable:
|
|
|
213
228
|
def __add__(self, other: Variable, /) -> Expression: ...
|
|
214
229
|
@overload
|
|
215
230
|
def __add__(self, other: Expression, /) -> Expression: ...
|
|
216
|
-
def __add__(self, other: float | Variable | Expression, /) -> Expression:
|
|
231
|
+
def __add__(self, other: (int | float | Variable | Expression), /) -> Expression:
|
|
217
232
|
"""
|
|
218
233
|
Add this variable to another value.
|
|
219
234
|
|
|
@@ -233,6 +248,7 @@ class Variable:
|
|
|
233
248
|
TypeError
|
|
234
249
|
If the operand type is unsupported.
|
|
235
250
|
"""
|
|
251
|
+
...
|
|
236
252
|
|
|
237
253
|
@overload
|
|
238
254
|
def __radd__(self, other: int, /) -> Expression: ...
|
|
@@ -242,7 +258,7 @@ class Variable:
|
|
|
242
258
|
def __radd__(self, other: Variable, /) -> Expression: ...
|
|
243
259
|
@overload
|
|
244
260
|
def __radd__(self, other: Expression, /) -> Expression: ...
|
|
245
|
-
def __radd__(self, other: float | Variable | Expression, /) -> Expression:
|
|
261
|
+
def __radd__(self, other: (int | float | Variable | Expression), /) -> Expression:
|
|
246
262
|
"""
|
|
247
263
|
Right-hand addition.
|
|
248
264
|
|
|
@@ -260,6 +276,7 @@ class Variable:
|
|
|
260
276
|
TypeError
|
|
261
277
|
If the operand type is unsupported.
|
|
262
278
|
"""
|
|
279
|
+
...
|
|
263
280
|
|
|
264
281
|
@overload
|
|
265
282
|
def __sub__(self, other: int, /) -> Expression: ...
|
|
@@ -269,7 +286,7 @@ class Variable:
|
|
|
269
286
|
def __sub__(self, other: Variable, /) -> Expression: ...
|
|
270
287
|
@overload
|
|
271
288
|
def __sub__(self, other: Expression, /) -> Expression: ...
|
|
272
|
-
def __sub__(self, other: float | Variable | Expression, /) -> Expression:
|
|
289
|
+
def __sub__(self, other: (int | float | Variable | Expression), /) -> Expression:
|
|
273
290
|
"""
|
|
274
291
|
Subtract a value from this variable.
|
|
275
292
|
|
|
@@ -289,12 +306,13 @@ class Variable:
|
|
|
289
306
|
TypeError
|
|
290
307
|
If the operand type is unsupported.
|
|
291
308
|
"""
|
|
309
|
+
...
|
|
292
310
|
|
|
293
311
|
@overload
|
|
294
312
|
def __rsub__(self, other: int, /) -> Expression: ...
|
|
295
313
|
@overload
|
|
296
314
|
def __rsub__(self, other: float, /) -> Expression: ...
|
|
297
|
-
def __rsub__(self, other: float, /) -> Expression:
|
|
315
|
+
def __rsub__(self, other: (int | float), /) -> Expression:
|
|
298
316
|
"""
|
|
299
317
|
Subtract this variable from a scalar (right-hand subtraction).
|
|
300
318
|
|
|
@@ -312,6 +330,7 @@ class Variable:
|
|
|
312
330
|
TypeError
|
|
313
331
|
If `other` is not a scalar.
|
|
314
332
|
"""
|
|
333
|
+
...
|
|
315
334
|
|
|
316
335
|
@overload
|
|
317
336
|
def __mul__(self, other: int, /) -> Expression: ...
|
|
@@ -321,7 +340,7 @@ class Variable:
|
|
|
321
340
|
def __mul__(self, other: Variable, /) -> Expression: ...
|
|
322
341
|
@overload
|
|
323
342
|
def __mul__(self, other: Expression, /) -> Expression: ...
|
|
324
|
-
def __mul__(self, other: float | Variable | Expression, /) -> Expression:
|
|
343
|
+
def __mul__(self, other: (int | float | Variable | Expression), /) -> Expression:
|
|
325
344
|
"""
|
|
326
345
|
Multiply this variable by another value.
|
|
327
346
|
|
|
@@ -341,6 +360,7 @@ class Variable:
|
|
|
341
360
|
TypeError
|
|
342
361
|
If the operand type is unsupported.
|
|
343
362
|
"""
|
|
363
|
+
...
|
|
344
364
|
|
|
345
365
|
@overload
|
|
346
366
|
def __rmul__(self, other: int, /) -> Expression: ...
|
|
@@ -350,7 +370,7 @@ class Variable:
|
|
|
350
370
|
def __rmul__(self, other: Variable, /) -> Expression: ...
|
|
351
371
|
@overload
|
|
352
372
|
def __rmul__(self, other: Expression, /) -> Expression: ...
|
|
353
|
-
def __rmul__(self, other: float | Variable | Expression, /) -> Expression:
|
|
373
|
+
def __rmul__(self, other: (int | float | Variable | Expression), /) -> Expression:
|
|
354
374
|
"""
|
|
355
375
|
Right-hand multiplication for scalars.
|
|
356
376
|
|
|
@@ -368,6 +388,7 @@ class Variable:
|
|
|
368
388
|
TypeError
|
|
369
389
|
If the operand type is unsupported.
|
|
370
390
|
"""
|
|
391
|
+
...
|
|
371
392
|
|
|
372
393
|
def __pow__(self, other: int, /) -> Expression:
|
|
373
394
|
"""
|
|
@@ -386,6 +407,7 @@ class Variable:
|
|
|
386
407
|
RuntimeError
|
|
387
408
|
If the param `modulo` usually supported for `__pow__` is specified.
|
|
388
409
|
"""
|
|
410
|
+
...
|
|
389
411
|
|
|
390
412
|
@overload
|
|
391
413
|
def __eq__(self, rhs: int, /) -> Constraint: ...
|
|
@@ -407,7 +429,7 @@ class Variable:
|
|
|
407
429
|
bool
|
|
408
430
|
"""
|
|
409
431
|
|
|
410
|
-
def __eq__(self, rhs: float | Expression, /) -> Constraint:
|
|
432
|
+
def __eq__(self, rhs: (int | float | Expression), /) -> Constraint:
|
|
411
433
|
"""
|
|
412
434
|
Create a constraint: Variable == float | int | Expression.
|
|
413
435
|
|
|
@@ -438,7 +460,7 @@ class Variable:
|
|
|
438
460
|
def __le__(self, rhs: Variable, /) -> Constraint: ...
|
|
439
461
|
@overload
|
|
440
462
|
def __le__(self, rhs: Expression, /) -> Constraint: ...
|
|
441
|
-
def __le__(self, rhs: float | Variable | Expression, /) -> Constraint:
|
|
463
|
+
def __le__(self, rhs: (int | float | Variable | Expression), /) -> Constraint:
|
|
442
464
|
"""
|
|
443
465
|
Create a constraint: Variable <= scalar.
|
|
444
466
|
|
|
@@ -460,6 +482,7 @@ class Variable:
|
|
|
460
482
|
TypeError
|
|
461
483
|
If the right-hand side is not of type float, int, Variable or Expression.
|
|
462
484
|
"""
|
|
485
|
+
...
|
|
463
486
|
|
|
464
487
|
@overload
|
|
465
488
|
def __ge__(self, rhs: int, /) -> Constraint: ...
|
|
@@ -469,7 +492,7 @@ class Variable:
|
|
|
469
492
|
def __ge__(self, rhs: Variable, /) -> Constraint: ...
|
|
470
493
|
@overload
|
|
471
494
|
def __ge__(self, rhs: Expression, /) -> Constraint: ...
|
|
472
|
-
def __ge__(self, rhs: float | Variable | Expression, /) -> Constraint:
|
|
495
|
+
def __ge__(self, rhs: (int | float | Variable | Expression), /) -> Constraint:
|
|
473
496
|
"""
|
|
474
497
|
Create a constraint: Variable >= scalar.
|
|
475
498
|
|
|
@@ -491,6 +514,7 @@ class Variable:
|
|
|
491
514
|
TypeError
|
|
492
515
|
If the right-hand side is not of type float, int, Variable or Expression.
|
|
493
516
|
"""
|
|
517
|
+
...
|
|
494
518
|
|
|
495
519
|
def __neg__(self, /) -> Expression:
|
|
496
520
|
"""
|
|
@@ -500,10 +524,122 @@ class Variable:
|
|
|
500
524
|
-------
|
|
501
525
|
Expression
|
|
502
526
|
"""
|
|
527
|
+
...
|
|
528
|
+
|
|
529
|
+
@property
|
|
530
|
+
def _environment(self, /) -> Environment:
|
|
531
|
+
"""Get this variables's environment."""
|
|
532
|
+
...
|
|
503
533
|
|
|
504
534
|
def __hash__(self, /) -> int: ...
|
|
535
|
+
def __str__(self, /) -> str: ...
|
|
536
|
+
def __repr__(self, /) -> str: ...
|
|
537
|
+
|
|
538
|
+
class Constant:
|
|
539
|
+
"""A constant expression.
|
|
540
|
+
|
|
541
|
+
Convenience class to indicate the empty set of variables of an expression's
|
|
542
|
+
constant term when iterating over the expression's components.
|
|
543
|
+
|
|
544
|
+
Note that the bias corresponding to the constant part is not part of this class.
|
|
545
|
+
|
|
546
|
+
Examples
|
|
547
|
+
--------
|
|
548
|
+
>>> from luna_quantum import Constant, Expression, HigherOrder, Linear, Quadratic
|
|
549
|
+
>>> expr: Expression = ...
|
|
550
|
+
>>> vars: Constant | Linear | Quadratic | HigherOrder
|
|
551
|
+
>>> bias: float
|
|
552
|
+
>>> for vars, bias in expr.items():
|
|
553
|
+
>>> match vars:
|
|
554
|
+
>>> case Constant(): do_something_with_constant(bias)
|
|
555
|
+
>>> case Linear(x): do_something_with_linear_var(x, bias)
|
|
556
|
+
>>> case Quadratic(x, y): do_something_with_quadratic_vars(x, y, bias)
|
|
557
|
+
>>> case HigherOrder(ho): do_something_with_higher_order_vars(ho, bias)
|
|
558
|
+
"""
|
|
559
|
+
|
|
560
|
+
class Linear:
|
|
561
|
+
"""A linear expression.
|
|
562
|
+
|
|
563
|
+
Convenience class to indicate the variable of an expression's linear term when
|
|
564
|
+
iterating over the expression's components.
|
|
565
|
+
|
|
566
|
+
Note that the bias corresponding to this variable is not part of this class.
|
|
567
|
+
|
|
568
|
+
Examples
|
|
569
|
+
--------
|
|
570
|
+
>>> from luna_quantum import Constant, Expression, HigherOrder, Linear, Quadratic
|
|
571
|
+
>>> expr: Expression = ...
|
|
572
|
+
>>> vars: Constant | Linear | Quadratic | HigherOrder
|
|
573
|
+
>>> bias: float
|
|
574
|
+
>>> for vars, bias in expr.items():
|
|
575
|
+
>>> match vars:
|
|
576
|
+
>>> case Constant(): do_something_with_constant(bias)
|
|
577
|
+
>>> case Linear(x): do_something_with_linear_var(x, bias)
|
|
578
|
+
>>> case Quadratic(x, y): do_something_with_quadratic_vars(x, y, bias)
|
|
579
|
+
>>> case HigherOrder(ho): do_something_with_higher_order_vars(ho, bias)
|
|
580
|
+
"""
|
|
581
|
+
|
|
582
|
+
__match_args__ = ("var",)
|
|
583
|
+
|
|
584
|
+
@property
|
|
585
|
+
def var(self) -> Variable: ...
|
|
586
|
+
|
|
587
|
+
class Quadratic:
|
|
588
|
+
"""A quadratic expression.
|
|
589
|
+
|
|
590
|
+
Convenience class to indicate the variables of an expression's quadratic term when
|
|
591
|
+
iterating over the expression's components.
|
|
592
|
+
|
|
593
|
+
Note that the bias corresponding to these two variables is not part of this class.
|
|
594
|
+
|
|
595
|
+
Examples
|
|
596
|
+
--------
|
|
597
|
+
>>> from luna_quantum import Constant, Expression, HigherOrder, Linear, Quadratic
|
|
598
|
+
>>> expr: Expression = ...
|
|
599
|
+
>>> vars: Constant | Linear | Quadratic | HigherOrder
|
|
600
|
+
>>> bias: float
|
|
601
|
+
>>> for vars, bias in expr.items():
|
|
602
|
+
>>> match vars:
|
|
603
|
+
>>> case Constant(): do_something_with_constant(bias)
|
|
604
|
+
>>> case Linear(x): do_something_with_linear_var(x, bias)
|
|
605
|
+
>>> case Quadratic(x, y): do_something_with_quadratic_vars(x, y, bias)
|
|
606
|
+
>>> case HigherOrder(ho): do_something_with_higher_order_vars(ho, bias)
|
|
607
|
+
"""
|
|
608
|
+
|
|
609
|
+
__match_args__ = "var_a", "var_b"
|
|
610
|
+
|
|
611
|
+
@property
|
|
612
|
+
def var_a(self) -> Variable: ...
|
|
613
|
+
@property
|
|
614
|
+
def var_b(self) -> Variable: ...
|
|
615
|
+
|
|
616
|
+
class HigherOrder:
|
|
617
|
+
"""A higher-order expression.
|
|
618
|
+
|
|
619
|
+
Convenience class to indicate the set of variables of an expression's higher-order
|
|
620
|
+
term when iterating over the expression's components.
|
|
621
|
+
|
|
622
|
+
Note that the bias corresponding to these variables is not part of this class.
|
|
623
|
+
|
|
624
|
+
Examples
|
|
625
|
+
--------
|
|
626
|
+
>>> from luna_quantum import Constant, Expression, HigherOrder, Linear, Quadratic
|
|
627
|
+
>>> expr: Expression = ...
|
|
628
|
+
>>> vars: Constant | Linear | Quadratic | HigherOrder
|
|
629
|
+
>>> bias: float
|
|
630
|
+
>>> for vars, bias in expr.items():
|
|
631
|
+
>>> match vars:
|
|
632
|
+
>>> case Constant(): do_something_with_constant(bias)
|
|
633
|
+
>>> case Linear(x): do_something_with_linear_var(x, bias)
|
|
634
|
+
>>> case Quadratic(x, y): do_something_with_quadratic_vars(x, y, bias)
|
|
635
|
+
>>> case HigherOrder(ho): do_something_with_higher_order_vars(ho, bias)
|
|
636
|
+
"""
|
|
637
|
+
|
|
638
|
+
__match_args__ = ("vars",)
|
|
639
|
+
|
|
640
|
+
@property
|
|
641
|
+
def vars(self) -> list[Variable]: ...
|
|
505
642
|
|
|
506
|
-
# _timing.pyi
|
|
507
643
|
class Timing:
|
|
508
644
|
"""
|
|
509
645
|
The object that holds information about an algorithm's runtime.
|
|
@@ -532,10 +668,12 @@ class Timing:
|
|
|
532
668
|
@property
|
|
533
669
|
def start(self, /) -> datetime:
|
|
534
670
|
"""The starting time of the algorithm."""
|
|
671
|
+
...
|
|
535
672
|
|
|
536
673
|
@property
|
|
537
674
|
def end(self, /) -> datetime:
|
|
538
675
|
"""The end, or finishing, time of the algorithm."""
|
|
676
|
+
...
|
|
539
677
|
|
|
540
678
|
@property
|
|
541
679
|
def total(self, /) -> timedelta:
|
|
@@ -547,25 +685,30 @@ class Timing:
|
|
|
547
685
|
RuntimeError
|
|
548
686
|
If total cannot be computed due to an inconsistent start or end time.
|
|
549
687
|
"""
|
|
688
|
+
...
|
|
550
689
|
|
|
551
690
|
@property
|
|
552
691
|
def total_seconds(self, /) -> float:
|
|
553
692
|
"""
|
|
554
|
-
The total time in seconds an algorithm needed to run.
|
|
555
|
-
|
|
693
|
+
The total time in seconds an algorithm needed to run.
|
|
694
|
+
|
|
695
|
+
Computed as the difference of end and start time.
|
|
556
696
|
|
|
557
697
|
Raises
|
|
558
698
|
------
|
|
559
699
|
RuntimeError
|
|
560
|
-
If total_seconds cannot be computed due to an inconsistent start or
|
|
700
|
+
If `total_seconds` cannot be computed due to an inconsistent start or
|
|
701
|
+
end time.
|
|
561
702
|
"""
|
|
703
|
+
...
|
|
562
704
|
|
|
563
705
|
@property
|
|
564
706
|
def qpu(self, /) -> float | None:
|
|
565
707
|
"""The qpu usage time of the algorithm this timing object was created for."""
|
|
708
|
+
...
|
|
566
709
|
|
|
567
710
|
@qpu.setter
|
|
568
|
-
def qpu(self, /, value: float | None):
|
|
711
|
+
def qpu(self, /, value: (float | None)) -> None:
|
|
569
712
|
"""
|
|
570
713
|
Set the qpu usage time.
|
|
571
714
|
|
|
@@ -574,11 +717,13 @@ class Timing:
|
|
|
574
717
|
ValueError
|
|
575
718
|
If `value` is negative.
|
|
576
719
|
"""
|
|
720
|
+
...
|
|
577
721
|
|
|
578
|
-
def add_qpu(self, /, value: float):
|
|
722
|
+
def add_qpu(self, /, value: float) -> None:
|
|
579
723
|
"""
|
|
580
|
-
Add qpu usage time to the qpu usage time already present.
|
|
581
|
-
|
|
724
|
+
Add qpu usage time to the qpu usage time already present.
|
|
725
|
+
|
|
726
|
+
If the current value is None, this method acts like a setter.
|
|
582
727
|
|
|
583
728
|
Parameters
|
|
584
729
|
----------
|
|
@@ -590,6 +735,7 @@ class Timing:
|
|
|
590
735
|
ValueError
|
|
591
736
|
If `value` is negative.
|
|
592
737
|
"""
|
|
738
|
+
...
|
|
593
739
|
|
|
594
740
|
class Timer:
|
|
595
741
|
"""
|
|
@@ -618,6 +764,7 @@ class Timer:
|
|
|
618
764
|
Timer
|
|
619
765
|
The timer.
|
|
620
766
|
"""
|
|
767
|
+
...
|
|
621
768
|
|
|
622
769
|
def stop(self, /) -> Timing:
|
|
623
770
|
"""
|
|
@@ -628,8 +775,8 @@ class Timer:
|
|
|
628
775
|
Timing
|
|
629
776
|
The timing object that holds the start and end time.
|
|
630
777
|
"""
|
|
778
|
+
...
|
|
631
779
|
|
|
632
|
-
# _solution.pyi
|
|
633
780
|
class Solution:
|
|
634
781
|
"""
|
|
635
782
|
The solution object that is obtained by running an algorihtm.
|
|
@@ -639,9 +786,10 @@ class Solution:
|
|
|
639
786
|
returned by the algorithm, metadata about the solution quality, e.g., the objective
|
|
640
787
|
value, and the runtime of the algorithm.
|
|
641
788
|
|
|
642
|
-
A `Solution` can be constructed explicitly using `from_dict` or by obtaining a
|
|
643
|
-
from an algorithm or by converting a different solution format with one of
|
|
644
|
-
translators. Note that the latter requires the environment the model
|
|
789
|
+
A `Solution` can be constructed explicitly using `from_dict` or by obtaining a
|
|
790
|
+
solution from an algorithm or by converting a different solution format with one of
|
|
791
|
+
the available translators. Note that the latter requires the environment the model
|
|
792
|
+
was created in.
|
|
645
793
|
|
|
646
794
|
Examples
|
|
647
795
|
--------
|
|
@@ -675,10 +823,13 @@ class Solution:
|
|
|
675
823
|
|
|
676
824
|
Notes
|
|
677
825
|
-----
|
|
678
|
-
- To ensure metadata like objective values or feasibility, use
|
|
826
|
+
- To ensure metadata like objective values or feasibility, use
|
|
827
|
+
`model.evaluate(solution)`.
|
|
679
828
|
- Use `encode()` and `decode()` to serialize and recover solutions.
|
|
680
829
|
"""
|
|
681
830
|
|
|
831
|
+
def __str__(self, /) -> str: ...
|
|
832
|
+
def __repr__(self, /) -> str: ...
|
|
682
833
|
def __len__(self, /) -> int: ...
|
|
683
834
|
def __iter__(self, /) -> ResultIterator:
|
|
684
835
|
"""
|
|
@@ -695,6 +846,7 @@ class Solution:
|
|
|
695
846
|
IndexError
|
|
696
847
|
If the row index is out of bounds for the variable environment.
|
|
697
848
|
"""
|
|
849
|
+
...
|
|
698
850
|
|
|
699
851
|
def __getitem__(self, item: int, /) -> ResultView:
|
|
700
852
|
"""
|
|
@@ -711,8 +863,9 @@ class Solution:
|
|
|
711
863
|
IndexError
|
|
712
864
|
If the row index is out of bounds for the variable environment.
|
|
713
865
|
"""
|
|
866
|
+
...
|
|
714
867
|
|
|
715
|
-
def __eq__(self, other: Solution, /) -> bool:
|
|
868
|
+
def __eq__(self, other: Solution, /) -> bool:
|
|
716
869
|
"""
|
|
717
870
|
Check whether this solution is equal to `other`.
|
|
718
871
|
|
|
@@ -724,6 +877,7 @@ class Solution:
|
|
|
724
877
|
-------
|
|
725
878
|
bool
|
|
726
879
|
"""
|
|
880
|
+
...
|
|
727
881
|
|
|
728
882
|
def best(self, /) -> ResultView | None:
|
|
729
883
|
"""
|
|
@@ -737,44 +891,60 @@ class Solution:
|
|
|
737
891
|
ResultView
|
|
738
892
|
The best result of the solution as a view.
|
|
739
893
|
"""
|
|
894
|
+
...
|
|
740
895
|
|
|
741
896
|
@property
|
|
742
897
|
def results(self, /) -> ResultIterator:
|
|
743
898
|
"""Get an iterator over the single results of the solution."""
|
|
899
|
+
...
|
|
744
900
|
|
|
745
901
|
@property
|
|
746
902
|
def samples(self, /) -> Samples:
|
|
747
903
|
"""Get a view into the samples of the solution."""
|
|
904
|
+
...
|
|
748
905
|
|
|
749
906
|
@property
|
|
750
907
|
def obj_values(self, /) -> NDArray:
|
|
751
908
|
"""
|
|
752
|
-
Get the objective values of the single samples as a ndarray.
|
|
753
|
-
|
|
909
|
+
Get the objective values of the single samples as a ndarray.
|
|
910
|
+
|
|
911
|
+
A value will be None if the sample hasn't yet been evaluated.
|
|
754
912
|
"""
|
|
913
|
+
...
|
|
755
914
|
|
|
756
915
|
@property
|
|
757
916
|
def raw_energies(self, /) -> NDArray:
|
|
758
|
-
"""
|
|
917
|
+
"""Get the raw energies.
|
|
918
|
+
|
|
759
919
|
Get the raw energy values of the single samples as returned by the solver /
|
|
760
920
|
algorithm. Will be None if the solver / algorithm did not provide a value.
|
|
761
921
|
"""
|
|
922
|
+
...
|
|
762
923
|
|
|
763
924
|
@property
|
|
764
925
|
def counts(self, /) -> NDArray:
|
|
765
926
|
"""Return how often each sample occurred in the solution."""
|
|
927
|
+
...
|
|
766
928
|
|
|
767
929
|
@property
|
|
768
930
|
def runtime(self, /) -> Timing | None:
|
|
769
931
|
"""Get the solver / algorithm runtime."""
|
|
932
|
+
...
|
|
933
|
+
|
|
934
|
+
@property
|
|
935
|
+
def sense(self, /) -> Sense:
|
|
936
|
+
"""Get the optimization sense."""
|
|
937
|
+
...
|
|
770
938
|
|
|
771
939
|
@property
|
|
772
940
|
def best_sample_idx(self, /) -> int | None:
|
|
773
941
|
"""Get the index of the sample with the best objective value."""
|
|
942
|
+
...
|
|
774
943
|
|
|
775
944
|
@property
|
|
776
945
|
def variable_names(self, /) -> list[str]:
|
|
777
946
|
"""Get the names of all variables in the solution."""
|
|
947
|
+
...
|
|
778
948
|
|
|
779
949
|
def expectation_value(self, /) -> float:
|
|
780
950
|
"""
|
|
@@ -790,6 +960,55 @@ class Solution:
|
|
|
790
960
|
ComputationError
|
|
791
961
|
If the computation fails for any reason.
|
|
792
962
|
"""
|
|
963
|
+
...
|
|
964
|
+
|
|
965
|
+
def feasibility_ratio(self, /) -> float:
|
|
966
|
+
"""
|
|
967
|
+
Compute the feasibility ratio of the solution.
|
|
968
|
+
|
|
969
|
+
Returns
|
|
970
|
+
-------
|
|
971
|
+
float
|
|
972
|
+
The feasibility ratio.
|
|
973
|
+
|
|
974
|
+
Raises
|
|
975
|
+
------
|
|
976
|
+
ComputationError
|
|
977
|
+
If the computation fails for any reason.
|
|
978
|
+
"""
|
|
979
|
+
...
|
|
980
|
+
|
|
981
|
+
def filter_feasible(self, /) -> Solution:
|
|
982
|
+
"""
|
|
983
|
+
Get a new solution with all infeasible samples removed.
|
|
984
|
+
|
|
985
|
+
Returns
|
|
986
|
+
-------
|
|
987
|
+
The new solution with only feasible samples.
|
|
988
|
+
|
|
989
|
+
Raises
|
|
990
|
+
------
|
|
991
|
+
ComputationError
|
|
992
|
+
If the computation fails for any reason.
|
|
993
|
+
"""
|
|
994
|
+
...
|
|
995
|
+
|
|
996
|
+
def highest_constraint_violation(self, /) -> int | None:
|
|
997
|
+
"""
|
|
998
|
+
Get the index of the constraint with the highest number of violations.
|
|
999
|
+
|
|
1000
|
+
Returns
|
|
1001
|
+
-------
|
|
1002
|
+
int | None
|
|
1003
|
+
The index of the constraint with the most violations. None, if the solution
|
|
1004
|
+
was created for an unconstrained model.
|
|
1005
|
+
|
|
1006
|
+
Raises
|
|
1007
|
+
------
|
|
1008
|
+
ComputationError
|
|
1009
|
+
If the computation fails for any reason.
|
|
1010
|
+
"""
|
|
1011
|
+
...
|
|
793
1012
|
|
|
794
1013
|
@overload
|
|
795
1014
|
def encode(self, /) -> bytes: ...
|
|
@@ -798,7 +1017,8 @@ class Solution:
|
|
|
798
1017
|
@overload
|
|
799
1018
|
def encode(self, /, *, level: int) -> bytes: ...
|
|
800
1019
|
@overload
|
|
801
|
-
def encode(self, /, *, compress: bool, level: int) -> bytes:
|
|
1020
|
+
def encode(self, /, *, compress: bool, level: int) -> bytes: ...
|
|
1021
|
+
def encode(self, /, *, compress: bool = True, level: int = 3) -> bytes:
|
|
802
1022
|
"""
|
|
803
1023
|
Serialize the solution into a compact binary format.
|
|
804
1024
|
|
|
@@ -807,7 +1027,7 @@ class Solution:
|
|
|
807
1027
|
compress : bool, optional
|
|
808
1028
|
Whether to compress the binary output. Default is True.
|
|
809
1029
|
level : int, optional
|
|
810
|
-
Compression level (0
|
|
1030
|
+
Compression level (0-9). Default is 3.
|
|
811
1031
|
|
|
812
1032
|
Returns
|
|
813
1033
|
-------
|
|
@@ -819,6 +1039,7 @@ class Solution:
|
|
|
819
1039
|
IOError
|
|
820
1040
|
If serialization fails.
|
|
821
1041
|
"""
|
|
1042
|
+
...
|
|
822
1043
|
|
|
823
1044
|
@overload
|
|
824
1045
|
def serialize(self, /) -> bytes: ...
|
|
@@ -829,13 +1050,14 @@ class Solution:
|
|
|
829
1050
|
@overload
|
|
830
1051
|
def serialize(self, /, compress: bool, level: int) -> bytes: ...
|
|
831
1052
|
def serialize(
|
|
832
|
-
self, /, compress: bool | None = ..., level: int | None = ...
|
|
1053
|
+
self, /, compress: (bool | None) = ..., level: (int | None) = ...
|
|
833
1054
|
) -> bytes:
|
|
834
1055
|
"""
|
|
835
1056
|
Alias for `encode()`.
|
|
836
1057
|
|
|
837
1058
|
See `encode()` for details.
|
|
838
1059
|
"""
|
|
1060
|
+
...
|
|
839
1061
|
|
|
840
1062
|
@classmethod
|
|
841
1063
|
def decode(cls, data: bytes) -> Solution:
|
|
@@ -857,184 +1079,124 @@ class Solution:
|
|
|
857
1079
|
DecodeError
|
|
858
1080
|
If decoding fails due to corruption or incompatibility.
|
|
859
1081
|
"""
|
|
1082
|
+
...
|
|
860
1083
|
|
|
861
1084
|
@classmethod
|
|
862
1085
|
def deserialize(cls, data: bytes) -> Solution:
|
|
863
1086
|
"""Alias for `decode()`."""
|
|
864
|
-
|
|
865
|
-
@staticmethod
|
|
866
|
-
def build(
|
|
867
|
-
component_types: list[Vtype],
|
|
868
|
-
*,
|
|
869
|
-
variable_names: list[str] | None = ...,
|
|
870
|
-
binary_cols: list[list[int]] | None = ...,
|
|
871
|
-
spin_cols: list[list[int]] | None = ...,
|
|
872
|
-
int_cols: list[list[int]] | None = ...,
|
|
873
|
-
real_cols: list[list[float]] | None = ...,
|
|
874
|
-
raw_energies: list[float | None] | None = ...,
|
|
875
|
-
timing: Timing | None = ...,
|
|
876
|
-
counts: list[int] | None = ...,
|
|
877
|
-
) -> Solution:
|
|
878
|
-
"""
|
|
879
|
-
Build a `Solution` based on the provided input data. The solution is constructed
|
|
880
|
-
based on a column layout of the solution. Let's take the following sample-set with three
|
|
881
|
-
samples as an example:
|
|
882
|
-
|
|
883
|
-
[ 0 1 -1 3 2.2 1 ]
|
|
884
|
-
[ 1 0 -1 6 3.8 0 ]
|
|
885
|
-
[ 1 1 +1 2 2.4 0 ]
|
|
886
|
-
|
|
887
|
-
Each row encodes a single sample. However, the variable types vary, the first, second, and
|
|
888
|
-
last columns all represent a Binary variable (index 0, 1, 5). The third column represents a
|
|
889
|
-
variable of type Spin (index 2). The fourth column (index 3), a variable of type Integer and
|
|
890
|
-
the fifth column (index 4), a real-valued variable.
|
|
891
|
-
|
|
892
|
-
Thus, the `component_types` list is:
|
|
893
|
-
|
|
894
|
-
>>> component_types = [Vtype.Binary, Vtype.Binary, Vtype.Spin, Vtype.Integer, Vtype.Real, Vtype.Binary]
|
|
895
|
-
|
|
896
|
-
Now we can extract all columns for a binary-valued variable and append them to a new list:
|
|
897
|
-
|
|
898
|
-
>>> binary_cols = [[0, 1, 1], [1, 0, 1], [1, 0, 0]]
|
|
899
|
-
|
|
900
|
-
where the first element in the list represents the first column, the second element the\
|
|
901
|
-
second column and the third element the fifth column.
|
|
902
|
-
We do the same for the remaining variable types:
|
|
903
|
-
|
|
904
|
-
>>> spin_cols = [[-1, -1, +1]]
|
|
905
|
-
>>> int_cols = [[3, 6, 2]]
|
|
906
|
-
>>> real_cols = [[2.2, 3.8, 2.4]]
|
|
907
|
-
|
|
908
|
-
If we know the raw energies, we can construct them as well:
|
|
909
|
-
|
|
910
|
-
>>> raw_energies = [-200, -100, +300]
|
|
911
|
-
|
|
912
|
-
And finally call the `build` function:
|
|
913
|
-
|
|
914
|
-
>>> sol = Solution.build(
|
|
915
|
-
... component_types,
|
|
916
|
-
... binary_cols,
|
|
917
|
-
... spin_cols,
|
|
918
|
-
... int_cols,
|
|
919
|
-
... real_cols,
|
|
920
|
-
... raw_energies,
|
|
921
|
-
... timing,
|
|
922
|
-
... counts=[1, 1, 1]
|
|
923
|
-
... )
|
|
924
|
-
>>> sol
|
|
925
|
-
|
|
926
|
-
In this example, we could also neglect the `counts` as it defaults to `1`
|
|
927
|
-
for all samples if not set:
|
|
928
|
-
|
|
929
|
-
>>> sol = Solution.build(
|
|
930
|
-
... component_types,
|
|
931
|
-
... binary_cols,
|
|
932
|
-
... spin_cols,
|
|
933
|
-
... int_cols,
|
|
934
|
-
... real_cols,
|
|
935
|
-
... raw_energies,
|
|
936
|
-
... timing
|
|
937
|
-
... )
|
|
938
|
-
>>> sol
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
Parameters
|
|
942
|
-
----------
|
|
943
|
-
component_types : list[Vtype]
|
|
944
|
-
The variable type each element in a sample encodes.
|
|
945
|
-
variable_names : list[Vtype], optional
|
|
946
|
-
The name of each variable in the solution.
|
|
947
|
-
binary_cols : list[list[int]], optional
|
|
948
|
-
The data of all binary valued columns. Each inner list encodes a single binary-valued
|
|
949
|
-
column. Required if any element in the `component_types` is `Vtype.Binary`.
|
|
950
|
-
spin_cols : list[list[int]], optional
|
|
951
|
-
The data of all spin-valued columns. Each inner list encodes a single spin-valued
|
|
952
|
-
column. Required if any element in the `component_types` is `Vtype.Spin`.
|
|
953
|
-
int_cols : list[list[int]], optional
|
|
954
|
-
The data of all integer-valued columns. Each inner list encodes a single integer valued
|
|
955
|
-
column. Required if any element in the `component_types` is `Vtype.Integer`.
|
|
956
|
-
real_cols : list[list[float]], optional
|
|
957
|
-
The data of all real-valued columns. Each inner list encodes a single real-valued
|
|
958
|
-
column. Required if any element in the `component_types` is `Vtype.Real`.
|
|
959
|
-
raw_energies : list[float, optional], optional
|
|
960
|
-
The data of all real valued columns. Each inner list encodes a single real-valued
|
|
961
|
-
column.
|
|
962
|
-
timing : Timing, optional
|
|
963
|
-
The timing data.
|
|
964
|
-
counts : list[int], optional
|
|
965
|
-
The number how often each sample in the solution has occurred. By default, 1 for all
|
|
966
|
-
samples.
|
|
967
|
-
|
|
968
|
-
Returns
|
|
969
|
-
-------
|
|
970
|
-
Solution
|
|
971
|
-
The constructed solution
|
|
972
|
-
|
|
973
|
-
Raises
|
|
974
|
-
------
|
|
975
|
-
RuntimeError
|
|
976
|
-
If a sample column has an incorrect number of samples or if `counts` has
|
|
977
|
-
a length different from the number of samples given.
|
|
978
|
-
"""
|
|
1087
|
+
...
|
|
979
1088
|
|
|
980
1089
|
@overload
|
|
981
1090
|
@staticmethod
|
|
982
|
-
def from_dict(
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
def from_dict(data: dict[str, float]) -> Solution: ...
|
|
992
|
-
@overload
|
|
993
|
-
@staticmethod
|
|
994
|
-
def from_dict(data: dict[Variable | str, int | float]) -> Solution: ...
|
|
995
|
-
@overload
|
|
996
|
-
@staticmethod
|
|
997
|
-
def from_dict(data: dict[Variable, int], *, env: Environment) -> Solution: ...
|
|
998
|
-
@overload
|
|
999
|
-
@staticmethod
|
|
1000
|
-
def from_dict(data: dict[Variable, float], *, env: Environment) -> Solution: ...
|
|
1091
|
+
def from_dict(
|
|
1092
|
+
data: dict[Variable, int],
|
|
1093
|
+
*,
|
|
1094
|
+
env: Environment = ...,
|
|
1095
|
+
model: Model = ...,
|
|
1096
|
+
timing: Timing = ...,
|
|
1097
|
+
counts: int = ...,
|
|
1098
|
+
sense: Sense = ...,
|
|
1099
|
+
) -> Solution: ...
|
|
1001
1100
|
@overload
|
|
1002
1101
|
@staticmethod
|
|
1003
|
-
def from_dict(
|
|
1102
|
+
def from_dict(
|
|
1103
|
+
data: dict[Variable, float],
|
|
1104
|
+
*,
|
|
1105
|
+
env: Environment = ...,
|
|
1106
|
+
model: Model = ...,
|
|
1107
|
+
timing: Timing = ...,
|
|
1108
|
+
counts: int = ...,
|
|
1109
|
+
sense: Sense = ...,
|
|
1110
|
+
) -> Solution: ...
|
|
1004
1111
|
@overload
|
|
1005
1112
|
@staticmethod
|
|
1006
|
-
def from_dict(
|
|
1113
|
+
def from_dict(
|
|
1114
|
+
data: dict[str, int],
|
|
1115
|
+
*,
|
|
1116
|
+
env: Environment = ...,
|
|
1117
|
+
model: Model = ...,
|
|
1118
|
+
timing: Timing = ...,
|
|
1119
|
+
counts: int = ...,
|
|
1120
|
+
sense: Sense = ...,
|
|
1121
|
+
) -> Solution: ...
|
|
1007
1122
|
@overload
|
|
1008
1123
|
@staticmethod
|
|
1009
1124
|
def from_dict(
|
|
1010
|
-
data: dict[
|
|
1125
|
+
data: dict[str, float],
|
|
1126
|
+
*,
|
|
1127
|
+
env: Environment = ...,
|
|
1128
|
+
model: Model = ...,
|
|
1129
|
+
timing: Timing = ...,
|
|
1130
|
+
counts: int = ...,
|
|
1131
|
+
sense: Sense = ...,
|
|
1011
1132
|
) -> Solution: ...
|
|
1012
1133
|
@overload
|
|
1013
1134
|
@staticmethod
|
|
1014
|
-
def from_dict(
|
|
1135
|
+
def from_dict(
|
|
1136
|
+
data: dict[Variable | str, int],
|
|
1137
|
+
*,
|
|
1138
|
+
env: Environment = ...,
|
|
1139
|
+
model: Model = ...,
|
|
1140
|
+
timing: Timing = ...,
|
|
1141
|
+
counts: int = ...,
|
|
1142
|
+
sense: Sense = ...,
|
|
1143
|
+
) -> Solution: ...
|
|
1015
1144
|
@overload
|
|
1016
1145
|
@staticmethod
|
|
1017
|
-
def from_dict(
|
|
1146
|
+
def from_dict(
|
|
1147
|
+
data: dict[Variable | str, float],
|
|
1148
|
+
*,
|
|
1149
|
+
env: Environment = ...,
|
|
1150
|
+
model: Model = ...,
|
|
1151
|
+
timing: Timing = ...,
|
|
1152
|
+
counts: int = ...,
|
|
1153
|
+
sense: Sense = ...,
|
|
1154
|
+
) -> Solution: ...
|
|
1018
1155
|
@overload
|
|
1019
1156
|
@staticmethod
|
|
1020
|
-
def from_dict(
|
|
1157
|
+
def from_dict(
|
|
1158
|
+
data: dict[Variable, int | float],
|
|
1159
|
+
*,
|
|
1160
|
+
env: Environment = ...,
|
|
1161
|
+
model: Model = ...,
|
|
1162
|
+
timing: Timing = ...,
|
|
1163
|
+
counts: int = ...,
|
|
1164
|
+
sense: Sense = ...,
|
|
1165
|
+
) -> Solution: ...
|
|
1021
1166
|
@overload
|
|
1022
1167
|
@staticmethod
|
|
1023
|
-
def from_dict(
|
|
1168
|
+
def from_dict(
|
|
1169
|
+
data: dict[str, int | float],
|
|
1170
|
+
*,
|
|
1171
|
+
env: Environment = ...,
|
|
1172
|
+
model: Model = ...,
|
|
1173
|
+
timing: Timing = ...,
|
|
1174
|
+
counts: int = ...,
|
|
1175
|
+
sense: Sense = ...,
|
|
1176
|
+
) -> Solution: ...
|
|
1024
1177
|
@overload
|
|
1025
1178
|
@staticmethod
|
|
1026
1179
|
def from_dict(
|
|
1027
|
-
data: dict[Variable | str, int | float],
|
|
1180
|
+
data: dict[Variable | str, int | float],
|
|
1181
|
+
*,
|
|
1182
|
+
env: Environment = ...,
|
|
1183
|
+
model: Model = ...,
|
|
1184
|
+
timing: Timing = ...,
|
|
1185
|
+
counts: int = ...,
|
|
1186
|
+
sense: Sense = ...,
|
|
1028
1187
|
) -> Solution: ...
|
|
1029
1188
|
@staticmethod
|
|
1030
1189
|
def from_dict(
|
|
1031
1190
|
data: dict[Variable | str, int | float],
|
|
1032
1191
|
*,
|
|
1033
|
-
env: Environment | None = ...,
|
|
1034
|
-
model: Model | None = ...,
|
|
1035
|
-
timing: Timing | None = ...,
|
|
1192
|
+
env: (Environment | None) = ...,
|
|
1193
|
+
model: (Model | None) = ...,
|
|
1194
|
+
timing: (Timing | None) = ...,
|
|
1195
|
+
counts: (int | None) = ...,
|
|
1196
|
+
sense: (Sense | None) = ...,
|
|
1036
1197
|
) -> Solution:
|
|
1037
|
-
"""
|
|
1198
|
+
"""Create a `Solution` from a dict.
|
|
1199
|
+
|
|
1038
1200
|
Create a `Solution` from a dict that maps variables or variable names to their
|
|
1039
1201
|
assigned values.
|
|
1040
1202
|
|
|
@@ -1049,6 +1211,8 @@ class Solution:
|
|
|
1049
1211
|
The environment the variable types shall be determined from.
|
|
1050
1212
|
model : Model, optional
|
|
1051
1213
|
A model to evaluate the sample with.
|
|
1214
|
+
counts : int, optional
|
|
1215
|
+
The number of occurrences of this sample.
|
|
1052
1216
|
|
|
1053
1217
|
Returns
|
|
1054
1218
|
-------
|
|
@@ -1063,6 +1227,7 @@ class Solution:
|
|
|
1063
1227
|
ValueError
|
|
1064
1228
|
If `env` and `model` are both present. When this is the case, the user's
|
|
1065
1229
|
intention is unclear as the model itself already contains an environment.
|
|
1230
|
+
Or if `sense` and `model` are both present as the sense is then ambiguous.
|
|
1066
1231
|
SolutionTranslationError
|
|
1067
1232
|
Generally if the sample translation fails. Might be specified by one of the
|
|
1068
1233
|
three following errors.
|
|
@@ -1074,72 +1239,122 @@ class Solution:
|
|
|
1074
1239
|
If the result's variable types are incompatible with the model environment's
|
|
1075
1240
|
variable types.
|
|
1076
1241
|
"""
|
|
1242
|
+
...
|
|
1077
1243
|
|
|
1078
|
-
@overload
|
|
1079
|
-
@staticmethod
|
|
1080
|
-
def from_dicts(data: list[dict[Variable, int]]) -> Solution: ...
|
|
1081
|
-
@overload
|
|
1082
|
-
@staticmethod
|
|
1083
|
-
def from_dicts(data: list[dict[Variable, float]]) -> Solution: ...
|
|
1084
|
-
@overload
|
|
1085
|
-
@staticmethod
|
|
1086
|
-
def from_dicts(data: list[dict[str, int]]) -> Solution: ...
|
|
1087
|
-
@overload
|
|
1088
|
-
@staticmethod
|
|
1089
|
-
def from_dicts(data: list[dict[str, float]]) -> Solution: ...
|
|
1090
|
-
@overload
|
|
1091
|
-
@staticmethod
|
|
1092
|
-
def from_dicts(data: list[dict[Variable | str, int | float]]) -> Solution: ...
|
|
1093
1244
|
@overload
|
|
1094
1245
|
@staticmethod
|
|
1095
1246
|
def from_dicts(
|
|
1096
|
-
data: list[dict[Variable, int]],
|
|
1247
|
+
data: list[dict[Variable, int]],
|
|
1248
|
+
*,
|
|
1249
|
+
env: Environment = ...,
|
|
1250
|
+
model: Model = ...,
|
|
1251
|
+
timing: Timing = ...,
|
|
1252
|
+
counts: list[int] = ...,
|
|
1253
|
+
sense: Sense = ...,
|
|
1097
1254
|
) -> Solution: ...
|
|
1098
1255
|
@overload
|
|
1099
1256
|
@staticmethod
|
|
1100
1257
|
def from_dicts(
|
|
1101
|
-
data: list[dict[Variable, float]],
|
|
1258
|
+
data: list[dict[Variable, float]],
|
|
1259
|
+
*,
|
|
1260
|
+
env: Environment = ...,
|
|
1261
|
+
model: Model = ...,
|
|
1262
|
+
timing: Timing = ...,
|
|
1263
|
+
counts: list[int] = ...,
|
|
1264
|
+
sense: Sense = ...,
|
|
1102
1265
|
) -> Solution: ...
|
|
1103
1266
|
@overload
|
|
1104
1267
|
@staticmethod
|
|
1105
|
-
def from_dicts(
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1268
|
+
def from_dicts(
|
|
1269
|
+
data: list[dict[str, int]],
|
|
1270
|
+
*,
|
|
1271
|
+
env: Environment = ...,
|
|
1272
|
+
model: Model = ...,
|
|
1273
|
+
timing: Timing = ...,
|
|
1274
|
+
counts: list[int] = ...,
|
|
1275
|
+
sense: Sense = ...,
|
|
1276
|
+
) -> Solution: ...
|
|
1109
1277
|
@overload
|
|
1110
1278
|
@staticmethod
|
|
1111
1279
|
def from_dicts(
|
|
1112
|
-
data: list[dict[
|
|
1280
|
+
data: list[dict[str, float]],
|
|
1281
|
+
*,
|
|
1282
|
+
env: Environment = ...,
|
|
1283
|
+
model: Model = ...,
|
|
1284
|
+
timing: Timing = ...,
|
|
1285
|
+
counts: list[int] = ...,
|
|
1286
|
+
sense: Sense = ...,
|
|
1113
1287
|
) -> Solution: ...
|
|
1114
1288
|
@overload
|
|
1115
1289
|
@staticmethod
|
|
1116
|
-
def from_dicts(
|
|
1290
|
+
def from_dicts(
|
|
1291
|
+
data: list[dict[Variable | str, int]],
|
|
1292
|
+
*,
|
|
1293
|
+
env: Environment = ...,
|
|
1294
|
+
model: Model = ...,
|
|
1295
|
+
timing: Timing = ...,
|
|
1296
|
+
counts: list[int] = ...,
|
|
1297
|
+
sense: Sense = ...,
|
|
1298
|
+
) -> Solution: ...
|
|
1117
1299
|
@overload
|
|
1118
1300
|
@staticmethod
|
|
1119
|
-
def from_dicts(
|
|
1301
|
+
def from_dicts(
|
|
1302
|
+
data: list[dict[Variable | str, float]],
|
|
1303
|
+
*,
|
|
1304
|
+
env: Environment = ...,
|
|
1305
|
+
model: Model = ...,
|
|
1306
|
+
timing: Timing = ...,
|
|
1307
|
+
counts: list[int] = ...,
|
|
1308
|
+
sense: Sense = ...,
|
|
1309
|
+
) -> Solution: ...
|
|
1120
1310
|
@overload
|
|
1121
1311
|
@staticmethod
|
|
1122
|
-
def from_dicts(
|
|
1312
|
+
def from_dicts(
|
|
1313
|
+
data: list[dict[Variable, int | float]],
|
|
1314
|
+
*,
|
|
1315
|
+
env: Environment = ...,
|
|
1316
|
+
model: Model = ...,
|
|
1317
|
+
timing: Timing = ...,
|
|
1318
|
+
counts: list[int] = ...,
|
|
1319
|
+
sense: Sense = ...,
|
|
1320
|
+
) -> Solution: ...
|
|
1123
1321
|
@overload
|
|
1124
1322
|
@staticmethod
|
|
1125
|
-
def from_dicts(
|
|
1323
|
+
def from_dicts(
|
|
1324
|
+
data: list[dict[str, int | float]],
|
|
1325
|
+
*,
|
|
1326
|
+
env: Environment = ...,
|
|
1327
|
+
model: Model = ...,
|
|
1328
|
+
timing: Timing = ...,
|
|
1329
|
+
counts: list[int] = ...,
|
|
1330
|
+
sense: Sense = ...,
|
|
1331
|
+
) -> Solution: ...
|
|
1126
1332
|
@overload
|
|
1127
1333
|
@staticmethod
|
|
1128
1334
|
def from_dicts(
|
|
1129
|
-
data: list[dict[Variable | str, int | float]],
|
|
1335
|
+
data: list[dict[Variable | str, int | float]],
|
|
1336
|
+
*,
|
|
1337
|
+
env: Environment = ...,
|
|
1338
|
+
model: Model = ...,
|
|
1339
|
+
timing: Timing = ...,
|
|
1340
|
+
counts: list[int] = ...,
|
|
1341
|
+
sense: Sense = ...,
|
|
1130
1342
|
) -> Solution: ...
|
|
1131
1343
|
@staticmethod
|
|
1132
1344
|
def from_dicts(
|
|
1133
1345
|
data: list[dict[Variable | str, int | float]],
|
|
1134
1346
|
*,
|
|
1135
|
-
env: Environment | None = ...,
|
|
1136
|
-
model: Model | None = ...,
|
|
1137
|
-
timing: Timing | None = ...,
|
|
1347
|
+
env: (Environment | None) = ...,
|
|
1348
|
+
model: (Model | None) = ...,
|
|
1349
|
+
timing: (Timing | None) = ...,
|
|
1350
|
+
counts: (list[int] | None) = ...,
|
|
1351
|
+
sense: (Sense | None) = ...,
|
|
1138
1352
|
) -> Solution:
|
|
1139
|
-
"""
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1353
|
+
"""Create a `Solution` from multiple dicts.
|
|
1354
|
+
|
|
1355
|
+
Create a `Solution` from multiple dicts that map variables or variable names to
|
|
1356
|
+
their assigned values. Duplicate samples contained in the `data` list are
|
|
1357
|
+
aggregated to a single sample.
|
|
1143
1358
|
|
|
1144
1359
|
If a Model is passed, the solution will be evaluated immediately. Otherwise,
|
|
1145
1360
|
there has to be an environment present to determine the correct variable types.
|
|
@@ -1152,6 +1367,10 @@ class Solution:
|
|
|
1152
1367
|
The environment the variable types shall be determined from.
|
|
1153
1368
|
model : Model, optional
|
|
1154
1369
|
A model to evaluate the sample with.
|
|
1370
|
+
counts : int, optional
|
|
1371
|
+
The number of occurrences for each sample.
|
|
1372
|
+
sense: Sense, optional
|
|
1373
|
+
The sense of the optimization problem.
|
|
1155
1374
|
|
|
1156
1375
|
Returns
|
|
1157
1376
|
-------
|
|
@@ -1166,6 +1385,8 @@ class Solution:
|
|
|
1166
1385
|
ValueError
|
|
1167
1386
|
If `env` and `model` are both present. When this is the case, the user's
|
|
1168
1387
|
intention is unclear as the model itself already contains an environment.
|
|
1388
|
+
Or if `sense` and `model` are both present as the sense is then ambiguous.
|
|
1389
|
+
Or if the the number of samples and the number of counts do not match.
|
|
1169
1390
|
SolutionTranslationError
|
|
1170
1391
|
Generally if the sample translation fails. Might be specified by one of the
|
|
1171
1392
|
three following errors.
|
|
@@ -1177,8 +1398,130 @@ class Solution:
|
|
|
1177
1398
|
If the result's variable types are incompatible with the model environment's
|
|
1178
1399
|
variable types.
|
|
1179
1400
|
"""
|
|
1401
|
+
...
|
|
1402
|
+
|
|
1403
|
+
@staticmethod
|
|
1404
|
+
def from_counts(
|
|
1405
|
+
data: dict[str, int],
|
|
1406
|
+
*,
|
|
1407
|
+
env: (Environment | None) = ...,
|
|
1408
|
+
model: (Model | None) = ...,
|
|
1409
|
+
timing: (Timing | None) = ...,
|
|
1410
|
+
sense: (Sense | None) = ...,
|
|
1411
|
+
bit_order: Literal["LTR", "RTL"] = "RTL",
|
|
1412
|
+
) -> Solution:
|
|
1413
|
+
"""
|
|
1414
|
+
Create a `Solution` from a dict that maps measured bitstrings to counts.
|
|
1415
|
+
|
|
1416
|
+
If a Model is passed, the solution will be evaluated immediately. Otherwise,
|
|
1417
|
+
there has to be an environment present to determine the correct variable types.
|
|
1418
|
+
Only applicable to binary or spin models.
|
|
1419
|
+
|
|
1420
|
+
Parameters
|
|
1421
|
+
----------
|
|
1422
|
+
data : dict[str, int]
|
|
1423
|
+
The counts that shall be part of the solution.
|
|
1424
|
+
env : Environment, optional
|
|
1425
|
+
The environment the variable types shall be determined from.
|
|
1426
|
+
model : Model, optional
|
|
1427
|
+
A model to evaluate the sample with.
|
|
1428
|
+
timing : Timing, optional
|
|
1429
|
+
The timing for acquiring the solution.
|
|
1430
|
+
sense : Sense, optional
|
|
1431
|
+
The sense the model the solution belongs to. Default: Sense.Min
|
|
1432
|
+
bit_order : Literal["LTR", "RTL"]
|
|
1433
|
+
The order of the bits in the bitstring. Default "RTL".
|
|
1434
|
+
|
|
1435
|
+
Returns
|
|
1436
|
+
-------
|
|
1437
|
+
Solution
|
|
1438
|
+
The solution object created from the sample dict.
|
|
1439
|
+
|
|
1440
|
+
Raises
|
|
1441
|
+
------
|
|
1442
|
+
NoActiveEnvironmentFoundError
|
|
1443
|
+
If no environment or model is passed to the method or available from the
|
|
1444
|
+
context.
|
|
1445
|
+
ValueError
|
|
1446
|
+
If `env` and `model` are both present. When this is the case, the user's
|
|
1447
|
+
intention is unclear as the model itself already contains an environment.
|
|
1448
|
+
Or if `sense` and `model` are both present as the sense is then ambiguous.
|
|
1449
|
+
Or if the the environment contains non-(binary or spin) variables.
|
|
1450
|
+
Or if a bitstring contains chars other than '0' and '1'.
|
|
1451
|
+
SolutionTranslationError
|
|
1452
|
+
Generally if the sample translation fails. Might be specified by one of the
|
|
1453
|
+
three following errors.
|
|
1454
|
+
SampleIncorrectLengthErr
|
|
1455
|
+
If a sample has a different number of variables than the environment.
|
|
1456
|
+
"""
|
|
1457
|
+
...
|
|
1458
|
+
|
|
1459
|
+
def print(
|
|
1460
|
+
self,
|
|
1461
|
+
/,
|
|
1462
|
+
layout: Literal["row", "column"] = "column",
|
|
1463
|
+
max_line_length: int = 80,
|
|
1464
|
+
max_column_length: int = 5,
|
|
1465
|
+
max_lines: int = 10,
|
|
1466
|
+
max_var_name_length: int = 10,
|
|
1467
|
+
show_metadata: Literal["before", "after", "hide"] = "after",
|
|
1468
|
+
) -> None:
|
|
1469
|
+
"""
|
|
1470
|
+
Show a solution object as a human-readable string.
|
|
1471
|
+
|
|
1472
|
+
This method provides various ways to customize the way the solution is
|
|
1473
|
+
represented as a string.
|
|
1474
|
+
|
|
1475
|
+
Parameters
|
|
1476
|
+
----------
|
|
1477
|
+
layout : Literal["row", "column"]
|
|
1478
|
+
With `"row"` layout, all assignments to one variable across different
|
|
1479
|
+
samples are shown in the same *row*, and each sample is shown in one
|
|
1480
|
+
column.
|
|
1481
|
+
With `"column"` layout, all assignments to one variable across different
|
|
1482
|
+
samples are shown in the same *column*, and each sample is shown in one row.
|
|
1483
|
+
max_line_length : int
|
|
1484
|
+
The max number of chars shown in one line or, in other words, the max width
|
|
1485
|
+
of a row.
|
|
1486
|
+
max_column_length : int
|
|
1487
|
+
The maximal number of chars in one column. For both the row and column
|
|
1488
|
+
layout, this controls the max number of chars a single variable assignment
|
|
1489
|
+
may be shown with. For the column layout, this also controls the max number
|
|
1490
|
+
of chars that a variable name is shown with.
|
|
1491
|
+
Note: the max column length cannot always be adhered to. This is
|
|
1492
|
+
specifically the case when a variable assignment is so high that the max
|
|
1493
|
+
column length is not sufficient to show the number correctly.
|
|
1494
|
+
max_lines : int
|
|
1495
|
+
The max number of lines used for showing the samples. Note that this
|
|
1496
|
+
parameter does not influence how metadata are shown, s.t. the total number
|
|
1497
|
+
of lines may be higher than `max_lines`.
|
|
1498
|
+
max_var_name_length : int
|
|
1499
|
+
The max number of chars that a variable is shown with in row layout. This
|
|
1500
|
+
parameter is ignored in column layout.
|
|
1501
|
+
show_metadata : Literal["before", "after", "hide"]
|
|
1502
|
+
Whether and where to show sample-specific metadata such as feasibility and
|
|
1503
|
+
objective value. Note that this parameter only controls how sample-specific
|
|
1504
|
+
metadata are shown. Other metadata, like the solution timing will be shown
|
|
1505
|
+
after the samples regardless of the value of this parameter.
|
|
1506
|
+
|
|
1507
|
+
- `"before"`: show metadata before the actual sample, i.e., above the
|
|
1508
|
+
sample in row layout, and left of the sample in column layout.
|
|
1509
|
+
- `"after"`: show metadata after the actual sample, i.e., below the
|
|
1510
|
+
sample in row layout, and right of the sample in column layout.
|
|
1511
|
+
- "hide": do not show sample-specific metadata.
|
|
1512
|
+
|
|
1513
|
+
Returns
|
|
1514
|
+
-------
|
|
1515
|
+
str
|
|
1516
|
+
The solution represented as a string.
|
|
1517
|
+
|
|
1518
|
+
Raises
|
|
1519
|
+
------
|
|
1520
|
+
ValueError
|
|
1521
|
+
If at least one of the params has an invalid value.
|
|
1522
|
+
"""
|
|
1523
|
+
...
|
|
1180
1524
|
|
|
1181
|
-
# _sample.pyi
|
|
1182
1525
|
class SamplesIterator:
|
|
1183
1526
|
"""
|
|
1184
1527
|
An iterator over a solution's samples.
|
|
@@ -1222,12 +1565,11 @@ class SampleIterator:
|
|
|
1222
1565
|
def __next__(self, /) -> int | float: ...
|
|
1223
1566
|
|
|
1224
1567
|
class Samples:
|
|
1225
|
-
"""
|
|
1226
|
-
A samples object is simply a set-like object that contains every different sample
|
|
1227
|
-
of a solution.
|
|
1568
|
+
"""A set-like object containing every different sample of a solution.
|
|
1228
1569
|
|
|
1229
|
-
|
|
1230
|
-
solution's
|
|
1570
|
+
A samples object is simply a set-like object that contains every different sample
|
|
1571
|
+
of a solution. The ``Samples`` class is readonly as it's merely a helper class for
|
|
1572
|
+
looking into a solution's different samples.
|
|
1231
1573
|
|
|
1232
1574
|
Examples
|
|
1233
1575
|
--------
|
|
@@ -1240,12 +1582,14 @@ class Samples:
|
|
|
1240
1582
|
[1, -4, -0.42]
|
|
1241
1583
|
"""
|
|
1242
1584
|
|
|
1585
|
+
def __str__(self, /) -> str: ...
|
|
1243
1586
|
@overload
|
|
1244
1587
|
def __getitem__(self, item: int, /) -> Sample: ...
|
|
1245
1588
|
@overload
|
|
1246
|
-
def __getitem__(self, item: tuple[int, int], /) -> int | float:
|
|
1247
|
-
|
|
1248
|
-
Extract a sample or variable assignment from the ``Samples`` object.
|
|
1589
|
+
def __getitem__(self, item: tuple[int, int], /) -> int | float: ...
|
|
1590
|
+
def __getitem__(self, item: (int | tuple[int, int]), /) -> int | float:
|
|
1591
|
+
"""Extract a sample or variable assignment from the ``Samples`` object.
|
|
1592
|
+
|
|
1249
1593
|
If ``item`` is an int, returns the sample in this row. If ``item`` is a tuple
|
|
1250
1594
|
of ints `(i, j)`, returns the variable assignment in row `i` and column `j`.
|
|
1251
1595
|
|
|
@@ -1260,6 +1604,7 @@ class Samples:
|
|
|
1260
1604
|
IndexError
|
|
1261
1605
|
If the row or column index is out of bounds for the variable environment.
|
|
1262
1606
|
"""
|
|
1607
|
+
...
|
|
1263
1608
|
|
|
1264
1609
|
def __len__(self, /) -> int:
|
|
1265
1610
|
"""
|
|
@@ -1269,6 +1614,7 @@ class Samples:
|
|
|
1269
1614
|
-------
|
|
1270
1615
|
int
|
|
1271
1616
|
"""
|
|
1617
|
+
...
|
|
1272
1618
|
|
|
1273
1619
|
def __iter__(self, /) -> SamplesIterator:
|
|
1274
1620
|
"""
|
|
@@ -1278,9 +1624,11 @@ class Samples:
|
|
|
1278
1624
|
-------
|
|
1279
1625
|
SamplesIterator
|
|
1280
1626
|
"""
|
|
1627
|
+
...
|
|
1281
1628
|
|
|
1282
1629
|
def tolist(self, /) -> list[list[int | float]]:
|
|
1283
|
-
"""
|
|
1630
|
+
"""Convert sample into a 2-dimensional list.
|
|
1631
|
+
|
|
1284
1632
|
Convert the sample into a 2-dimensional list where a row constitutes a single
|
|
1285
1633
|
sample, and a column constitutes all assignments for a single variable.
|
|
1286
1634
|
|
|
@@ -1289,10 +1637,12 @@ class Samples:
|
|
|
1289
1637
|
list[list[int | float]]
|
|
1290
1638
|
The samples object as a 2-dimensional list.
|
|
1291
1639
|
"""
|
|
1640
|
+
...
|
|
1292
1641
|
|
|
1293
1642
|
class Sample:
|
|
1294
|
-
"""
|
|
1295
|
-
|
|
1643
|
+
"""Assignment of actual values to the model's variables.
|
|
1644
|
+
|
|
1645
|
+
A sample object is an assignment of an actual value to each of the model's
|
|
1296
1646
|
variables.
|
|
1297
1647
|
|
|
1298
1648
|
The ``Sample`` class is readonly as it's merely a helper class for looking into a
|
|
@@ -1311,17 +1661,20 @@ class Sample:
|
|
|
1311
1661
|
[0, -5, 0.28]
|
|
1312
1662
|
"""
|
|
1313
1663
|
|
|
1664
|
+
def __str__(self, /) -> str: ...
|
|
1314
1665
|
@overload
|
|
1315
1666
|
def __getitem__(self, item: int, /) -> int | float: ...
|
|
1316
1667
|
@overload
|
|
1317
1668
|
def __getitem__(self, item: Variable, /) -> int | float: ...
|
|
1318
|
-
|
|
1669
|
+
@overload
|
|
1670
|
+
def __getitem__(self, item: str, /) -> int | float: ...
|
|
1671
|
+
def __getitem__(self, item: (int | Variable | str), /) -> int | float:
|
|
1319
1672
|
"""
|
|
1320
1673
|
Extract a variable assignment from the ``Sample`` object.
|
|
1321
1674
|
|
|
1322
1675
|
Returns
|
|
1323
1676
|
-------
|
|
1324
|
-
|
|
1677
|
+
int or float
|
|
1325
1678
|
|
|
1326
1679
|
Raises
|
|
1327
1680
|
------
|
|
@@ -1330,6 +1683,7 @@ class Sample:
|
|
|
1330
1683
|
IndexError
|
|
1331
1684
|
If the row or column index is out of bounds for the variable environment.
|
|
1332
1685
|
"""
|
|
1686
|
+
...
|
|
1333
1687
|
|
|
1334
1688
|
def __len__(self, /) -> int:
|
|
1335
1689
|
"""
|
|
@@ -1339,6 +1693,7 @@ class Sample:
|
|
|
1339
1693
|
-------
|
|
1340
1694
|
int
|
|
1341
1695
|
"""
|
|
1696
|
+
...
|
|
1342
1697
|
|
|
1343
1698
|
def __iter__(self, /) -> SampleIterator:
|
|
1344
1699
|
"""
|
|
@@ -1348,8 +1703,18 @@ class Sample:
|
|
|
1348
1703
|
-------
|
|
1349
1704
|
SampleIterator
|
|
1350
1705
|
"""
|
|
1706
|
+
...
|
|
1707
|
+
|
|
1708
|
+
def to_dict(self, /) -> dict[str, int | float]:
|
|
1709
|
+
"""Convert the sample to a dictionary.
|
|
1710
|
+
|
|
1711
|
+
Returns
|
|
1712
|
+
-------
|
|
1713
|
+
dict
|
|
1714
|
+
A dictionary representation of the sample, where the keys are the
|
|
1715
|
+
variable names and the values are the variables' assignments.
|
|
1716
|
+
"""
|
|
1351
1717
|
|
|
1352
|
-
# _result.pyi
|
|
1353
1718
|
class ResultIterator:
|
|
1354
1719
|
"""
|
|
1355
1720
|
An iterator over a solution's results.
|
|
@@ -1398,28 +1763,35 @@ class Result:
|
|
|
1398
1763
|
@property
|
|
1399
1764
|
def sample(self, /) -> Sample:
|
|
1400
1765
|
"""Get the sample of the result."""
|
|
1766
|
+
...
|
|
1401
1767
|
|
|
1402
1768
|
@property
|
|
1403
1769
|
def obj_value(self, /) -> float | None:
|
|
1404
1770
|
"""Get the objective value of the result."""
|
|
1771
|
+
...
|
|
1405
1772
|
|
|
1406
1773
|
@property
|
|
1407
1774
|
def constraints(self, /) -> NDArray | None:
|
|
1408
|
-
"""
|
|
1775
|
+
"""The result's feasibility of all constraints.
|
|
1776
|
+
|
|
1409
1777
|
Get this result's feasibility values of all constraints. Note that
|
|
1410
1778
|
`results.constraints[i]` iff. `model.constraints[i]` is feasible for
|
|
1411
1779
|
this result.
|
|
1412
1780
|
"""
|
|
1781
|
+
...
|
|
1413
1782
|
|
|
1414
1783
|
@property
|
|
1415
1784
|
def variable_bounds(self, /) -> NDArray | None:
|
|
1416
|
-
"""
|
|
1417
|
-
|
|
1418
|
-
"""
|
|
1785
|
+
"""Get this result's feasibility values of all variable bounds."""
|
|
1786
|
+
...
|
|
1419
1787
|
|
|
1420
1788
|
@property
|
|
1421
1789
|
def feasible(self, /) -> bool | None:
|
|
1422
1790
|
"""Return whether all constraint results are feasible for this result."""
|
|
1791
|
+
...
|
|
1792
|
+
|
|
1793
|
+
def __str__(self, /) -> str: ...
|
|
1794
|
+
def __repr__(self, /) -> str: ...
|
|
1423
1795
|
|
|
1424
1796
|
class ResultView:
|
|
1425
1797
|
"""
|
|
@@ -1450,46 +1822,56 @@ class ResultView:
|
|
|
1450
1822
|
@property
|
|
1451
1823
|
def sample(self, /) -> Sample:
|
|
1452
1824
|
"""Get the sample of the result."""
|
|
1825
|
+
...
|
|
1453
1826
|
|
|
1454
1827
|
@property
|
|
1455
1828
|
def counts(self, /) -> int:
|
|
1456
1829
|
"""Return how often this result appears in the solution."""
|
|
1830
|
+
...
|
|
1457
1831
|
|
|
1458
1832
|
@property
|
|
1459
1833
|
def obj_value(self, /) -> float | None:
|
|
1460
1834
|
"""
|
|
1461
|
-
Get the objective value of this sample if present.
|
|
1462
|
-
|
|
1835
|
+
Get the objective value of this sample if present.
|
|
1836
|
+
|
|
1837
|
+
This is the value computed by the corresponding AqModel.
|
|
1463
1838
|
"""
|
|
1839
|
+
...
|
|
1464
1840
|
|
|
1465
1841
|
@property
|
|
1466
1842
|
def raw_energy(self, /) -> float | None:
|
|
1467
1843
|
"""
|
|
1468
|
-
Get the raw energy returned by the algorithm if present.
|
|
1469
|
-
|
|
1844
|
+
Get the raw energy returned by the algorithm if present.
|
|
1845
|
+
|
|
1846
|
+
This value is not guaranteed to be accurate under consideration of the
|
|
1847
|
+
corresponding AqModel.
|
|
1470
1848
|
"""
|
|
1849
|
+
...
|
|
1471
1850
|
|
|
1472
1851
|
@property
|
|
1473
1852
|
def constraints(self, /) -> NDArray | None:
|
|
1474
1853
|
"""
|
|
1475
|
-
Get this result's feasibility values of all constraints.
|
|
1476
|
-
|
|
1854
|
+
Get this result's feasibility values of all constraints.
|
|
1855
|
+
|
|
1856
|
+
Note that `results.constraints[i]` iff. `model.constraints[i]` is feasible for
|
|
1477
1857
|
this result.
|
|
1478
1858
|
"""
|
|
1859
|
+
...
|
|
1479
1860
|
|
|
1480
1861
|
@property
|
|
1481
1862
|
def variable_bounds(self, /) -> NDArray | None:
|
|
1482
|
-
"""
|
|
1483
|
-
|
|
1484
|
-
"""
|
|
1863
|
+
"""Get this result's feasibility values of all variable bounds."""
|
|
1864
|
+
...
|
|
1485
1865
|
|
|
1486
1866
|
@property
|
|
1487
1867
|
def feasible(self, /) -> bool | None:
|
|
1488
1868
|
"""Return whether all constraint results are feasible for this result."""
|
|
1869
|
+
...
|
|
1489
1870
|
|
|
1490
|
-
def
|
|
1871
|
+
def __str__(self, /) -> str: ...
|
|
1872
|
+
def __repr__(self, /) -> str: ...
|
|
1873
|
+
def __eq__(self, other: ResultView, /) -> bool: ...
|
|
1491
1874
|
|
|
1492
|
-
# _model.pyi
|
|
1493
1875
|
class Sense(Enum):
|
|
1494
1876
|
"""
|
|
1495
1877
|
Enumeration of optimization senses supported by the optimization system.
|
|
@@ -1500,7 +1882,6 @@ class Sense(Enum):
|
|
|
1500
1882
|
|
|
1501
1883
|
Min = ...
|
|
1502
1884
|
"""Indicate the objective function to be minimized."""
|
|
1503
|
-
|
|
1504
1885
|
Max = ...
|
|
1505
1886
|
"""Indicate the objective function to be maximized."""
|
|
1506
1887
|
|
|
@@ -1558,22 +1939,11 @@ class Model:
|
|
|
1558
1939
|
Notes
|
|
1559
1940
|
-----
|
|
1560
1941
|
- The `Model` class does not solve the optimization problem.
|
|
1561
|
-
- Use `.objective`, `.constraints`, and `.environment` to access the symbolic
|
|
1942
|
+
- Use `.objective`, `.constraints`, and `.environment` to access the symbolic
|
|
1943
|
+
content.
|
|
1562
1944
|
- Use `encode()` and `decode()` to serialize and recover models.
|
|
1563
1945
|
"""
|
|
1564
1946
|
|
|
1565
|
-
metadata: ModelMetadata | None = ...
|
|
1566
|
-
|
|
1567
|
-
@staticmethod
|
|
1568
|
-
def load_luna(model_id: str, client: ILunaSolve | str | None = None) -> Model: ...
|
|
1569
|
-
def save_luna(self, client: ILunaSolve | str | None = None) -> None: ...
|
|
1570
|
-
def delete_luna(self, client: ILunaSolve | str | None = None) -> None: ...
|
|
1571
|
-
def load_solutions(
|
|
1572
|
-
self, client: ILunaSolve | str | None = None
|
|
1573
|
-
) -> list[Solution]: ...
|
|
1574
|
-
def load_solve_jobs(
|
|
1575
|
-
self, client: ILunaSolve | str | None = None
|
|
1576
|
-
) -> list[SolveJob]: ...
|
|
1577
1947
|
@overload
|
|
1578
1948
|
def __init__(self, /) -> None: ...
|
|
1579
1949
|
@overload
|
|
@@ -1593,10 +1963,10 @@ class Model:
|
|
|
1593
1963
|
def __init__(
|
|
1594
1964
|
self,
|
|
1595
1965
|
/,
|
|
1596
|
-
name: str | None = ...,
|
|
1966
|
+
name: (str | None) = ...,
|
|
1597
1967
|
*,
|
|
1598
|
-
sense: Sense | None = ...,
|
|
1599
|
-
env: Environment | None = ...,
|
|
1968
|
+
sense: (Sense | None) = ...,
|
|
1969
|
+
env: (Environment | None) = ...,
|
|
1600
1970
|
) -> None:
|
|
1601
1971
|
"""
|
|
1602
1972
|
Initialize a new symbolic model.
|
|
@@ -1609,6 +1979,7 @@ class Model:
|
|
|
1609
1979
|
The environment in which the model operates. If not provided, a new
|
|
1610
1980
|
environment will be created or inferred from context.
|
|
1611
1981
|
"""
|
|
1982
|
+
...
|
|
1612
1983
|
|
|
1613
1984
|
def set_sense(self, /, sense: Sense) -> None:
|
|
1614
1985
|
"""
|
|
@@ -1619,47 +1990,130 @@ class Model:
|
|
|
1619
1990
|
sense : Sense
|
|
1620
1991
|
The sense of the model (minimization, maximization)
|
|
1621
1992
|
"""
|
|
1993
|
+
...
|
|
1994
|
+
|
|
1995
|
+
@overload
|
|
1996
|
+
def add_variable(self, name: str, /) -> Variable: ...
|
|
1997
|
+
@overload
|
|
1998
|
+
def add_variable(self, name: str, /, vtype: (Vtype | None) = ...) -> Variable: ...
|
|
1999
|
+
@overload
|
|
2000
|
+
def add_variable(
|
|
2001
|
+
self, name: str, /, vtype: Vtype, *, lower: (float | type[Unbounded])
|
|
2002
|
+
) -> Variable: ...
|
|
2003
|
+
@overload
|
|
2004
|
+
def add_variable(
|
|
2005
|
+
self, name: str, /, vtype: Vtype, *, upper: (float | type[Unbounded])
|
|
2006
|
+
) -> Variable: ...
|
|
2007
|
+
@overload
|
|
2008
|
+
def add_variable(
|
|
2009
|
+
self,
|
|
2010
|
+
name: str,
|
|
2011
|
+
/,
|
|
2012
|
+
vtype: Vtype,
|
|
2013
|
+
*,
|
|
2014
|
+
lower: (float | type[Unbounded]),
|
|
2015
|
+
upper: (float | type[Unbounded]),
|
|
2016
|
+
) -> Variable: ...
|
|
2017
|
+
def add_variable(
|
|
2018
|
+
self,
|
|
2019
|
+
name: str,
|
|
2020
|
+
/,
|
|
2021
|
+
vtype: (Vtype | None) = ...,
|
|
2022
|
+
*,
|
|
2023
|
+
lower: (float | type[Unbounded] | None) = ...,
|
|
2024
|
+
upper: (float | type[Unbounded] | None) = ...,
|
|
2025
|
+
) -> Variable:
|
|
2026
|
+
"""
|
|
2027
|
+
Add a new variable to the model.
|
|
2028
|
+
|
|
2029
|
+
Parameters
|
|
2030
|
+
----------
|
|
2031
|
+
name : str
|
|
2032
|
+
The name of the variable.
|
|
2033
|
+
vtype : Vtype, optional
|
|
2034
|
+
The variable type (e.g., `Vtype.Real`, `Vtype.Integer`, etc.).
|
|
2035
|
+
Defaults to `Vtype.Binary`.
|
|
2036
|
+
lower: float, optional
|
|
2037
|
+
The lower bound restricts the range of the variable. Only applicable for
|
|
2038
|
+
`Real` and `Integer` variables.
|
|
2039
|
+
upper: float, optional
|
|
2040
|
+
The upper bound restricts the range of the variable. Only applicable for
|
|
2041
|
+
`Real` and `Integer` variables.
|
|
2042
|
+
|
|
2043
|
+
Returns
|
|
2044
|
+
-------
|
|
2045
|
+
Variable
|
|
2046
|
+
The variable added to the model.
|
|
2047
|
+
"""
|
|
2048
|
+
...
|
|
2049
|
+
|
|
2050
|
+
def get_variable(self, name: str, /) -> Variable:
|
|
2051
|
+
"""Get a variable by its label (name).
|
|
2052
|
+
|
|
2053
|
+
Parameters
|
|
2054
|
+
----------
|
|
2055
|
+
label : str
|
|
2056
|
+
The name/label of the variable
|
|
2057
|
+
|
|
2058
|
+
Returns
|
|
2059
|
+
-------
|
|
2060
|
+
Variable
|
|
2061
|
+
The variable with the specified label/name.
|
|
2062
|
+
|
|
2063
|
+
Raises
|
|
2064
|
+
------
|
|
2065
|
+
VariableNotExistingError
|
|
2066
|
+
If no variable with the specified name is registered.
|
|
2067
|
+
"""
|
|
2068
|
+
...
|
|
1622
2069
|
|
|
1623
2070
|
@property
|
|
1624
2071
|
def name(self, /) -> str:
|
|
1625
2072
|
"""Return the name of the model."""
|
|
2073
|
+
...
|
|
1626
2074
|
|
|
1627
2075
|
@property
|
|
1628
2076
|
def sense(self, /) -> Sense:
|
|
1629
2077
|
"""
|
|
1630
|
-
Get the sense of the model
|
|
2078
|
+
Get the sense of the model.
|
|
1631
2079
|
|
|
1632
2080
|
Returns
|
|
1633
2081
|
-------
|
|
1634
2082
|
Sense
|
|
1635
2083
|
The sense of the model (Min or Max).
|
|
1636
2084
|
"""
|
|
2085
|
+
...
|
|
1637
2086
|
|
|
1638
2087
|
@property
|
|
1639
2088
|
def objective(self, /) -> Expression:
|
|
1640
2089
|
"""Get the objective expression of the model."""
|
|
2090
|
+
...
|
|
1641
2091
|
|
|
1642
2092
|
@objective.setter
|
|
1643
|
-
def objective(self, value: Expression, /):
|
|
2093
|
+
def objective(self, value: Expression, /) -> None:
|
|
1644
2094
|
"""Set the objective expression of the model."""
|
|
2095
|
+
...
|
|
1645
2096
|
|
|
1646
2097
|
@property
|
|
1647
2098
|
def constraints(self, /) -> Constraints:
|
|
1648
2099
|
"""Access the set of constraints associated with the model."""
|
|
2100
|
+
...
|
|
1649
2101
|
|
|
1650
2102
|
@constraints.setter
|
|
1651
|
-
def constraints(self, value: Constraints, /):
|
|
2103
|
+
def constraints(self, value: Constraints, /) -> None:
|
|
1652
2104
|
"""Replace the model's constraints with a new set."""
|
|
2105
|
+
...
|
|
1653
2106
|
|
|
1654
2107
|
@property
|
|
1655
2108
|
def environment(self, /) -> Environment:
|
|
1656
2109
|
"""Get the environment in which this model is defined."""
|
|
2110
|
+
...
|
|
1657
2111
|
|
|
1658
2112
|
@overload
|
|
1659
2113
|
def variables(self, /) -> list[Variable]: ...
|
|
1660
2114
|
@overload
|
|
1661
2115
|
def variables(self, /, *, active: bool) -> list[Variable]: ...
|
|
1662
|
-
def variables(self, /, active: bool | None = ...) -> list[Variable]:
|
|
2116
|
+
def variables(self, /, active: (bool | None) = ...) -> list[Variable]:
|
|
1663
2117
|
"""
|
|
1664
2118
|
Get all variables that are part of this model.
|
|
1665
2119
|
|
|
@@ -1673,12 +2127,15 @@ class Model:
|
|
|
1673
2127
|
-------
|
|
1674
2128
|
The model's variables as a list.
|
|
1675
2129
|
"""
|
|
2130
|
+
...
|
|
1676
2131
|
|
|
1677
2132
|
@overload
|
|
1678
|
-
def add_constraint(self, /, constraint: Constraint): ...
|
|
2133
|
+
def add_constraint(self, /, constraint: Constraint) -> None: ...
|
|
1679
2134
|
@overload
|
|
1680
|
-
def add_constraint(self, /, constraint: Constraint, name: str): ...
|
|
1681
|
-
def add_constraint(
|
|
2135
|
+
def add_constraint(self, /, constraint: Constraint, name: str) -> None: ...
|
|
2136
|
+
def add_constraint(
|
|
2137
|
+
self, /, constraint: Constraint, name: (str | None) = ...
|
|
2138
|
+
) -> None:
|
|
1682
2139
|
"""
|
|
1683
2140
|
Add a constraint to the model's constraint collection.
|
|
1684
2141
|
|
|
@@ -1689,12 +2146,15 @@ class Model:
|
|
|
1689
2146
|
name : str, optional
|
|
1690
2147
|
The name of the constraint to be added.
|
|
1691
2148
|
"""
|
|
2149
|
+
...
|
|
1692
2150
|
|
|
1693
2151
|
@overload
|
|
1694
|
-
def set_objective(self, /, expression: Expression): ...
|
|
2152
|
+
def set_objective(self, /, expression: Expression) -> None: ...
|
|
1695
2153
|
@overload
|
|
1696
|
-
def set_objective(self, /, expression: Expression, *, sense: Sense): ...
|
|
1697
|
-
def set_objective(
|
|
2154
|
+
def set_objective(self, /, expression: Expression, *, sense: Sense) -> None: ...
|
|
2155
|
+
def set_objective(
|
|
2156
|
+
self, /, expression: Expression, *, sense: (Sense | None) = ...
|
|
2157
|
+
) -> None:
|
|
1698
2158
|
"""
|
|
1699
2159
|
Set the model's objective to this expression.
|
|
1700
2160
|
|
|
@@ -1705,6 +2165,7 @@ class Model:
|
|
|
1705
2165
|
sense : Sense, optional
|
|
1706
2166
|
The sense of the model for this objective, by default Sense.Min.
|
|
1707
2167
|
"""
|
|
2168
|
+
...
|
|
1708
2169
|
|
|
1709
2170
|
@property
|
|
1710
2171
|
def num_constraints(self, /) -> int:
|
|
@@ -1716,6 +2177,7 @@ class Model:
|
|
|
1716
2177
|
int
|
|
1717
2178
|
Total number of constraints.
|
|
1718
2179
|
"""
|
|
2180
|
+
...
|
|
1719
2181
|
|
|
1720
2182
|
def evaluate(self, /, solution: Solution) -> Solution:
|
|
1721
2183
|
"""
|
|
@@ -1731,6 +2193,7 @@ class Model:
|
|
|
1731
2193
|
Solution
|
|
1732
2194
|
A new solution object with filled-out information.
|
|
1733
2195
|
"""
|
|
2196
|
+
...
|
|
1734
2197
|
|
|
1735
2198
|
def evaluate_sample(self, /, sample: Sample) -> Result:
|
|
1736
2199
|
"""
|
|
@@ -1746,6 +2209,55 @@ class Model:
|
|
|
1746
2209
|
Result
|
|
1747
2210
|
A result object containing the information from the evaluation process.
|
|
1748
2211
|
"""
|
|
2212
|
+
...
|
|
2213
|
+
|
|
2214
|
+
def violated_constraints(self, /, sample: Sample) -> Constraints:
|
|
2215
|
+
"""
|
|
2216
|
+
Get all model constraints that are violated by the given sample.
|
|
2217
|
+
|
|
2218
|
+
Parameters
|
|
2219
|
+
----------
|
|
2220
|
+
sample : Sample
|
|
2221
|
+
The sample to check constraint feasibility for.
|
|
2222
|
+
|
|
2223
|
+
Returns
|
|
2224
|
+
-------
|
|
2225
|
+
Constraints
|
|
2226
|
+
The constraints violated by the given sample.
|
|
2227
|
+
"""
|
|
2228
|
+
...
|
|
2229
|
+
|
|
2230
|
+
def substitute(
|
|
2231
|
+
self, /, target: Variable, replacement: (Expression | Variable)
|
|
2232
|
+
) -> None:
|
|
2233
|
+
"""Substitute every occurrence of variable.
|
|
2234
|
+
|
|
2235
|
+
Substitute every occurrence of a variable in the model's objective and
|
|
2236
|
+
constraint expressions with another expression.
|
|
2237
|
+
|
|
2238
|
+
Given a `Model` instance `self`, this method replaces all occurrences of
|
|
2239
|
+
`target` with `replacement` for the objective and each constraint.
|
|
2240
|
+
If any substitution would cross differing environments (e.g. captures from two
|
|
2241
|
+
different scopes), it raises a `DifferentEnvsError`.
|
|
2242
|
+
|
|
2243
|
+
Parameters
|
|
2244
|
+
----------
|
|
2245
|
+
target : VarRef
|
|
2246
|
+
The variable reference to replace.
|
|
2247
|
+
replacement : Expression
|
|
2248
|
+
The expression to insert in place of `target`.
|
|
2249
|
+
|
|
2250
|
+
Returns
|
|
2251
|
+
-------
|
|
2252
|
+
None
|
|
2253
|
+
Performs substitution in place; no return value.
|
|
2254
|
+
|
|
2255
|
+
Raises
|
|
2256
|
+
------
|
|
2257
|
+
DifferentEnvsError
|
|
2258
|
+
If the environments of `self`, `target`, and `replacement`
|
|
2259
|
+
are not compatible.
|
|
2260
|
+
"""
|
|
1749
2261
|
|
|
1750
2262
|
@overload
|
|
1751
2263
|
def encode(self, /) -> bytes: ...
|
|
@@ -1755,7 +2267,9 @@ class Model:
|
|
|
1755
2267
|
def encode(self, /, *, level: int) -> bytes: ...
|
|
1756
2268
|
@overload
|
|
1757
2269
|
def encode(self, /, compress: bool, level: int) -> bytes: ...
|
|
1758
|
-
def encode(
|
|
2270
|
+
def encode(
|
|
2271
|
+
self, /, compress: (bool | None) = True, level: (int | None) = 3
|
|
2272
|
+
) -> bytes:
|
|
1759
2273
|
"""
|
|
1760
2274
|
Serialize the model into a compact binary format.
|
|
1761
2275
|
|
|
@@ -1764,7 +2278,7 @@ class Model:
|
|
|
1764
2278
|
compress : bool, optional
|
|
1765
2279
|
Whether to compress the binary output. Default is True.
|
|
1766
2280
|
level : int, optional
|
|
1767
|
-
Compression level (0
|
|
2281
|
+
Compression level (0-9). Default is 3.
|
|
1768
2282
|
|
|
1769
2283
|
Returns
|
|
1770
2284
|
-------
|
|
@@ -1776,6 +2290,7 @@ class Model:
|
|
|
1776
2290
|
IOError
|
|
1777
2291
|
If serialization fails.
|
|
1778
2292
|
"""
|
|
2293
|
+
...
|
|
1779
2294
|
|
|
1780
2295
|
@overload
|
|
1781
2296
|
def serialize(self, /) -> bytes: ...
|
|
@@ -1786,13 +2301,14 @@ class Model:
|
|
|
1786
2301
|
@overload
|
|
1787
2302
|
def serialize(self, /, compress: bool, level: int) -> bytes: ...
|
|
1788
2303
|
def serialize(
|
|
1789
|
-
self, /, compress: bool | None = ..., level: int | None = ...
|
|
2304
|
+
self, /, compress: (bool | None) = ..., level: (int | None) = ...
|
|
1790
2305
|
) -> bytes:
|
|
1791
2306
|
"""
|
|
1792
2307
|
Alias for `encode()`.
|
|
1793
2308
|
|
|
1794
2309
|
See `encode()` for full documentation.
|
|
1795
2310
|
"""
|
|
2311
|
+
...
|
|
1796
2312
|
|
|
1797
2313
|
@classmethod
|
|
1798
2314
|
def decode(cls, data: bytes) -> Model:
|
|
@@ -1814,6 +2330,7 @@ class Model:
|
|
|
1814
2330
|
DecodeError
|
|
1815
2331
|
If decoding fails due to corruption or incompatibility.
|
|
1816
2332
|
"""
|
|
2333
|
+
...
|
|
1817
2334
|
|
|
1818
2335
|
@classmethod
|
|
1819
2336
|
def deserialize(cls, data: bytes) -> Model:
|
|
@@ -1822,8 +2339,9 @@ class Model:
|
|
|
1822
2339
|
|
|
1823
2340
|
See `decode()` for full documentation.
|
|
1824
2341
|
"""
|
|
2342
|
+
...
|
|
1825
2343
|
|
|
1826
|
-
def __eq__(self, other: Model, /) -> bool:
|
|
2344
|
+
def __eq__(self, other: Model, /) -> bool:
|
|
1827
2345
|
"""
|
|
1828
2346
|
Check whether this model is equal to `other`.
|
|
1829
2347
|
|
|
@@ -1835,18 +2353,32 @@ class Model:
|
|
|
1835
2353
|
-------
|
|
1836
2354
|
bool
|
|
1837
2355
|
"""
|
|
2356
|
+
...
|
|
1838
2357
|
|
|
2358
|
+
def __str__(self, /) -> str: ...
|
|
2359
|
+
def __repr__(self, /) -> str: ...
|
|
1839
2360
|
def __hash__(self, /) -> int: ...
|
|
2361
|
+
metadata: ModelMetadata | None = ...
|
|
2362
|
+
|
|
2363
|
+
@staticmethod
|
|
2364
|
+
def load_luna(model_id: str, client: (ILunaSolve | str | None) = None) -> Model: ...
|
|
2365
|
+
def save_luna(self, client: (ILunaSolve | str | None) = None) -> None: ...
|
|
2366
|
+
def delete_luna(self, client: (ILunaSolve | str | None) = None) -> None: ...
|
|
2367
|
+
def load_solutions(
|
|
2368
|
+
self, client: (ILunaSolve | str | None) = None
|
|
2369
|
+
) -> list[Solution]: ...
|
|
2370
|
+
def load_solve_jobs(
|
|
2371
|
+
self, client: (ILunaSolve | str | None) = None
|
|
2372
|
+
) -> list[SolveJob]: ...
|
|
1840
2373
|
|
|
1841
|
-
# _expression.pyi
|
|
1842
2374
|
class Expression:
|
|
1843
2375
|
"""
|
|
1844
|
-
Polynomial expression supporting symbolic arithmetic, constraint creation
|
|
2376
|
+
Polynomial expression supporting symbolic arithmetic, constraint creation.
|
|
1845
2377
|
|
|
1846
|
-
An `Expression` represents a real-valued mathematical function composed of
|
|
1847
|
-
scalars, and coefficients. Expressions may include constant, linear,
|
|
1848
|
-
higher-order terms (cubic and beyond). They are used to build
|
|
1849
|
-
and constraints in symbolic optimization models.
|
|
2378
|
+
An `Expression` represents a real-valued mathematical function composed of
|
|
2379
|
+
variables, scalars, and coefficients. Expressions may include constant, linear,
|
|
2380
|
+
quadratic, and higher-order terms (cubic and beyond). They are used to build
|
|
2381
|
+
objective functions and constraints in symbolic optimization models.
|
|
1850
2382
|
|
|
1851
2383
|
Expressions support both regular and in-place arithmetic, including addition and
|
|
1852
2384
|
multiplication with integers, floats, `Variable` instances, and other `Expression`s.
|
|
@@ -1936,20 +2468,21 @@ class Expression:
|
|
|
1936
2468
|
def __init__(self, /) -> None: ...
|
|
1937
2469
|
@overload
|
|
1938
2470
|
def __init__(self, /, env: Environment) -> None: ...
|
|
1939
|
-
def __init__(self, /, env: Environment | None = ...) -> None:
|
|
2471
|
+
def __init__(self, /, env: (Environment | None) = ...) -> None:
|
|
1940
2472
|
"""
|
|
1941
|
-
|
|
2473
|
+
Create a new empty expression scoped to an environment.
|
|
1942
2474
|
|
|
1943
2475
|
Parameters
|
|
1944
2476
|
----------
|
|
1945
|
-
|
|
1946
|
-
|
|
2477
|
+
env : Environment
|
|
2478
|
+
The environment to which this expression is bound.
|
|
1947
2479
|
|
|
1948
2480
|
Raises
|
|
1949
2481
|
------
|
|
1950
|
-
|
|
1951
|
-
|
|
2482
|
+
NoActiveEnvironmentFoundError
|
|
2483
|
+
If no environment is provided and none is active in the context.
|
|
1952
2484
|
"""
|
|
2485
|
+
...
|
|
1953
2486
|
|
|
1954
2487
|
def get_offset(self, /) -> float:
|
|
1955
2488
|
"""
|
|
@@ -1960,6 +2493,7 @@ class Expression:
|
|
|
1960
2493
|
float
|
|
1961
2494
|
The constant term.
|
|
1962
2495
|
"""
|
|
2496
|
+
...
|
|
1963
2497
|
|
|
1964
2498
|
def get_linear(self, /, variable: Variable) -> float:
|
|
1965
2499
|
"""
|
|
@@ -1980,6 +2514,7 @@ class Expression:
|
|
|
1980
2514
|
VariableOutOfRangeError
|
|
1981
2515
|
If the variable index is not valid in this expression's environment.
|
|
1982
2516
|
"""
|
|
2517
|
+
...
|
|
1983
2518
|
|
|
1984
2519
|
def get_quadratic(self, /, u: Variable, v: Variable) -> float:
|
|
1985
2520
|
"""
|
|
@@ -2000,6 +2535,7 @@ class Expression:
|
|
|
2000
2535
|
VariableOutOfRangeError
|
|
2001
2536
|
If either variable is out of bounds for the expression's environment.
|
|
2002
2537
|
"""
|
|
2538
|
+
...
|
|
2003
2539
|
|
|
2004
2540
|
def get_higher_order(self, /, variables: tuple[Variable, ...]) -> float:
|
|
2005
2541
|
"""
|
|
@@ -2020,6 +2556,21 @@ class Expression:
|
|
|
2020
2556
|
VariableOutOfRangeError
|
|
2021
2557
|
If any variable is out of bounds for the environment.
|
|
2022
2558
|
"""
|
|
2559
|
+
...
|
|
2560
|
+
|
|
2561
|
+
def items(self, /) -> ExpressionIterator:
|
|
2562
|
+
"""
|
|
2563
|
+
Iterate over the single components of an expression.
|
|
2564
|
+
|
|
2565
|
+
An *component* refers to
|
|
2566
|
+
a single constant, linear, quadratic, or higher-order term of an expression.
|
|
2567
|
+
|
|
2568
|
+
Returns
|
|
2569
|
+
-------
|
|
2570
|
+
ExpressionIterator
|
|
2571
|
+
The iterator over the expression's components.
|
|
2572
|
+
"""
|
|
2573
|
+
...
|
|
2023
2574
|
|
|
2024
2575
|
@property
|
|
2025
2576
|
def num_variables(self, /) -> int:
|
|
@@ -2031,6 +2582,7 @@ class Expression:
|
|
|
2031
2582
|
int
|
|
2032
2583
|
Number of variables with non-zero coefficients.
|
|
2033
2584
|
"""
|
|
2585
|
+
...
|
|
2034
2586
|
|
|
2035
2587
|
def is_equal(self, /, other: Expression) -> bool:
|
|
2036
2588
|
"""
|
|
@@ -2046,6 +2598,37 @@ class Expression:
|
|
|
2046
2598
|
bool
|
|
2047
2599
|
If the two expressions are equal.
|
|
2048
2600
|
"""
|
|
2601
|
+
...
|
|
2602
|
+
|
|
2603
|
+
def substitute(
|
|
2604
|
+
self, /, target: Variable, replacement: (Expression | Variable)
|
|
2605
|
+
) -> Expression:
|
|
2606
|
+
"""
|
|
2607
|
+
Substitute every occurrence of a variable with another expression.
|
|
2608
|
+
|
|
2609
|
+
Given an expression `self`, this method replaces all occurrences of `target`
|
|
2610
|
+
with `replacement`. If the substitution would cross differing environments
|
|
2611
|
+
(e.g. captures from two different scopes), it returns a `DifferentEnvsErr`.
|
|
2612
|
+
|
|
2613
|
+
Parameters
|
|
2614
|
+
----------
|
|
2615
|
+
target : VarRef
|
|
2616
|
+
The variable reference to replace.
|
|
2617
|
+
replacement : Expression
|
|
2618
|
+
The expression to insert in place of `target`.
|
|
2619
|
+
|
|
2620
|
+
Returns
|
|
2621
|
+
-------
|
|
2622
|
+
Expression
|
|
2623
|
+
The resulting expression after substitution.
|
|
2624
|
+
|
|
2625
|
+
Raises
|
|
2626
|
+
------
|
|
2627
|
+
DifferentEnvsErr
|
|
2628
|
+
If the environments of `self`, `target` and `replacement`
|
|
2629
|
+
are not compatible.
|
|
2630
|
+
"""
|
|
2631
|
+
...
|
|
2049
2632
|
|
|
2050
2633
|
@overload
|
|
2051
2634
|
def encode(self, /) -> bytes: ...
|
|
@@ -2055,7 +2638,9 @@ class Expression:
|
|
|
2055
2638
|
def encode(self, /, *, level: int) -> bytes: ...
|
|
2056
2639
|
@overload
|
|
2057
2640
|
def encode(self, /, compress: bool, level: int) -> bytes: ...
|
|
2058
|
-
def encode(
|
|
2641
|
+
def encode(
|
|
2642
|
+
self, /, compress: (bool | None) = True, level: (int | None) = 3
|
|
2643
|
+
) -> bytes:
|
|
2059
2644
|
"""
|
|
2060
2645
|
Serialize the expression into a compact binary format.
|
|
2061
2646
|
|
|
@@ -2064,7 +2649,7 @@ class Expression:
|
|
|
2064
2649
|
compress : bool, optional
|
|
2065
2650
|
Whether to compress the data. Default is True.
|
|
2066
2651
|
level : int, optional
|
|
2067
|
-
Compression level (0
|
|
2652
|
+
Compression level (0-9). Default is 3.
|
|
2068
2653
|
|
|
2069
2654
|
Returns
|
|
2070
2655
|
-------
|
|
@@ -2076,6 +2661,7 @@ class Expression:
|
|
|
2076
2661
|
IOError
|
|
2077
2662
|
If serialization fails.
|
|
2078
2663
|
"""
|
|
2664
|
+
...
|
|
2079
2665
|
|
|
2080
2666
|
@overload
|
|
2081
2667
|
def serialize(self, /) -> bytes: ...
|
|
@@ -2086,13 +2672,14 @@ class Expression:
|
|
|
2086
2672
|
@overload
|
|
2087
2673
|
def serialize(self, /, compress: bool, level: int) -> bytes: ...
|
|
2088
2674
|
def serialize(
|
|
2089
|
-
self, /, compress: bool | None = ..., level: int | None = ...
|
|
2675
|
+
self, /, compress: (bool | None) = ..., level: (int | None) = ...
|
|
2090
2676
|
) -> bytes:
|
|
2091
2677
|
"""
|
|
2092
2678
|
Alias for `encode()`.
|
|
2093
2679
|
|
|
2094
2680
|
See `encode()` for full documentation.
|
|
2095
2681
|
"""
|
|
2682
|
+
...
|
|
2096
2683
|
|
|
2097
2684
|
@classmethod
|
|
2098
2685
|
def decode(cls, data: bytes) -> Expression:
|
|
@@ -2114,6 +2701,7 @@ class Expression:
|
|
|
2114
2701
|
DecodeError
|
|
2115
2702
|
If decoding fails due to corruption or incompatibility.
|
|
2116
2703
|
"""
|
|
2704
|
+
...
|
|
2117
2705
|
|
|
2118
2706
|
@classmethod
|
|
2119
2707
|
def deserialize(cls, data: bytes) -> Expression:
|
|
@@ -2122,6 +2710,7 @@ class Expression:
|
|
|
2122
2710
|
|
|
2123
2711
|
See `decode()` for full documentation.
|
|
2124
2712
|
"""
|
|
2713
|
+
...
|
|
2125
2714
|
|
|
2126
2715
|
@overload
|
|
2127
2716
|
def __add__(self, other: Expression, /) -> Expression: ...
|
|
@@ -2131,7 +2720,7 @@ class Expression:
|
|
|
2131
2720
|
def __add__(self, other: int, /) -> Expression: ...
|
|
2132
2721
|
@overload
|
|
2133
2722
|
def __add__(self, other: float, /) -> Expression: ...
|
|
2134
|
-
def __add__(self, other: Expression | Variable | float, /) -> Expression:
|
|
2723
|
+
def __add__(self, other: (Expression | Variable | int | float), /) -> Expression:
|
|
2135
2724
|
"""
|
|
2136
2725
|
Add another expression, variable, or scalar.
|
|
2137
2726
|
|
|
@@ -2150,6 +2739,7 @@ class Expression:
|
|
|
2150
2739
|
TypeError
|
|
2151
2740
|
If the operand type is unsupported.
|
|
2152
2741
|
"""
|
|
2742
|
+
...
|
|
2153
2743
|
|
|
2154
2744
|
@overload
|
|
2155
2745
|
def __radd__(self, other: Expression, /) -> Expression: ...
|
|
@@ -2159,7 +2749,7 @@ class Expression:
|
|
|
2159
2749
|
def __radd__(self, other: int, /) -> Expression: ...
|
|
2160
2750
|
@overload
|
|
2161
2751
|
def __radd__(self, other: float, /) -> Expression: ...
|
|
2162
|
-
def __radd__(self, other: Expression | Variable | float, /) -> Expression:
|
|
2752
|
+
def __radd__(self, other: (Expression | Variable | int | float), /) -> Expression:
|
|
2163
2753
|
"""
|
|
2164
2754
|
Add this expression to a scalar or variable.
|
|
2165
2755
|
|
|
@@ -2176,16 +2766,17 @@ class Expression:
|
|
|
2176
2766
|
TypeError
|
|
2177
2767
|
If the operand type is unsupported.
|
|
2178
2768
|
"""
|
|
2769
|
+
...
|
|
2179
2770
|
|
|
2180
2771
|
@overload
|
|
2181
|
-
def __iadd__(self, other: Expression, /): ...
|
|
2772
|
+
def __iadd__(self, other: Expression, /) -> Self: ...
|
|
2182
2773
|
@overload
|
|
2183
|
-
def __iadd__(self, other: Variable, /): ...
|
|
2774
|
+
def __iadd__(self, other: Variable, /) -> Self: ...
|
|
2184
2775
|
@overload
|
|
2185
|
-
def __iadd__(self, other: int, /): ...
|
|
2776
|
+
def __iadd__(self, other: int, /) -> Self: ...
|
|
2186
2777
|
@overload
|
|
2187
|
-
def __iadd__(self, other: float, /): ...
|
|
2188
|
-
def __iadd__(self, other: Expression | Variable | float, /) ->
|
|
2778
|
+
def __iadd__(self, other: float, /) -> Self: ...
|
|
2779
|
+
def __iadd__(self, other: (Expression | Variable | int | float), /) -> Self:
|
|
2189
2780
|
"""
|
|
2190
2781
|
In-place addition.
|
|
2191
2782
|
|
|
@@ -2195,7 +2786,7 @@ class Expression:
|
|
|
2195
2786
|
|
|
2196
2787
|
Returns
|
|
2197
2788
|
-------
|
|
2198
|
-
|
|
2789
|
+
Self
|
|
2199
2790
|
|
|
2200
2791
|
Raises
|
|
2201
2792
|
------
|
|
@@ -2204,16 +2795,17 @@ class Expression:
|
|
|
2204
2795
|
TypeError
|
|
2205
2796
|
If the operand type is unsupported.
|
|
2206
2797
|
"""
|
|
2798
|
+
...
|
|
2207
2799
|
|
|
2208
2800
|
@overload
|
|
2209
|
-
def __isub__(self, other: Expression, /): ...
|
|
2801
|
+
def __isub__(self, other: Expression, /) -> Self: ...
|
|
2210
2802
|
@overload
|
|
2211
|
-
def __isub__(self, other: Variable, /): ...
|
|
2803
|
+
def __isub__(self, other: Variable, /) -> Self: ...
|
|
2212
2804
|
@overload
|
|
2213
|
-
def __isub__(self, other: int, /): ...
|
|
2805
|
+
def __isub__(self, other: int, /) -> Self: ...
|
|
2214
2806
|
@overload
|
|
2215
|
-
def __isub__(self, other: float, /): ...
|
|
2216
|
-
def __isub__(self, other: Expression | Variable | float, /):
|
|
2807
|
+
def __isub__(self, other: float, /) -> Self: ...
|
|
2808
|
+
def __isub__(self, other: (Expression | Variable | int | float), /) -> Self:
|
|
2217
2809
|
"""
|
|
2218
2810
|
In-place subtraction.
|
|
2219
2811
|
|
|
@@ -2223,7 +2815,7 @@ class Expression:
|
|
|
2223
2815
|
|
|
2224
2816
|
Returns
|
|
2225
2817
|
-------
|
|
2226
|
-
|
|
2818
|
+
Self
|
|
2227
2819
|
|
|
2228
2820
|
Raises
|
|
2229
2821
|
------
|
|
@@ -2232,6 +2824,7 @@ class Expression:
|
|
|
2232
2824
|
TypeError
|
|
2233
2825
|
If the operand type is unsupported.
|
|
2234
2826
|
"""
|
|
2827
|
+
...
|
|
2235
2828
|
|
|
2236
2829
|
@overload
|
|
2237
2830
|
def __sub__(self, other: Expression, /) -> Expression: ...
|
|
@@ -2241,7 +2834,7 @@ class Expression:
|
|
|
2241
2834
|
def __sub__(self, other: int, /) -> Expression: ...
|
|
2242
2835
|
@overload
|
|
2243
2836
|
def __sub__(self, other: float, /) -> Expression: ...
|
|
2244
|
-
def __sub__(self, other: Expression | Variable | float, /) -> Expression:
|
|
2837
|
+
def __sub__(self, other: (Expression | Variable | int | float), /) -> Expression:
|
|
2245
2838
|
"""
|
|
2246
2839
|
Subtract another expression, variable, or scalar.
|
|
2247
2840
|
|
|
@@ -2260,6 +2853,7 @@ class Expression:
|
|
|
2260
2853
|
TypeError
|
|
2261
2854
|
If the operand type is unsupported.
|
|
2262
2855
|
"""
|
|
2856
|
+
...
|
|
2263
2857
|
|
|
2264
2858
|
@overload
|
|
2265
2859
|
def __mul__(self, other: Expression, /) -> Expression: ...
|
|
@@ -2269,7 +2863,7 @@ class Expression:
|
|
|
2269
2863
|
def __mul__(self, other: int, /) -> Expression: ...
|
|
2270
2864
|
@overload
|
|
2271
2865
|
def __mul__(self, other: float, /) -> Expression: ...
|
|
2272
|
-
def __mul__(self, other: Expression | Variable | float, /) -> Expression:
|
|
2866
|
+
def __mul__(self, other: (Expression | Variable | int | float), /) -> Expression:
|
|
2273
2867
|
"""
|
|
2274
2868
|
Multiply this expression by another value.
|
|
2275
2869
|
|
|
@@ -2288,12 +2882,13 @@ class Expression:
|
|
|
2288
2882
|
TypeError
|
|
2289
2883
|
If the operand type is unsupported.
|
|
2290
2884
|
"""
|
|
2885
|
+
...
|
|
2291
2886
|
|
|
2292
2887
|
@overload
|
|
2293
2888
|
def __rmul__(self, other: int, /) -> Expression: ...
|
|
2294
2889
|
@overload
|
|
2295
2890
|
def __rmul__(self, other: float, /) -> Expression: ...
|
|
2296
|
-
def __rmul__(self, other: float, /) -> Expression:
|
|
2891
|
+
def __rmul__(self, other: (int | float), /) -> Expression:
|
|
2297
2892
|
"""
|
|
2298
2893
|
Right-hand multiplication.
|
|
2299
2894
|
|
|
@@ -2310,16 +2905,17 @@ class Expression:
|
|
|
2310
2905
|
TypeError
|
|
2311
2906
|
If the operand type is unsupported.
|
|
2312
2907
|
"""
|
|
2908
|
+
...
|
|
2313
2909
|
|
|
2314
2910
|
@overload
|
|
2315
|
-
def __imul__(self, other: Expression, /): ...
|
|
2911
|
+
def __imul__(self, other: Expression, /) -> Self: ...
|
|
2316
2912
|
@overload
|
|
2317
|
-
def __imul__(self, other: Variable, /): ...
|
|
2913
|
+
def __imul__(self, other: Variable, /) -> Self: ...
|
|
2318
2914
|
@overload
|
|
2319
|
-
def __imul__(self, other: int, /): ...
|
|
2915
|
+
def __imul__(self, other: int, /) -> Self: ...
|
|
2320
2916
|
@overload
|
|
2321
|
-
def __imul__(self, other: float, /): ...
|
|
2322
|
-
def __imul__(self, other: Expression | Variable | float, /):
|
|
2917
|
+
def __imul__(self, other: float, /) -> Self: ...
|
|
2918
|
+
def __imul__(self, other: (Expression | Variable | int | float), /) -> Self:
|
|
2323
2919
|
"""
|
|
2324
2920
|
In-place multiplication.
|
|
2325
2921
|
|
|
@@ -2329,7 +2925,7 @@ class Expression:
|
|
|
2329
2925
|
|
|
2330
2926
|
Returns
|
|
2331
2927
|
-------
|
|
2332
|
-
|
|
2928
|
+
Self
|
|
2333
2929
|
|
|
2334
2930
|
Raises
|
|
2335
2931
|
------
|
|
@@ -2338,6 +2934,7 @@ class Expression:
|
|
|
2338
2934
|
TypeError
|
|
2339
2935
|
If the operand type is unsupported.
|
|
2340
2936
|
"""
|
|
2937
|
+
...
|
|
2341
2938
|
|
|
2342
2939
|
def __pow__(self, other: int, /) -> Expression:
|
|
2343
2940
|
"""
|
|
@@ -2356,18 +2953,19 @@ class Expression:
|
|
|
2356
2953
|
RuntimeError
|
|
2357
2954
|
If the param `modulo` usually supported for `__pow__` is specified.
|
|
2358
2955
|
"""
|
|
2956
|
+
...
|
|
2359
2957
|
|
|
2360
2958
|
@overload
|
|
2361
2959
|
def __eq__(self, rhs: Expression, /) -> Constraint: ...
|
|
2362
2960
|
@overload
|
|
2363
2961
|
def __eq__(self, rhs: Variable, /) -> Constraint: ...
|
|
2364
2962
|
@overload
|
|
2365
|
-
def __eq__(self, rhs: int, /) -> Constraint: ...
|
|
2963
|
+
def __eq__(self, rhs: int, /) -> Constraint: ...
|
|
2366
2964
|
@overload
|
|
2367
|
-
def __eq__(self, rhs: float, /) -> Constraint: ...
|
|
2368
|
-
def __eq__(self, rhs: Expression | Variable | float, /) -> Constraint:
|
|
2965
|
+
def __eq__(self, rhs: float, /) -> Constraint: ...
|
|
2966
|
+
def __eq__(self, rhs: (Expression | Variable | int | float), /) -> Constraint:
|
|
2369
2967
|
"""
|
|
2370
|
-
Compare to a different expression or create a constraint `expression == scalar
|
|
2968
|
+
Compare to a different expression or create a constraint `expression == scalar`.
|
|
2371
2969
|
|
|
2372
2970
|
If `rhs` is of type `Variable` or `Expression` it is moved to the `lhs` in the
|
|
2373
2971
|
constraint, resulting in the following constraint:
|
|
@@ -2387,6 +2985,7 @@ class Expression:
|
|
|
2387
2985
|
TypeError
|
|
2388
2986
|
If the right-hand side is not an Expression or scalar.
|
|
2389
2987
|
"""
|
|
2988
|
+
...
|
|
2390
2989
|
|
|
2391
2990
|
@overload
|
|
2392
2991
|
def __le__(self, rhs: Expression, /) -> Constraint: ...
|
|
@@ -2396,7 +2995,7 @@ class Expression:
|
|
|
2396
2995
|
def __le__(self, rhs: int, /) -> Constraint: ...
|
|
2397
2996
|
@overload
|
|
2398
2997
|
def __le__(self, rhs: float, /) -> Constraint: ...
|
|
2399
|
-
def __le__(self, rhs: Expression | Variable | float, /) -> Constraint:
|
|
2998
|
+
def __le__(self, rhs: (Expression | Variable | int | float), /) -> Constraint:
|
|
2400
2999
|
"""
|
|
2401
3000
|
Create a constraint `expression <= scalar`.
|
|
2402
3001
|
|
|
@@ -2418,6 +3017,7 @@ class Expression:
|
|
|
2418
3017
|
TypeError
|
|
2419
3018
|
If the right-hand side is not of type float, int, Variable or Expression.
|
|
2420
3019
|
"""
|
|
3020
|
+
...
|
|
2421
3021
|
|
|
2422
3022
|
@overload
|
|
2423
3023
|
def __ge__(self, rhs: Expression, /) -> Constraint: ...
|
|
@@ -2427,7 +3027,7 @@ class Expression:
|
|
|
2427
3027
|
def __ge__(self, rhs: int, /) -> Constraint: ...
|
|
2428
3028
|
@overload
|
|
2429
3029
|
def __ge__(self, rhs: float, /) -> Constraint: ...
|
|
2430
|
-
def __ge__(self, rhs: Expression | Variable | float, /) -> Constraint:
|
|
3030
|
+
def __ge__(self, rhs: (Expression | Variable | int | float), /) -> Constraint:
|
|
2431
3031
|
"""
|
|
2432
3032
|
Create a constraint: expression >= scalar.
|
|
2433
3033
|
|
|
@@ -2449,6 +3049,7 @@ class Expression:
|
|
|
2449
3049
|
TypeError
|
|
2450
3050
|
If the right-hand side is not of type float, int, Variable or Expression.
|
|
2451
3051
|
"""
|
|
3052
|
+
...
|
|
2452
3053
|
|
|
2453
3054
|
def __neg__(self, /) -> Expression:
|
|
2454
3055
|
"""
|
|
@@ -2458,14 +3059,43 @@ class Expression:
|
|
|
2458
3059
|
-------
|
|
2459
3060
|
Expression
|
|
2460
3061
|
"""
|
|
3062
|
+
...
|
|
3063
|
+
|
|
3064
|
+
@property
|
|
3065
|
+
def _environment(self, /) -> Environment:
|
|
3066
|
+
"""Get this expression's environment."""
|
|
3067
|
+
...
|
|
3068
|
+
|
|
3069
|
+
def __str__(self, /) -> str: ...
|
|
3070
|
+
def __repr__(self, /) -> str: ...
|
|
3071
|
+
|
|
3072
|
+
class ExpressionIterator:
|
|
3073
|
+
"""
|
|
3074
|
+
Iterate over the single components of an expression.
|
|
3075
|
+
|
|
3076
|
+
Examples
|
|
3077
|
+
--------
|
|
3078
|
+
>>> from luna_quantum import Constant, Expression, HigherOrder, Linear, Quadratic
|
|
3079
|
+
>>> expr: Expression = ...
|
|
3080
|
+
>>> vars: Constant | Linear | Quadratic | HigherOrder
|
|
3081
|
+
>>> bias: float
|
|
3082
|
+
>>> for vars, bias in expr.items():
|
|
3083
|
+
>>> match vars:
|
|
3084
|
+
>>> case Constant(): do_something_with_constant(bias)
|
|
3085
|
+
>>> case Linear(x): do_something_with_linear_var(x, bias)
|
|
3086
|
+
>>> case Quadratic(x, y): do_something_with_quadratic_vars(x, y, bias)
|
|
3087
|
+
>>> case HigherOrder(ho): do_something_with_higher_order_vars(ho, bias)
|
|
3088
|
+
"""
|
|
3089
|
+
|
|
3090
|
+
def __next__(self) -> tuple[Constant | Linear | Quadratic | HigherOrder, float]: ...
|
|
3091
|
+
def __iter__(self) -> ExpressionIterator: ...
|
|
2461
3092
|
|
|
2462
|
-
# _environment.pyi
|
|
2463
3093
|
class Environment:
|
|
2464
3094
|
"""
|
|
2465
3095
|
Execution context for variable creation and expression scoping.
|
|
2466
3096
|
|
|
2467
|
-
An `Environment` provides the symbolic scope in which `Variable`
|
|
2468
|
-
It is required for
|
|
3097
|
+
An `Environment` provides the symbolic scope in which `Variable`s are defined.
|
|
3098
|
+
It is required for constructing variables ensuring consistency across expressions.
|
|
2469
3099
|
The environment does **not** store constraints or expressions — it only facilitates
|
|
2470
3100
|
their creation by acting as a context manager and anchor for `Variable` instances.
|
|
2471
3101
|
|
|
@@ -2489,7 +3119,8 @@ class Environment:
|
|
|
2489
3119
|
Notes
|
|
2490
3120
|
-----
|
|
2491
3121
|
- The environment is required to create `Variable` instances.
|
|
2492
|
-
- It does **not** own constraints or expressions — they merely reference variables
|
|
3122
|
+
- It does **not** own constraints or expressions — they merely reference variables
|
|
3123
|
+
tied to an environment.
|
|
2493
3124
|
- Environments **cannot be nested**. Only one can be active at a time.
|
|
2494
3125
|
- Use `encode()` / `decode()` to persist and recover expression trees.
|
|
2495
3126
|
"""
|
|
@@ -2500,8 +3131,9 @@ class Environment:
|
|
|
2500
3131
|
|
|
2501
3132
|
It is recommended to use this in a `with` statement to ensure proper scoping.
|
|
2502
3133
|
"""
|
|
3134
|
+
...
|
|
2503
3135
|
|
|
2504
|
-
def __enter__(self, /) ->
|
|
3136
|
+
def __enter__(self, /) -> Self:
|
|
2505
3137
|
"""
|
|
2506
3138
|
Activate this environment for variable creation.
|
|
2507
3139
|
|
|
@@ -2515,13 +3147,21 @@ class Environment:
|
|
|
2515
3147
|
MultipleActiveEnvironmentsError
|
|
2516
3148
|
If another environment is already active.
|
|
2517
3149
|
"""
|
|
3150
|
+
...
|
|
2518
3151
|
|
|
2519
|
-
def __exit__(
|
|
3152
|
+
def __exit__(
|
|
3153
|
+
self,
|
|
3154
|
+
/,
|
|
3155
|
+
exc_type: (type[BaseException] | None) = ...,
|
|
3156
|
+
exc_value: (BaseException | None) = ...,
|
|
3157
|
+
exc_traceback: (TracebackType | None) = ...,
|
|
3158
|
+
) -> None:
|
|
2520
3159
|
"""
|
|
2521
3160
|
Deactivate this environment.
|
|
2522
3161
|
|
|
2523
3162
|
Called automatically at the end of a `with` block.
|
|
2524
3163
|
"""
|
|
3164
|
+
...
|
|
2525
3165
|
|
|
2526
3166
|
def get_variable(self, /, name: str) -> Variable:
|
|
2527
3167
|
"""
|
|
@@ -2542,6 +3182,7 @@ class Environment:
|
|
|
2542
3182
|
VariableNotExistingError
|
|
2543
3183
|
If no variable with the specified name is registered.
|
|
2544
3184
|
"""
|
|
3185
|
+
...
|
|
2545
3186
|
|
|
2546
3187
|
@overload
|
|
2547
3188
|
def encode(self, /) -> bytes: ...
|
|
@@ -2551,7 +3192,9 @@ class Environment:
|
|
|
2551
3192
|
def encode(self, /, *, level: int) -> bytes: ...
|
|
2552
3193
|
@overload
|
|
2553
3194
|
def encode(self, /, compress: bool, level: int) -> bytes: ...
|
|
2554
|
-
def encode(
|
|
3195
|
+
def encode(
|
|
3196
|
+
self, /, compress: (bool | None) = True, level: (int | None) = 3
|
|
3197
|
+
) -> bytes:
|
|
2555
3198
|
"""
|
|
2556
3199
|
Serialize the environment into a compact binary format.
|
|
2557
3200
|
|
|
@@ -2574,6 +3217,7 @@ class Environment:
|
|
|
2574
3217
|
IOError
|
|
2575
3218
|
If serialization fails.
|
|
2576
3219
|
"""
|
|
3220
|
+
...
|
|
2577
3221
|
|
|
2578
3222
|
@overload
|
|
2579
3223
|
def serialize(self, /) -> bytes: ...
|
|
@@ -2584,13 +3228,14 @@ class Environment:
|
|
|
2584
3228
|
@overload
|
|
2585
3229
|
def serialize(self, /, compress: bool, level: int) -> bytes: ...
|
|
2586
3230
|
def serialize(
|
|
2587
|
-
self, /, compress: bool | None = ..., level: int | None = ...
|
|
3231
|
+
self, /, compress: (bool | None) = ..., level: (int | None) = ...
|
|
2588
3232
|
) -> bytes:
|
|
2589
3233
|
"""
|
|
2590
3234
|
Alias for `encode()`.
|
|
2591
3235
|
|
|
2592
3236
|
See `encode()` for full usage details.
|
|
2593
3237
|
"""
|
|
3238
|
+
...
|
|
2594
3239
|
|
|
2595
3240
|
@classmethod
|
|
2596
3241
|
def decode(cls, data: bytes) -> Environment:
|
|
@@ -2612,6 +3257,7 @@ class Environment:
|
|
|
2612
3257
|
DecodeError
|
|
2613
3258
|
If decoding fails due to corruption or incompatibility.
|
|
2614
3259
|
"""
|
|
3260
|
+
...
|
|
2615
3261
|
|
|
2616
3262
|
@classmethod
|
|
2617
3263
|
def deserialize(cls, data: bytes) -> Environment:
|
|
@@ -2620,10 +3266,12 @@ class Environment:
|
|
|
2620
3266
|
|
|
2621
3267
|
See `decode()` for full usage details.
|
|
2622
3268
|
"""
|
|
3269
|
+
...
|
|
2623
3270
|
|
|
2624
|
-
def __eq__(self, other: Environment, /) -> bool: ...
|
|
3271
|
+
def __eq__(self, other: Environment, /) -> bool: ...
|
|
3272
|
+
def __str__(self, /) -> str: ...
|
|
3273
|
+
def __repr__(self, /) -> str: ...
|
|
2625
3274
|
|
|
2626
|
-
# _constraints.pyi
|
|
2627
3275
|
class Comparator(Enum):
|
|
2628
3276
|
"""
|
|
2629
3277
|
Comparison operators used to define constraints.
|
|
@@ -2649,13 +3297,14 @@ class Comparator(Enum):
|
|
|
2649
3297
|
|
|
2650
3298
|
Eq = ...
|
|
2651
3299
|
"""Equality (==)"""
|
|
2652
|
-
|
|
2653
3300
|
Le = ...
|
|
2654
3301
|
"""Less-than or equal (<=)"""
|
|
2655
|
-
|
|
2656
3302
|
Ge = ...
|
|
2657
3303
|
"""Greater-than or equal (>=)"""
|
|
2658
3304
|
|
|
3305
|
+
def __str__(self, /) -> str: ...
|
|
3306
|
+
def __repr__(self, /) -> str: ...
|
|
3307
|
+
|
|
2659
3308
|
class Constraint:
|
|
2660
3309
|
"""
|
|
2661
3310
|
A symbolic constraint formed by comparing an expression to a constant.
|
|
@@ -2754,8 +3403,8 @@ class Constraint:
|
|
|
2754
3403
|
def __init__(
|
|
2755
3404
|
self,
|
|
2756
3405
|
/,
|
|
2757
|
-
lhs: Variable | Expression,
|
|
2758
|
-
rhs: float | Expression | Variable,
|
|
3406
|
+
lhs: (Variable | Expression),
|
|
3407
|
+
rhs: (int | float | Expression | Variable),
|
|
2759
3408
|
comparator: Comparator,
|
|
2760
3409
|
name: str,
|
|
2761
3410
|
) -> None:
|
|
@@ -2780,6 +3429,7 @@ class Constraint:
|
|
|
2780
3429
|
IllegalConstraintNameError
|
|
2781
3430
|
If the constraint is tried to be created with an illegal name.
|
|
2782
3431
|
"""
|
|
3432
|
+
...
|
|
2783
3433
|
|
|
2784
3434
|
@property
|
|
2785
3435
|
def name(self, /) -> str | None:
|
|
@@ -2791,41 +3441,47 @@ class Constraint:
|
|
|
2791
3441
|
str, optional
|
|
2792
3442
|
Returns the name of the constraint as a string or None if it is unnamed.
|
|
2793
3443
|
"""
|
|
3444
|
+
...
|
|
2794
3445
|
|
|
2795
3446
|
@property
|
|
2796
3447
|
def lhs(self, /) -> Expression:
|
|
2797
3448
|
"""
|
|
2798
|
-
Get the left-hand side of the constraint
|
|
3449
|
+
Get the left-hand side of the constraint.
|
|
2799
3450
|
|
|
2800
3451
|
Returns
|
|
2801
3452
|
-------
|
|
2802
3453
|
Expression
|
|
2803
3454
|
The left-hand side expression.
|
|
2804
3455
|
"""
|
|
3456
|
+
...
|
|
2805
3457
|
|
|
2806
3458
|
@property
|
|
2807
3459
|
def rhs(self, /) -> float:
|
|
2808
3460
|
"""
|
|
2809
|
-
Get the right-hand side of the constraint
|
|
3461
|
+
Get the right-hand side of the constraint.
|
|
2810
3462
|
|
|
2811
3463
|
Returns
|
|
2812
3464
|
-------
|
|
2813
3465
|
float
|
|
2814
3466
|
The right-hand side expression.
|
|
2815
3467
|
"""
|
|
3468
|
+
...
|
|
2816
3469
|
|
|
2817
3470
|
@property
|
|
2818
3471
|
def comparator(self, /) -> Comparator:
|
|
2819
3472
|
"""
|
|
2820
|
-
Get the comparator of the constraint
|
|
3473
|
+
Get the comparator of the constraint.
|
|
2821
3474
|
|
|
2822
3475
|
Returns
|
|
2823
3476
|
-------
|
|
2824
3477
|
Comparator
|
|
2825
3478
|
The comparator of the constraint.
|
|
2826
3479
|
"""
|
|
3480
|
+
...
|
|
2827
3481
|
|
|
2828
|
-
def __eq__(self, other: Constraint, /) -> bool: ...
|
|
3482
|
+
def __eq__(self, other: Constraint, /) -> bool: ...
|
|
3483
|
+
def __str__(self, /) -> str: ...
|
|
3484
|
+
def __repr__(self, /) -> str: ...
|
|
2829
3485
|
|
|
2830
3486
|
class Constraints:
|
|
2831
3487
|
"""
|
|
@@ -2845,8 +3501,6 @@ class Constraints:
|
|
|
2845
3501
|
... c = Constraint(x + 1, 0.0, Comparator.Le)
|
|
2846
3502
|
|
|
2847
3503
|
>>> cs = Constraints()
|
|
2848
|
-
>>> cs.add_constraint(c)
|
|
2849
|
-
|
|
2850
3504
|
>>> cs += x >= 1.0
|
|
2851
3505
|
|
|
2852
3506
|
Serialization:
|
|
@@ -2862,21 +3516,12 @@ class Constraints:
|
|
|
2862
3516
|
|
|
2863
3517
|
def __init__(self, /) -> None: ...
|
|
2864
3518
|
@overload
|
|
2865
|
-
def add_constraint(self, /, constraint: Constraint):
|
|
2866
|
-
"""
|
|
2867
|
-
Add a constraint to the collection.
|
|
2868
|
-
|
|
2869
|
-
Parameters
|
|
2870
|
-
----------
|
|
2871
|
-
constraint : Constraint
|
|
2872
|
-
The constraint to be added.
|
|
2873
|
-
name : str, optional
|
|
2874
|
-
The name of the constraint to be added.
|
|
2875
|
-
"""
|
|
2876
|
-
|
|
3519
|
+
def add_constraint(self, /, constraint: Constraint) -> None: ...
|
|
2877
3520
|
@overload
|
|
2878
|
-
def add_constraint(self, /, constraint: Constraint, name: str): ...
|
|
2879
|
-
def add_constraint(
|
|
3521
|
+
def add_constraint(self, /, constraint: Constraint, name: str) -> None: ...
|
|
3522
|
+
def add_constraint(
|
|
3523
|
+
self, /, constraint: Constraint, name: (str | None) = ...
|
|
3524
|
+
) -> None:
|
|
2880
3525
|
"""
|
|
2881
3526
|
Add a constraint to the collection.
|
|
2882
3527
|
|
|
@@ -2887,6 +3532,7 @@ class Constraints:
|
|
|
2887
3532
|
name : str, optional
|
|
2888
3533
|
The name of the constraint to be added.
|
|
2889
3534
|
"""
|
|
3535
|
+
...
|
|
2890
3536
|
|
|
2891
3537
|
@overload
|
|
2892
3538
|
def encode(self, /) -> bytes: ...
|
|
@@ -2896,7 +3542,9 @@ class Constraints:
|
|
|
2896
3542
|
def encode(self, /, *, level: int) -> bytes: ...
|
|
2897
3543
|
@overload
|
|
2898
3544
|
def encode(self, /, compress: bool, level: int) -> bytes: ...
|
|
2899
|
-
def encode(
|
|
3545
|
+
def encode(
|
|
3546
|
+
self, /, compress: (bool | None) = True, level: (int | None) = 3
|
|
3547
|
+
) -> bytes:
|
|
2900
3548
|
"""
|
|
2901
3549
|
Serialize the constraint collection to a binary blob.
|
|
2902
3550
|
|
|
@@ -2905,7 +3553,7 @@ class Constraints:
|
|
|
2905
3553
|
compress : bool, optional
|
|
2906
3554
|
Whether to compress the result. Default is True.
|
|
2907
3555
|
level : int, optional
|
|
2908
|
-
Compression level (0
|
|
3556
|
+
Compression level (0-9). Default is 3.
|
|
2909
3557
|
|
|
2910
3558
|
Returns
|
|
2911
3559
|
-------
|
|
@@ -2917,6 +3565,7 @@ class Constraints:
|
|
|
2917
3565
|
IOError
|
|
2918
3566
|
If serialization fails.
|
|
2919
3567
|
"""
|
|
3568
|
+
...
|
|
2920
3569
|
|
|
2921
3570
|
@overload
|
|
2922
3571
|
def serialize(self, /) -> bytes: ...
|
|
@@ -2927,13 +3576,14 @@ class Constraints:
|
|
|
2927
3576
|
@overload
|
|
2928
3577
|
def serialize(self, /, compress: bool, level: int) -> bytes: ...
|
|
2929
3578
|
def serialize(
|
|
2930
|
-
self, /, compress: bool | None = ..., level: int | None = ...
|
|
3579
|
+
self, /, compress: (bool | None) = ..., level: (int | None) = ...
|
|
2931
3580
|
) -> bytes:
|
|
2932
3581
|
"""
|
|
2933
3582
|
Alias for `encode()`.
|
|
2934
3583
|
|
|
2935
3584
|
See `encode()` for details.
|
|
2936
3585
|
"""
|
|
3586
|
+
...
|
|
2937
3587
|
|
|
2938
3588
|
@classmethod
|
|
2939
3589
|
def decode(cls, data: bytes, env: Environment) -> Expression:
|
|
@@ -2955,6 +3605,7 @@ class Constraints:
|
|
|
2955
3605
|
DecodeError
|
|
2956
3606
|
If decoding fails due to corruption or incompatibility.
|
|
2957
3607
|
"""
|
|
3608
|
+
...
|
|
2958
3609
|
|
|
2959
3610
|
@classmethod
|
|
2960
3611
|
def deserialize(cls, data: bytes, env: Environment) -> Expression:
|
|
@@ -2963,12 +3614,13 @@ class Constraints:
|
|
|
2963
3614
|
|
|
2964
3615
|
See `decode()` for usage.
|
|
2965
3616
|
"""
|
|
3617
|
+
...
|
|
2966
3618
|
|
|
2967
3619
|
@overload
|
|
2968
|
-
def __iadd__(self, constraint: Constraint, /): ...
|
|
3620
|
+
def __iadd__(self, constraint: Constraint, /) -> Self: ...
|
|
2969
3621
|
@overload
|
|
2970
|
-
def __iadd__(self, constraint: tuple[Constraint, str], /): ...
|
|
2971
|
-
def __iadd__(self, constraint: Constraint | tuple[Constraint, str], /):
|
|
3622
|
+
def __iadd__(self, constraint: tuple[Constraint, str], /) -> Self: ...
|
|
3623
|
+
def __iadd__(self, constraint: (Constraint | tuple[Constraint, str]), /) -> Self:
|
|
2972
3624
|
"""
|
|
2973
3625
|
In-place constraint addition using `+=`.
|
|
2974
3626
|
|
|
@@ -2987,9 +3639,22 @@ class Constraints:
|
|
|
2987
3639
|
TypeError
|
|
2988
3640
|
If the value is not a `Constraint` or valid symbolic comparison.
|
|
2989
3641
|
"""
|
|
3642
|
+
...
|
|
2990
3643
|
|
|
2991
|
-
def __eq__(self, other: Constraints, /) -> bool: ...
|
|
3644
|
+
def __eq__(self, other: Constraints, /) -> bool: ...
|
|
3645
|
+
def __str__(self, /) -> str: ...
|
|
3646
|
+
def __repr__(self, /) -> str: ...
|
|
2992
3647
|
def __getitem__(self, item: int, /) -> Constraint: ...
|
|
3648
|
+
def __len__(self, /) -> int:
|
|
3649
|
+
"""
|
|
3650
|
+
Get the number of constraints.
|
|
3651
|
+
|
|
3652
|
+
Returns
|
|
3653
|
+
-------
|
|
3654
|
+
int
|
|
3655
|
+
The number of constraints associated with this `Constraints` object.
|
|
3656
|
+
"""
|
|
3657
|
+
...
|
|
2993
3658
|
|
|
2994
3659
|
__all__ = [
|
|
2995
3660
|
"Bounds",
|