luna-quantum 1.0.3rc3__cp311-cp311-win_amd64.whl → 1.0.4rc2__cp311-cp311-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__.pyi CHANGED
@@ -25,9 +25,9 @@ from ._core import (
25
25
  Variable,
26
26
  Vtype,
27
27
  errors,
28
+ transformations,
28
29
  translator,
29
30
  utils,
30
- transformations,
31
31
  )
32
32
  from .utils import quicksum
33
33
  from luna_quantum._core import __luna_quantum_version__
Binary file
luna_quantum/_core.pyi CHANGED
@@ -1,3 +1,4 @@
1
+ from collections.abc import Callable, Iterator
1
2
  from datetime import datetime, timedelta
2
3
  from enum import Enum
3
4
  from types import TracebackType
@@ -205,6 +206,11 @@ class Variable:
205
206
  """
206
207
  ...
207
208
 
209
+ @property
210
+ def id(self, /) -> int:
211
+ """Get the id of the variable."""
212
+ ...
213
+
208
214
  @property
209
215
  def name(self, /) -> str:
210
216
  """Get the name of the variable."""
@@ -904,7 +910,7 @@ class Solution:
904
910
  ...
905
911
 
906
912
  @property
907
- def obj_values(self, /) -> NDArray:
913
+ def obj_values(self, /) -> NDArray | None:
908
914
  """
909
915
  Get the objective values of the single samples as a ndarray.
910
916
 
@@ -913,7 +919,7 @@ class Solution:
913
919
  ...
914
920
 
915
921
  @property
916
- def raw_energies(self, /) -> NDArray:
922
+ def raw_energies(self, /) -> NDArray | None:
917
923
  """Get the raw energies.
918
924
 
919
925
  Get the raw energy values of the single samples as returned by the solver /
@@ -978,6 +984,23 @@ class Solution:
978
984
  """
979
985
  ...
980
986
 
987
+ def filter(self, /, f: Callable[[ResultView], bool]) -> Solution:
988
+ """
989
+ Get a new solution with all samples for which the condition `f` is true.
990
+
991
+ Parameters
992
+ ----------
993
+ f : Callable[[ResultView], bool]
994
+ A filter function yielding true for all samples to be contained in the
995
+ new solution.
996
+
997
+ Returns
998
+ -------
999
+ Solution
1000
+ The new solution with only samples for which the condition is true.
1001
+ """
1002
+ ...
1003
+
981
1004
  def filter_feasible(self, /) -> Solution:
982
1005
  """
983
1006
  Get a new solution with all infeasible samples removed.
@@ -1409,6 +1432,7 @@ class Solution:
1409
1432
  timing: (Timing | None) = ...,
1410
1433
  sense: (Sense | None) = ...,
1411
1434
  bit_order: Literal["LTR", "RTL"] = "RTL",
1435
+ raw_energies: (list[float] | None) = ...,
1412
1436
  ) -> Solution:
1413
1437
  """
1414
1438
  Create a `Solution` from a dict that maps measured bitstrings to counts.
@@ -1431,6 +1455,8 @@ class Solution:
1431
1455
  The sense the model the solution belongs to. Default: Sense.Min
1432
1456
  bit_order : Literal["LTR", "RTL"]
1433
1457
  The order of the bits in the bitstring. Default "RTL".
1458
+ energies: list[float], optional
1459
+ The raw energies for each sample. Default None.
1434
1460
 
1435
1461
  Returns
1436
1462
  -------
@@ -1522,6 +1548,90 @@ class Solution:
1522
1548
  """
1523
1549
  ...
1524
1550
 
1551
+ @overload
1552
+ def add_var(self, var: Variable, data: list[int | float]) -> None: ...
1553
+ @overload
1554
+ def add_var(
1555
+ self, var: str, data: list[int | float], vtype: (Vtype | None) = ...
1556
+ ) -> None: ...
1557
+ def add_var(
1558
+ self,
1559
+ var: (str | Variable),
1560
+ data: list[int | float],
1561
+ vtype: (Vtype | None) = ...,
1562
+ ) -> None:
1563
+ """Add a variable column to the solution.
1564
+
1565
+ Parameters
1566
+ ----------
1567
+ var : str | Variable
1568
+ The name of the variable for which the sample column is created,
1569
+ or the variable itself.
1570
+ data : list[int | float]
1571
+ The contents of the sample column to be added.
1572
+ vtype : Vtype | None, default None
1573
+ The vtype of the variable for which the sample column is created.
1574
+ If the `var` parameter is a str, the vtype is defaulted to Vtype.Binary.
1575
+ If the `var` is a Variable, the `vtype` parameter is ignored and the
1576
+ vtype of the variable is used.
1577
+
1578
+ Raises
1579
+ ------
1580
+ SampleColumnCreationError
1581
+ """
1582
+
1583
+ @overload
1584
+ def add_vars(
1585
+ self, variables: list[Variable], data: list[list[int | float]]
1586
+ ) -> None: ...
1587
+ @overload
1588
+ def add_vars(
1589
+ self, variables: list[str], data: list[list[int | float]], vtypes: list[Vtype]
1590
+ ) -> None: ...
1591
+ @overload
1592
+ def add_vars(
1593
+ self,
1594
+ variables: list[Variable | str],
1595
+ data: list[list[int | float]],
1596
+ vtypes: list[Vtype | None],
1597
+ ) -> None: ...
1598
+ def add_vars(
1599
+ self,
1600
+ variables: list[Variable | str],
1601
+ data: list[list[int | float]],
1602
+ vtypes: (list[Vtype | None] | None) = ...,
1603
+ ) -> None:
1604
+ """Add multiple variable columns to the solution.
1605
+
1606
+ Parameters
1607
+ ----------
1608
+ vars : list[str | Variable]
1609
+ The names of the variable for which the sample columns are created,
1610
+ or a list of the variables itself.
1611
+ data : list[list[int | float]]
1612
+ A list of the contents of the sample columns to be added.
1613
+ vtypes : list[Vtype] | None
1614
+ The vtypes of the variables for which the sample columns are created.
1615
+ If the `vars` parameter is a `list[str], the vtypes are defaulted to
1616
+ Vtype.Binary.
1617
+ If the `vars` is a list[Variable], the `vtypes` parameter is ignored and the
1618
+ vtypes of the variable is used.
1619
+ For mixed `vars`, the vtype is chosen dynamically following the
1620
+ two rules above.
1621
+
1622
+ Raises
1623
+ ------
1624
+ SampleColumnCreationError
1625
+ """
1626
+
1627
+ def remove_var(self, var: (str | Variable)) -> None:
1628
+ """Remove the sample column for the given variable."""
1629
+ ...
1630
+
1631
+ def remove_vars(self, variables: list[str | Variable]) -> None:
1632
+ """Remove the sample columns for the given variables."""
1633
+ ...
1634
+
1525
1635
  class SamplesIterator:
1526
1636
  """
1527
1637
  An iterator over a solution's samples.
@@ -2047,6 +2157,63 @@ class Model:
2047
2157
  """
2048
2158
  ...
2049
2159
 
2160
+ @overload
2161
+ def add_variable_with_fallback(self, name: str, /) -> Variable: ...
2162
+ @overload
2163
+ def add_variable_with_fallback(
2164
+ self, name: str, /, vtype: (Vtype | None) = ...
2165
+ ) -> Variable: ...
2166
+ @overload
2167
+ def add_variable_with_fallback(
2168
+ self, name: str, /, vtype: Vtype, *, lower: (float | type[Unbounded] | None)
2169
+ ) -> Variable: ...
2170
+ @overload
2171
+ def add_variable_with_fallback(
2172
+ self, name: str, /, vtype: Vtype, *, upper: (float | type[Unbounded] | None)
2173
+ ) -> Variable: ...
2174
+ @overload
2175
+ def add_variable_with_fallback(
2176
+ self,
2177
+ name: str,
2178
+ /,
2179
+ vtype: Vtype,
2180
+ *,
2181
+ lower: (float | type[Unbounded] | None),
2182
+ upper: (float | type[Unbounded] | None),
2183
+ ) -> Variable: ...
2184
+ def add_variable_with_fallback(
2185
+ self,
2186
+ name: str,
2187
+ /,
2188
+ vtype: (Vtype | None) = ...,
2189
+ *,
2190
+ lower: (float | type[Unbounded] | None) = ...,
2191
+ upper: (float | type[Unbounded] | None) = ...,
2192
+ ) -> Variable:
2193
+ """
2194
+ Add a new variable to the model with fallback renaming.
2195
+
2196
+ Parameters
2197
+ ----------
2198
+ name : str
2199
+ The name of the variable.
2200
+ vtype : Vtype, optional
2201
+ The variable type (e.g., `Vtype.Real`, `Vtype.Integer`, etc.).
2202
+ Defaults to `Vtype.Binary`.
2203
+ lower: float, optional
2204
+ The lower bound restricts the range of the variable. Only applicable for
2205
+ `Real` and `Integer` variables.
2206
+ upper: float, optional
2207
+ The upper bound restricts the range of the variable. Only applicable for
2208
+ `Real` and `Integer` variables.
2209
+
2210
+ Returns
2211
+ -------
2212
+ Variable
2213
+ The variable added to the model.
2214
+ """
2215
+ ...
2216
+
2050
2217
  def get_variable(self, name: str, /) -> Variable:
2051
2218
  """Get a variable by its label (name).
2052
2219
 
@@ -2167,6 +2334,18 @@ class Model:
2167
2334
  """
2168
2335
  ...
2169
2336
 
2337
+ @property
2338
+ def num_variables(self, /) -> int:
2339
+ """
2340
+ Return the number of variables defined in the model.
2341
+
2342
+ Returns
2343
+ -------
2344
+ int
2345
+ Total number of variables.
2346
+ """
2347
+ ...
2348
+
2170
2349
  @property
2171
2350
  def num_constraints(self, /) -> int:
2172
2351
  """
@@ -2376,6 +2555,9 @@ class Model:
2376
2555
  def __str__(self, /) -> str: ...
2377
2556
  def __repr__(self, /) -> str: ...
2378
2557
  def __hash__(self, /) -> int: ...
2558
+ def deep_clone(self) -> Model:
2559
+ """Make a deep clone of the model."""
2560
+ ...
2379
2561
  metadata: ModelMetadata | None = ...
2380
2562
 
2381
2563
  @staticmethod
@@ -2613,6 +2795,72 @@ class Expression:
2613
2795
  """
2614
2796
  ...
2615
2797
 
2798
+ def linear_items(self, /) -> list[tuple[Variable, float]]:
2799
+ """
2800
+ Get all linear components.
2801
+
2802
+ Returns
2803
+ -------
2804
+ list[tuple[Variable, float]]
2805
+ The linear components.
2806
+ """
2807
+ ...
2808
+
2809
+ def quadratic_items(self, /) -> list[tuple[Variable, Variable, float]]:
2810
+ """
2811
+ Get all quadratic components.
2812
+
2813
+ Returns
2814
+ -------
2815
+ list[tuple[Variable, Variable, float]]
2816
+ The quadratic components.
2817
+ """
2818
+ ...
2819
+
2820
+ def higher_order_items(self, /) -> list[tuple[list[Variable], float]]:
2821
+ """
2822
+ Get all higher-order components.
2823
+
2824
+ Returns
2825
+ -------
2826
+ list[tuple[list[Variable], float]]
2827
+ The higher-order components.
2828
+ """
2829
+ ...
2830
+
2831
+ def is_constant(self, /) -> bool:
2832
+ """
2833
+ Check if expression is constant.
2834
+
2835
+ Returns
2836
+ -------
2837
+ bool
2838
+ If the expression is constant
2839
+ """
2840
+ ...
2841
+
2842
+ def has_quadratic(self, /) -> bool:
2843
+ """
2844
+ Check if expression has quadratic.
2845
+
2846
+ Returns
2847
+ -------
2848
+ bool
2849
+ If the expression has quadratic
2850
+ """
2851
+ ...
2852
+
2853
+ def has_higher_order(self, /) -> bool:
2854
+ """
2855
+ Check if expression has higher-order.
2856
+
2857
+ Returns
2858
+ -------
2859
+ bool
2860
+ If the expression has higher-order
2861
+ """
2862
+ ...
2863
+
2616
2864
  def is_equal(self, /, other: Expression) -> bool:
2617
2865
  """
2618
2866
  Compare two expressions for equality.
@@ -3698,6 +3946,11 @@ class Constraints:
3698
3946
  @overload
3699
3947
  def __getitem__(self, item: int, /) -> Constraint: ...
3700
3948
  def __getitem__(self, item: (int | str), /) -> Constraint: ...
3949
+ @overload
3950
+ def __setitem__(self, item: str, content: Constraint, /) -> None: ...
3951
+ @overload
3952
+ def __setitem__(self, item: int, content: Constraint, /) -> None: ...
3953
+ def __setitem__(self, item: (int | str), content: Constraint, /) -> None: ...
3701
3954
  def __len__(self, /) -> int:
3702
3955
  """
3703
3956
  Get the number of constraints.
@@ -3709,6 +3962,7 @@ class Constraints:
3709
3962
  """
3710
3963
  ...
3711
3964
 
3965
+ def __iter__(self, /) -> Iterator[Constraint]: ...
3712
3966
  def equal_contents(self, other: Constraints, /) -> bool:
3713
3967
  """
3714
3968
  Check whether this constraints has equal contents as `other`.
@@ -0,0 +1,247 @@
1
+ """Decorators."""
2
+
3
+ from collections.abc import Callable
4
+ from typing import Any, Generic, TypeVar, override
5
+
6
+ from . import Model, Solution
7
+ from .transformations import (
8
+ ActionType,
9
+ AnalysisCache,
10
+ AnalysisPass,
11
+ BasePass,
12
+ MetaAnalysisPass,
13
+ TransformationOutcome,
14
+ TransformationPass,
15
+ )
16
+
17
+ T = TypeVar("T")
18
+
19
+
20
+ type AnalysisSignature[T] = Callable[[Model, AnalysisCache], T]
21
+
22
+ type MetaAnalysisSignature[T] = Callable[[list[BasePass], AnalysisCache], T]
23
+
24
+ type Outcome = (
25
+ TransformationOutcome | tuple[Model, ActionType] | tuple[Model, ActionType, Any]
26
+ )
27
+ type TransformationSignature = Callable[
28
+ [Model, AnalysisCache],
29
+ Outcome,
30
+ ]
31
+ type BackwardsSignature = Callable[[Solution, AnalysisCache], Solution]
32
+
33
+
34
+ def __identity_backwards(solution: Solution, _: AnalysisCache) -> Solution:
35
+ return solution
36
+
37
+
38
+ class DynamicAnalysisPass(AnalysisPass, Generic[T]):
39
+ def __init__(
40
+ self,
41
+ name: str,
42
+ requires: list[str],
43
+ func: AnalysisSignature[T],
44
+ ) -> None:
45
+ self._name = name
46
+ self._requires = requires
47
+ self._func = func
48
+
49
+ @property
50
+ def name(self) -> str:
51
+ return self._name
52
+
53
+ @property
54
+ def requires(self) -> list[str]:
55
+ return self._requires
56
+
57
+ def __repr__(self) -> str:
58
+ return f'FunctionAnalysis(name="{self.name}")'
59
+
60
+ @override
61
+ def run(self, model: Model, cache: AnalysisCache) -> T:
62
+ return self._func(model, cache)
63
+
64
+ def __call__(self, model: Model, cache: AnalysisCache) -> T:
65
+ return self._func(model, cache)
66
+
67
+
68
+ class DynamicMetaAnalysisPass(MetaAnalysisPass, Generic[T]):
69
+ def __init__(
70
+ self,
71
+ name: str,
72
+ requires: list[str],
73
+ func: MetaAnalysisSignature[T],
74
+ ) -> None:
75
+ self._name = name
76
+ self._requires = requires
77
+ self._func = func
78
+
79
+ @property
80
+ def name(self) -> str:
81
+ return self._name
82
+
83
+ @property
84
+ def requires(self) -> list[str]:
85
+ return self._requires
86
+
87
+ def __repr__(self) -> str:
88
+ return f'FunctionMetaAnalysis(name="{self.name}")'
89
+
90
+ @override
91
+ def run(self, passes: list[BasePass], cache: AnalysisCache) -> T:
92
+ return self._func(passes, cache)
93
+
94
+ def __call__(self, passes: list[BasePass], cache: AnalysisCache) -> T:
95
+ return self._func(passes, cache)
96
+
97
+
98
+ class DynamicTransformationPass(TransformationPass):
99
+ def __init__(
100
+ self,
101
+ name: str,
102
+ requires: list[str],
103
+ invalidates: list[str],
104
+ func: TransformationSignature,
105
+ backwards: BackwardsSignature,
106
+ ) -> None:
107
+ self._name = name
108
+ self._requires = requires
109
+ self._invalidates = invalidates
110
+ self._func = func
111
+ self._backwards = backwards
112
+
113
+ @property
114
+ def name(self) -> str:
115
+ return self._name
116
+
117
+ @property
118
+ def requires(self) -> list[str]:
119
+ return self._requires
120
+
121
+ @override
122
+ def run(self, model: Model, cache: AnalysisCache) -> Outcome:
123
+ return self._func(model, cache)
124
+
125
+ @override
126
+ def backwards(self, solution: Solution, cache: AnalysisCache) -> Solution:
127
+ return self._backwards(solution, cache)
128
+
129
+ def __call__(self, model: Model, cache: AnalysisCache) -> Outcome:
130
+ return self._func(model, cache)
131
+
132
+ def __repr__(self) -> str:
133
+ return f'FunctionTransformation(name="{self.name}")'
134
+
135
+
136
+ def analyse(
137
+ name: str | None = None, requires: list[str] | None = None
138
+ ) -> Callable[[AnalysisSignature[T]], DynamicAnalysisPass[T]]:
139
+ """Create an AnalysisPass instance from a function.
140
+
141
+ Parameters
142
+ ----------
143
+ name: str | None
144
+ The name of the analysis pass. If no name provided, uses the function name.
145
+ requires: list[str] | None
146
+ List of required analysis passes (defaults to empty list)
147
+
148
+ Returns
149
+ -------
150
+ Callable[[Callable[[Model, AnalysisCache], Any]], AnalysisPass]
151
+ An instance of a dynamically created AnalysisPass subclass
152
+ """
153
+ if requires is None:
154
+ requires = []
155
+
156
+ _T = TypeVar("_T")
157
+
158
+ def _decorator(
159
+ func: AnalysisSignature[_T],
160
+ ) -> DynamicAnalysisPass[_T]:
161
+ loc_name = name or func.__name__.replace("_", "-")
162
+
163
+ return DynamicAnalysisPass(name=loc_name, requires=requires, func=func)
164
+
165
+ return _decorator
166
+
167
+
168
+ def meta_analyse(
169
+ name: str | None = None, requires: list[str] | None = None
170
+ ) -> Callable[[MetaAnalysisSignature[T]], DynamicMetaAnalysisPass[T]]:
171
+ """Create an MetaAnalysisPass instance from a function.
172
+
173
+ Parameters
174
+ ----------
175
+ name: str | None
176
+ The name of the analysis pass. If no name provided, uses the function name.
177
+ requires: list[str] | None
178
+ List of required analysis passes (defaults to empty list)
179
+
180
+ Returns
181
+ -------
182
+ Callable[[Callable[[list[BasePass], AnalysisCache], Any]], MetaAnalysisPass]
183
+ An instance of a dynamically created AnalysisPass subclass
184
+ """
185
+ if requires is None:
186
+ requires = []
187
+
188
+ _T = TypeVar("_T")
189
+
190
+ def _decorator(
191
+ func: MetaAnalysisSignature[_T],
192
+ ) -> DynamicMetaAnalysisPass[_T]:
193
+ loc_name = name or func.__name__.replace("_", "-")
194
+
195
+ return DynamicMetaAnalysisPass(name=loc_name, requires=requires, func=func)
196
+
197
+ return _decorator
198
+
199
+
200
+ def transform(
201
+ name: str | None = None,
202
+ requires: list[str] | None = None,
203
+ invalidates: list[str] | None = None,
204
+ backwards: BackwardsSignature | None = None,
205
+ ) -> Callable[[TransformationSignature], DynamicTransformationPass]:
206
+ """Create an TransformationPass instance from a function.
207
+
208
+ Parameters
209
+ ----------
210
+ name: str | None = None
211
+ The name of the analysis pass. If no name provided, uses the function name.
212
+ requires: list[str] | None = None
213
+ List of required analysis passes (defaults to empty list)
214
+ invalidates: list[str] | None = None
215
+ List of analysis results to invalidate (defaults to empty list)
216
+ backwards: BackwardsSignature | None = None,
217
+ Solution backwards mapping function. If none provided, pass solution upstream
218
+ without modification.
219
+
220
+ Returns
221
+ -------
222
+ Callable[[TransformationSignature], DynamicTransformationPass]
223
+ An instance of a dynamically created TransformationPass subclass
224
+ """
225
+ if requires is None:
226
+ requires = []
227
+ if invalidates is None:
228
+ invalidates = []
229
+
230
+ if backwards is None:
231
+ backwards = __identity_backwards
232
+
233
+ def _decorator(func: TransformationSignature) -> DynamicTransformationPass:
234
+ loc_name = name or func.__name__.replace("_", "-")
235
+
236
+ return DynamicTransformationPass(
237
+ name=loc_name,
238
+ requires=requires,
239
+ invalidates=invalidates,
240
+ func=func,
241
+ backwards=backwards,
242
+ )
243
+
244
+ return _decorator
245
+
246
+
247
+ __all__ = ["analyse", "transform"]
luna_quantum/errors.pyi CHANGED
@@ -241,6 +241,11 @@ class NoConstraintForKeyError(IndexError):
241
241
 
242
242
  def __str__(self, /) -> str: ...
243
243
 
244
+ class SampleColCreationError(IndexError):
245
+ """Raised when an error occured during creation of a sample column."""
246
+
247
+ def __str__(self, /) -> str: ...
248
+
244
249
  class InternalPanicError(RuntimeError):
245
250
  """Raised when an internal and unrecoverable error occurred."""
246
251
 
@@ -262,6 +267,7 @@ __all__ = [
262
267
  "MultipleActiveEnvironmentsError",
263
268
  "NoActiveEnvironmentFoundError",
264
269
  "NoConstraintForKeyError",
270
+ "SampleColCreationError",
265
271
  "SampleIncompatibleVtypeError",
266
272
  "SampleIncorrectLengthError",
267
273
  "SampleUnexpectedVariableError",
@@ -49,34 +49,6 @@ class Qctrl(QpuTokenBackend):
49
49
  https://docs.q-ctrl.com/fire-opal/topics/fire-opals-qaoa-solver)
50
50
  """
51
51
 
52
- class IBMQ(BaseModel):
53
- """
54
- Configuration parameters for the IBM Quantum backend.
55
-
56
- Attributes
57
- ----------
58
- hub: str, default="ibm-q"
59
- The IBM Quantum hub to use for accessing quantum resources.
60
- This defines your access level and available systems.
61
-
62
- group: str, default="open"
63
- The IBM Quantum group within your hub.
64
- Groups help organize users and projects within a hub.
65
-
66
- project: str, default="main"
67
- The IBM Quantum project within your group.
68
- Projects help organize work and resource allocation.
69
-
70
- token: Union[str, None, QpuToken], default=None
71
- The IBM API token.
72
- """
73
-
74
- hub: str = "ibm-q"
75
- group: str = "open"
76
- project: str = "main"
77
-
78
- token: str | QpuToken | None = Field(repr=False, exclude=True, default=None)
79
-
80
52
  class IBMCloud(BaseModel):
81
53
  """
82
54
  Configuration parameters for the IBM Cloud backend.
@@ -90,14 +62,14 @@ class Qctrl(QpuTokenBackend):
90
62
  The IBM API token.
91
63
  """
92
64
 
93
- instance: str
65
+ instance: str = ""
94
66
 
95
67
  token: str | QpuToken | None = Field(repr=False, exclude=True, default=None)
96
68
 
97
69
  organization_slug: Any = None
98
70
  backend_name: str | None = None
99
71
 
100
- ibm_credentials: IBMQ | IBMCloud = Field(default=IBMQ())
72
+ ibm_credentials: IBMCloud = Field(default=IBMCloud())
101
73
 
102
74
  token: str | QpuToken | None = Field(repr=False, exclude=True, default=None)
103
75
 
@@ -1,8 +1,9 @@
1
1
  from abc import abstractmethod
2
+ from collections.abc import Callable
2
3
  from enum import Enum
3
4
  from typing import Any, Literal, overload
4
5
 
5
- from aqmodels import Model, Sense, Solution, Timing, Vtype
6
+ from . import Model, Sense, Solution, Timing, Vtype
6
7
 
7
8
  class BasePass:
8
9
  @property
@@ -14,6 +15,76 @@ class BasePass:
14
15
  """Get a list of required passes that need to be run before this pass."""
15
16
  ...
16
17
 
18
+ class Pipeline(BasePass):
19
+ @overload
20
+ def __init__(self, passes: list[BasePass]) -> None: ...
21
+ @overload
22
+ def __init__(self, passes: list[BasePass], name: str) -> None: ...
23
+ def __init__(self, passes: list[BasePass], name: str | None = ...) -> None: ...
24
+ @property
25
+ def name(self) -> str:
26
+ """Get the name of this pass."""
27
+ ...
28
+ @property
29
+ def requires(self) -> list[str]:
30
+ """Get a list of required passes that need to be run before this pass."""
31
+ ...
32
+
33
+ @property
34
+ def satisfies(self) -> set[str]:
35
+ """Get a list of required passes that need to be run before this pass."""
36
+ ...
37
+
38
+ def add(self, new_pass: BasePass) -> None:
39
+ """Add new pass to pipeline."""
40
+ ...
41
+
42
+ def clear(self) -> None:
43
+ """Clear pipeline."""
44
+ ...
45
+
46
+ @property
47
+ def passes(self) -> list[BasePass]:
48
+ """Get all passes that are part of the pipeline."""
49
+ ...
50
+
51
+ def __len__(self) -> int: ...
52
+
53
+ class IfElsePass(BasePass):
54
+ @overload
55
+ def __init__(
56
+ self,
57
+ requires: list[str],
58
+ condition: Callable[[AnalysisCache], bool],
59
+ then: Pipeline,
60
+ otherwise: Pipeline,
61
+ ) -> None: ...
62
+ @overload
63
+ def __init__(
64
+ self,
65
+ requires: list[str],
66
+ condition: Callable[[AnalysisCache], bool],
67
+ then: Pipeline,
68
+ otherwise: Pipeline,
69
+ name: str,
70
+ ) -> None: ...
71
+ def __init__(
72
+ self,
73
+ requires: list[str],
74
+ condition: Callable[[AnalysisCache], bool],
75
+ then: Pipeline,
76
+ otherwise: Pipeline,
77
+ name: str | None = ...,
78
+ ) -> None: ...
79
+ @property
80
+ def name(self) -> str:
81
+ """Get the name of this pass."""
82
+ ...
83
+ @property
84
+ def requires(self) -> list[str]:
85
+ """Get a list of required passes that need to be run before this pass."""
86
+ ...
87
+
17
88
  class TransformationPass(BasePass):
18
89
  @property
19
90
  @abstractmethod
@@ -29,7 +100,11 @@ class TransformationPass(BasePass):
29
100
  """Get a list of passes that are invalidated by this pass."""
30
101
  ...
31
102
  @abstractmethod
32
- def run(self, model: Model, cache: AnalysisCache) -> tuple[Model, ActionType]:
103
+ def run(
104
+ self, model: Model, cache: AnalysisCache
105
+ ) -> (
106
+ TransformationOutcome | tuple[Model, ActionType] | tuple[Model, ActionType, Any]
107
+ ):
33
108
  """Run/Execute this transformation pass."""
34
109
  ...
35
110
  @abstractmethod
@@ -41,13 +116,28 @@ class TransformationPass(BasePass):
41
116
  """
42
117
  ...
43
118
 
119
+ class TransformationOutcome:
120
+ """Output object for transformation pass."""
121
+
122
+ model: Model
123
+ action: ActionType
124
+ analysis: ...
125
+
126
+ def __init__(
127
+ self, model: Model, action: ActionType, analysis: ... = None
128
+ ) -> None: ...
129
+ @staticmethod
130
+ def nothing(model: Model) -> TransformationOutcome:
131
+ """Easy nothing action return."""
132
+ ...
133
+
44
134
  class AnalysisCache:
45
135
  @overload
46
136
  def __getitem__( # type: ignore[reportOverlappingOverload]
47
137
  self, key: Literal["max-bias"]
48
138
  ) -> MaxBias: ...
49
139
  @overload
50
- def __getitem__(self, key: str) -> dict[Any, Any]: ...
140
+ def __getitem__(self, key: str) -> ...: ...
51
141
  def __getitem__(self, key: str) -> Any:
52
142
  """Get the analysis result for a specific analysis pass."""
53
143
  ...
@@ -63,7 +153,22 @@ class AnalysisPass(BasePass):
63
153
  """Get a list of required passes that need to be run before this pass."""
64
154
  ...
65
155
  @abstractmethod
66
- def run(self, model: Model, cache: AnalysisCache) -> float:
156
+ def run(self, model: Model, cache: AnalysisCache) -> ...:
157
+ """Run/Execute this analysis pass."""
158
+ ...
159
+
160
+ class MetaAnalysisPass(BasePass):
161
+ @property
162
+ @abstractmethod
163
+ def name(self) -> str:
164
+ """Get the name of this pass."""
165
+ ...
166
+ @property
167
+ def requires(self) -> list[str]:
168
+ """Get a list of required passes that need to be run before this pass."""
169
+ ...
170
+ @abstractmethod
171
+ def run(self, passes: list[BasePass], cache: AnalysisCache) -> ...:
67
172
  """Run/Execute this analysis pass."""
68
173
  ...
69
174
 
@@ -72,7 +177,9 @@ class ActionType(Enum):
72
177
  """Indicate that the pass did transform the model."""
73
178
  DidAnalysis = ...
74
179
  """Indicate that the pass did analyse the model."""
75
- Nothing = ...
180
+ DidAnalysisTransform = ...
181
+ """Indicate that the pass did analyse and transfrom the model."""
182
+ DidNothing = ...
76
183
  """Indicate that the pass did NOT do anything."""
77
184
 
78
185
  class ChangeSensePass(BasePass):
@@ -105,15 +212,22 @@ class MaxBiasAnalysis(BasePass):
105
212
 
106
213
  def __init__(self) -> None: ...
107
214
 
108
- class BinarySpinAnalysis(BasePass):
109
- """An analysis pass noting down which variables need to be transformed."""
215
+ class BinarySpinPass(BasePass):
216
+ """An transformation pass changing the binary/spin variables to spin/binary."""
110
217
 
111
- def __init__(self, vtype: Literal[Vtype.Binary, Vtype.Spin]) -> None: ...
218
+ def __init__(
219
+ self, vtype: Literal[Vtype.Binary, Vtype.Spin], prefix: str | None
220
+ ) -> None: ...
112
221
  @property
113
222
  def vtype(self) -> Vtype:
114
223
  """Get the target vtype."""
115
224
  ...
116
225
 
226
+ @property
227
+ def prefix(self) -> str | None:
228
+ """Get the naming prefix."""
229
+ ...
230
+
117
231
  class BinarySpinInfo:
118
232
  @property
119
233
  def old_vtype(self) -> Vtype:
@@ -122,19 +236,9 @@ class BinarySpinInfo:
122
236
 
123
237
  @property
124
238
  def new_vtype(self) -> Vtype:
125
- """Get the target vtype."""
126
- ...
127
-
128
- @property
129
- def map(self) -> dict[str, str]:
130
239
  """Get the variable name mapping."""
131
240
  ...
132
241
 
133
- class BinarySpinPass(BasePass):
134
- """An transformation pass changing the denoted variables to target."""
135
-
136
- def __init__(self) -> None: ...
137
-
138
242
  class LogElement:
139
243
  """An element of the execution log of an intermediate representation (IR)."""
140
244
 
@@ -153,6 +257,11 @@ class LogElement:
153
257
  """Transformation type information for this log element, if available."""
154
258
  ...
155
259
 
260
+ # @property
261
+ # def components(self) -> list[LogElement] | None:
262
+ # """Components of this log-element."""
263
+ # ...
264
+
156
265
  class IR:
157
266
  """The intermediate representation (IR) of a model after transformation.
158
267
 
@@ -187,7 +296,7 @@ class PassManager:
187
296
  """
188
297
 
189
298
  def __init__(
190
- self, passes: list[BasePass | TransformationPass | AnalysisPass]
299
+ self, passes: list[BasePass | TransformationPass | AnalysisPass] | None = ...
191
300
  ) -> None:
192
301
  """Manage and execute a sequence of passes on a model.
193
302
 
@@ -200,9 +309,9 @@ class PassManager:
200
309
 
201
310
  Parameters
202
311
  ----------
203
- passes : list[TransformationPass | AnalysisPass]
312
+ passes : list[TransformationPass | AnalysisPass] | None
204
313
  An ordered sequence of Pass instances to apply. Each Pass must conform to
205
- the `TransformationPass` or `AnalysisPass` interface.
314
+ the `TransformationPass` or `AnalysisPass` interface, default None.
206
315
  """
207
316
  ...
208
317
 
luna_quantum/utils.pyi CHANGED
@@ -1,7 +1,7 @@
1
1
  from collections.abc import Generator, Iterable
2
2
  from typing import overload
3
3
 
4
- from aqmodels import Expression, Variable
4
+ from . import Expression, Variable
5
5
 
6
6
  @overload
7
7
  def quicksum(iterable: Generator[Expression], /) -> Expression: ...
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: luna-quantum
3
- Version: 1.0.3rc3
3
+ Version: 1.0.4rc2
4
4
  Classifier: Programming Language :: Python :: 3
5
5
  Classifier: License :: OSI Approved :: Apache Software License
6
6
  Classifier: Operating System :: OS Independent
@@ -16,7 +16,7 @@ License-File: NOTICE
16
16
  Summary: Python SDK for Aqarios' Luna Platform
17
17
  Keywords: aqarios,luna,quantum computing,quantum optimization,optimization,sdk
18
18
  Author-email: Aqarios <pypi@aqarios.com>
19
- License: Apache-2.0
19
+ License-Expression: Apache-2.0
20
20
  Requires-Python: >=3.11.0, <3.14
21
21
  Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
22
22
  Project-URL: Homepage, https://aqarios.com/
@@ -1,11 +1,11 @@
1
- luna_quantum-1.0.3rc3.dist-info/METADATA,sha256=1TbSzuciN5vaguhRzvuOPRByA5JstwjrHtqPFoCh0Pc,1574
2
- luna_quantum-1.0.3rc3.dist-info/WHEEL,sha256=auo2gA2SV-bvS4ssY6DIG7dtu3SpmB5FcBkwIwO6YZk,96
3
- luna_quantum-1.0.3rc3.dist-info/licenses/LICENSE,sha256=bR2Wj7Il7KNny38LiDGrASo12StUfpReF--OewXD5cw,10349
4
- luna_quantum-1.0.3rc3.dist-info/licenses/NOTICE,sha256=GHZYA5H4QFAhbhXliAi2SjWWXLjxl4hrHdEPyUbC0r0,601
1
+ luna_quantum-1.0.4rc2.dist-info/METADATA,sha256=3nElJ8QpDP4nLJF4-sBuorJN5c5BSV3G5g26CdauZGI,1585
2
+ luna_quantum-1.0.4rc2.dist-info/WHEEL,sha256=Ncll1xfKuKRSH9zs2vSEuHQoNZLcJWpzadJbiEni0qk,96
3
+ luna_quantum-1.0.4rc2.dist-info/licenses/LICENSE,sha256=bR2Wj7Il7KNny38LiDGrASo12StUfpReF--OewXD5cw,10349
4
+ luna_quantum-1.0.4rc2.dist-info/licenses/NOTICE,sha256=GHZYA5H4QFAhbhXliAi2SjWWXLjxl4hrHdEPyUbC0r0,601
5
5
  luna_quantum/__init__.py,sha256=9Dpk-wfL5fR_R74c-JsFKZmUy7OUfe4hj4ZXEJaPAt4,3342
6
- luna_quantum/__init__.pyi,sha256=hDTZ1lJV4kd104FvjVmMbMn0jNt9V3LqTvDDssJGwQU,1746
7
- luna_quantum/_core.cp311-win_amd64.pyd,sha256=ztfFnPs3h0p65wgzj36UR619grhyj7j7SWe2435DuYc,5332480
8
- luna_quantum/_core.pyi,sha256=6pMRZOkvfa8nBUpuY709CpJxIi5BmYjsO9T9dx7ltjc,109845
6
+ luna_quantum/__init__.pyi,sha256=9Md6njbzsErrktv0GlRGYSunQIrIyw5r0kEJx1yMpkw,1746
7
+ luna_quantum/_core.cp311-win_amd64.pyd,sha256=b5YlkOS6BqH9HWTyfefyD1dpBFm-7rhRDFnFoqjfO80,5993984
8
+ luna_quantum/_core.pyi,sha256=mezdmnUnyZqfYqFIKG4a1UtM3A6Y4RqSNqdybbH9q-E,117664
9
9
  luna_quantum/algorithms/__init__.py,sha256=EoTNO0FXXjPrhpYfN7q9c_nUhmVHk2nEZsbhaVOBh_g,70
10
10
  luna_quantum/aqm_overwrites/__init__.py,sha256=ieIVhfslOwrznbvwqu3vNzU_nFIHS1hyeUgIV097WdQ,49
11
11
  luna_quantum/aqm_overwrites/model.py,sha256=stqMo97W0nzDLoWmTqwefdu7xgtPAWS46dsxOcJDHpU,6283
@@ -81,8 +81,9 @@ luna_quantum/client/schemas/wrappers/datetime_wrapper.py,sha256=11KmaftPtKoafhcg
81
81
  luna_quantum/client/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
82
82
  luna_quantum/client/utils/qpu_token_utils.py,sha256=goq4nwmxKz0GTqLep01ydoopqHb336FPv6CXGGtR260,4915
83
83
  luna_quantum/config.py,sha256=a5UgYn6TIT2pFfdprvDy0RzyI4eAI_OFSdFSxpjQr2M,228
84
+ luna_quantum/decorators.py,sha256=h9APzB-s3p_kCf0LfBPjG23hlswcWZfupK492DxUoJc,7084
84
85
  luna_quantum/errors.py,sha256=9qeMJY-hI1qlBqrWjaESVGx3ujEQuFdqONGgIl107kk,1458
85
- luna_quantum/errors.pyi,sha256=AynKirSxuqSRfoxA-IJ43-aTM3T55w8FSmbAJrB-jNM,9387
86
+ luna_quantum/errors.pyi,sha256=tf4cDmBtbE6Mjujl3B3nbT1zQzLM__iS9neFYA3chv4,9579
86
87
  luna_quantum/exceptions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
87
88
  luna_quantum/exceptions/base_luna_quantum_error.py,sha256=Gl65slQxbNJoo8Kgnqif-slshlluCke0O0ow2r5PZE0,91
88
89
  luna_quantum/exceptions/patch_class_field_exists_error.py,sha256=4nmnGlPXp-SjuNX72PETXQ4eZzVpMTxH0eYs1IVDUPQ,408
@@ -175,7 +176,7 @@ luna_quantum/solve/parameters/backends/aws/rigetti.py,sha256=t4mZHr1cqrJ3dPdCg3t
175
176
  luna_quantum/solve/parameters/backends/dwave.py,sha256=BjNlM2nKWeyaMfpBcBHaAOt7mzV-p-SjC6bUQ5ltaNk,375
176
177
  luna_quantum/solve/parameters/backends/dwave_qpu.py,sha256=JQucgjQEmvLWa7tAaasw5ZZ02fa83vOoxg1xdOIfSEw,7480
177
178
  luna_quantum/solve/parameters/backends/ibm.py,sha256=4T7vNcyrG2IAAR-LuJMQZKdndhqkvPbWSotlayGJYHM,4369
178
- luna_quantum/solve/parameters/backends/qctrl.py,sha256=eeEj2pAXKQCFRmBrcgahdune615C_Hlz3gaWQbiOVwM,4528
179
+ luna_quantum/solve/parameters/backends/qctrl.py,sha256=W0BzW6HqcuynQOsm1HP38PUMB2AYMz2FC5LvUa8DJ5U,3606
179
180
  luna_quantum/solve/parameters/backends/zib.py,sha256=_hqSR5RyVJ5TBIUTPUHoCf-h--THt2jP5hRJkggMUCw,369
180
181
  luna_quantum/solve/parameters/constants.py,sha256=-i0Moh5JJZw5yYcX_393rSGw1TMXzNmez1vGoy18tOk,521
181
182
  luna_quantum/solve/parameters/mixins/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -244,7 +245,7 @@ luna_quantum/solve/usecases/solve_job_delete_usecase.py,sha256=a-lo9CoWjePo-aq7Y
244
245
  luna_quantum/solve/usecases/solve_job_fetch_updates_usecase.py,sha256=9vcs3x5uLmBjkqSF12IMHrPjrPSodm0AHI0qPVAruNE,1735
245
246
  luna_quantum/solve/usecases/solve_job_get_result_usecase.py,sha256=_62COwl-I1iGaX2lfrUnmZmPyKJZRNrJGtRVBiW1SYc,3636
246
247
  luna_quantum/transformations.py,sha256=A00BqmKpZz1Ixrb77a_ynpuqtB7w-AlVshg-QHp2UwM,920
247
- luna_quantum/transformations.pyi,sha256=ZuTF6cCy6vAcsqYuy7rBfNjHuYGay4vukrL-Zvobq7s,8053
248
+ luna_quantum/transformations.pyi,sha256=XjLxMhYGAeHABq19SHDBOTDEsOcHaBgTBQzlJ-5SxpQ,11135
248
249
  luna_quantum/translator.py,sha256=5RDTzFzd5sw3JzxFQsHdZQWhz2KDl03nzik5dUHebHI,1157
249
250
  luna_quantum/translator.pyi,sha256=RcePKY4Ztw-uv0Dfyx2DTw1TBMyem_SWts1MmzYZfn0,27347
250
251
  luna_quantum/util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -255,5 +256,5 @@ luna_quantum/util/log_utils.py,sha256=0-ARoGkp7xyTvw1i-pRJoq1ylDKNC4eDoVY2DG05DS
255
256
  luna_quantum/util/pretty_base.py,sha256=rJy28OKfNdB1j5xdzOmFrCdbw-Gb-JJ5Dcz3NvOpIcQ,2182
256
257
  luna_quantum/util/pydantic_utils.py,sha256=KipyyVaajjFB-krdPl_j5BLogaiPqn0L8mrJuLwZtic,1301
257
258
  luna_quantum/utils.py,sha256=RlF0LFK0qXavL22BSjMuNcGBGJrEL8mde_rAPX66qhw,137
258
- luna_quantum/utils.pyi,sha256=JbBq1V2SpGy4IbwqCQQKoJUM17LiTD35Wv8Im1YY1pw,2008
259
- luna_quantum-1.0.3rc3.dist-info/RECORD,,
259
+ luna_quantum/utils.pyi,sha256=TRV-THwZJdYDD5q3kn4W-p4dslim54xNJW0yFbXPFhs,2001
260
+ luna_quantum-1.0.4rc2.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: maturin (1.9.1)
2
+ Generator: maturin (1.9.3)
3
3
  Root-Is-Purelib: false
4
4
  Tag: cp311-cp311-win_amd64