luna-quantum 1.0.0__cp311-cp311-win_amd64.whl → 1.0.1__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.

Files changed (46) hide show
  1. luna_quantum/__init__.py +38 -17
  2. luna_quantum/__init__.pyi +29 -14
  3. luna_quantum/_core.cp311-win_amd64.pyd +0 -0
  4. luna_quantum/_core.pyi +1050 -377
  5. luna_quantum/algorithms/__init__.py +1 -0
  6. luna_quantum/backends/__init__.py +1 -0
  7. luna_quantum/client/rest_client/qpu_token_rest_client.py +7 -3
  8. luna_quantum/client/schemas/circuit.py +5 -6
  9. luna_quantum/client/schemas/create/__init__.py +10 -1
  10. luna_quantum/client/schemas/create/circuit.py +5 -6
  11. luna_quantum/client/schemas/create/qpu_token.py +2 -5
  12. luna_quantum/client/schemas/create/qpu_token_time_quota.py +3 -6
  13. luna_quantum/client/schemas/create/qpu_token_time_quota_update.py +15 -0
  14. luna_quantum/client/schemas/create/solve_job_create.py +1 -1
  15. luna_quantum/client/schemas/qpu_token/qpu_token.py +9 -16
  16. luna_quantum/client/schemas/qpu_token/token_provider.py +3 -6
  17. luna_quantum/errors.py +34 -1
  18. luna_quantum/errors.pyi +88 -26
  19. luna_quantum/solve/domain/solve_job.py +2 -2
  20. luna_quantum/solve/parameters/algorithms/base_params/quantum_annealing_params.py +1 -0
  21. luna_quantum/solve/parameters/algorithms/base_params/scipy_optimizer.py +4 -2
  22. luna_quantum/solve/parameters/algorithms/quantum_annealing/quantum_annealing.py +38 -22
  23. luna_quantum/solve/parameters/algorithms/quantum_gate/flex_qaoa/optimizers.py +4 -2
  24. luna_quantum/solve/parameters/algorithms/quantum_gate/qaoa.py +1 -3
  25. luna_quantum/solve/parameters/algorithms/quantum_gate/vqe.py +2 -3
  26. luna_quantum/solve/parameters/algorithms/search_algorithms/dialectic_search.py +0 -16
  27. luna_quantum/solve/parameters/backends/__init__.py +1 -1
  28. luna_quantum/solve/parameters/backends/dwave_qpu.py +4 -2
  29. luna_quantum/solve/parameters/backends/ibm.py +8 -2
  30. luna_quantum/solve/parameters/backends/qctrl.py +4 -3
  31. luna_quantum/solve/use_cases/hamiltonian_cycle.py +2 -2
  32. luna_quantum/solve/usecases/model_get_solution_usecase.py +4 -1
  33. luna_quantum/solve/usecases/solve_job_get_result_usecase.py +1 -3
  34. luna_quantum/transformations.py +18 -0
  35. luna_quantum/transformations.pyi +258 -0
  36. luna_quantum/translator.py +23 -1
  37. luna_quantum/translator.pyi +77 -44
  38. luna_quantum/util/debug_info.py +52 -0
  39. luna_quantum/util/log_utils.py +15 -11
  40. luna_quantum/utils.py +2 -53
  41. luna_quantum/utils.pyi +33 -1
  42. {luna_quantum-1.0.0.dist-info → luna_quantum-1.0.1.dist-info}/METADATA +2 -4
  43. {luna_quantum-1.0.0.dist-info → luna_quantum-1.0.1.dist-info}/RECORD +46 -40
  44. {luna_quantum-1.0.0.dist-info → luna_quantum-1.0.1.dist-info}/WHEEL +1 -1
  45. {luna_quantum-1.0.0.dist-info → luna_quantum-1.0.1.dist-info}/licenses/LICENSE +1 -1
  46. {luna_quantum-1.0.0.dist-info → luna_quantum-1.0.1.dist-info}/licenses/NOTICE +0 -0
@@ -14,14 +14,16 @@ class LinearOptimizerParams(ScipyOptimizerParams):
14
14
  ScipyOptimizer.
15
15
 
16
16
  Wrapper for scipy.optimize.minimize. See
17
- https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.minimize.html
17
+ [SciPy minimize documentation](
18
+ https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.minimize.html)
18
19
  for more information of the available methods and parameters.
19
20
 
20
21
  Attributes
21
22
  ----------
22
23
  method: ScipyOptimizerMethod
23
24
  Type of solver. See
24
- https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.minimize.html
25
+ [SciPy minimize documentation](
26
+ https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.minimize.html)
25
27
  for supported methods.
26
28
  tol: float | None
27
29
  Tolerance for termination.
@@ -39,9 +39,7 @@ class QAOA(LunaAlgorithm[AWS | IonQ | IQM | Rigetti | IBM]):
39
39
  optimizer : ScipyOptimizerParams | Dict
40
40
  Configuration for the classical optimization routine that updates the
41
41
  variational parameters. Default is a ScipyOptimizer instance with default
42
- settings. See ScipyOptimizer class or
43
- https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.minimize.html
44
- for details of contained parameters.
42
+ settings. See ScipyOptimizerParams class for details of contained parameters.
45
43
  initial_params: LinearQAOAParams | BasicQAOAParams | RandomQAOAParams | Dict
46
44
  Custom QAOA variational circuit parameters. By default linear
47
45
  increasing/decreasing parameters for the selected `reps` are generated.
@@ -40,9 +40,8 @@ class VQE(LunaAlgorithm[IBM]):
40
40
  optimizer : ScipyOptimizerParams | Dict
41
41
  Configuration for the classical optimization routine that updates the
42
42
  variational parameters. Default is a ScipyOptimizer instance with default
43
- settings. See ScipyOptimizer class or
44
- https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.minimize.html
45
- for details of contained parameters.
43
+ settings. See ScipyOptimizer Params class or for details
44
+ of contained parameters.
46
45
  initial_params_seed: int | None
47
46
  Seed for random number generator for intial params.
48
47
  initial_params_range: tuple[float, float]
@@ -72,22 +72,6 @@ class DialecticSearch(LunaAlgorithm[DWave]):
72
72
  decomposer: Decomposer
73
73
  Decomposer: Breaks down problems into subproblems of manageable size
74
74
  Default is a Decomposer instance with default settings.
75
-
76
- Notes
77
- -----
78
- The Dialectic Search algorithm operates through two distinct phases:
79
-
80
- 1. Antithesis: Generates a complementary solution designed to explore different
81
- regions of the solution space
82
- 2. Synthesis: Creates new solutions by exploring paths between thesis and antithesis
83
-
84
- Each phase uses tabu search with potentially different parameter settings to
85
- guide the exploration process. This approach is particularly effective for
86
- problems with complex landscapes containing many local optima.
87
-
88
- The algorithm uses D-Wave's backend technology to efficiently solve optimization
89
- problems. For more details on D-Wave solvers, see:
90
- https://docs.dwavesys.com/
91
75
  """
92
76
 
93
77
  antithesis_tabu_params: TabuSearchBaseParams = Field(
@@ -6,7 +6,7 @@ from .ibm import IBM
6
6
  from .qctrl import Qctrl
7
7
  from .zib import ZIB
8
8
 
9
- __all__ = [
9
+ __all__: list[str] = [
10
10
  "AWS",
11
11
  "IBM",
12
12
  "IQM",
@@ -19,10 +19,10 @@ class DWaveQpu(DWave, QpuTokenBackend):
19
19
 
20
20
  Attributes
21
21
  ----------
22
- embedding_parameters: Embedding | None, default=None
22
+ embedding_parameters: Embedding | AutoEmbedding | None
23
23
  Detailed configuration for manual embedding when not using auto-embedding.
24
24
  If None and decomposer is also None, default embedding parameters will be used.
25
- Ignored if decomposer is set to AutoEmbedding.
25
+ Ignored if decomposer is set to AutoEmbedding. Default is None.
26
26
  qpu_backend: str
27
27
  Specific D-Wave quantum processing unit (QPU) for your optimization
28
28
  """
@@ -76,8 +76,10 @@ class DWaveQpu(DWave, QpuTokenBackend):
76
76
 
77
77
  return_overlap: bool, default=False
78
78
  Controls return value format:
79
+
79
80
  - True: Returns (embedding, validity_flag) tuple
80
81
  - False: Returns only the embedding
82
+
81
83
  This function returns an embedding regardless of whether qubits are used by
82
84
  multiple variables.
83
85
 
@@ -25,7 +25,7 @@ class IBM(IBackend):
25
25
  """
26
26
 
27
27
  class SimulatorBackend(BaseModel):
28
- """Simulator.
28
+ """Qiskit Statevector Simulator.
29
29
 
30
30
  Use a simulator as backend. The QAOA is executed completely on our server, and
31
31
  no IBM token is required.
@@ -41,7 +41,13 @@ class IBM(IBackend):
41
41
  backend_name: Literal["aer", "statevector"] = "aer"
42
42
 
43
43
  class FakeProviderBackend(BaseModel):
44
- """FaleProvider.
44
+ """Simulator with emulated QPU noise model.
45
+
46
+ The Qiskit fake provider runs a simulation with a noise model derived from
47
+ an actual QPU hardware implementation.
48
+ See [IBM documentation](
49
+ https://docs.quantum.ibm.com/api/qiskit-ibm-runtime/fake-provider) for
50
+ available “fake” devices.
45
51
 
46
52
  Use a V2 fake backend from `qiskit_ibm_runtime.fake_provider`. The QAOA is
47
53
  executed entirely on our server, and no IBM token is required.
@@ -33,10 +33,10 @@ class Qctrl(QpuTokenBackend):
33
33
  - 'basic_simulator': Uses the basic simulator (default if None)
34
34
  Check your IBM Quantum account for available backends.
35
35
 
36
- ibm_credentials: QCtrl.IBMQ | QCtrl.IBMCloud, default=Qctrl.IBMQ()
36
+ ibm_credentials: IBMQ | IBMCloud
37
37
  The IBM backend credentials, i.e. how to access the IBM service. Q-Ctrl
38
38
  currently supports two mehtods, via the old IBMQ pattern or the new IBMCloud
39
- pattern.
39
+ pattern. Default is Qctrl.IBMQ()
40
40
 
41
41
  token: QpuToken | str | None, default=None
42
42
  The Q-Ctrl API token.
@@ -45,7 +45,8 @@ class Qctrl(QpuTokenBackend):
45
45
  Notes
46
46
  -----
47
47
  For detailed information about Fire Opal's QAOA solver and its capabilities,
48
- see Q-CTRL's documentation: https://docs.q-ctrl.com/fire-opal/topics/fire-opals-qaoa-solver
48
+ see [Q-CTRL's documentation](
49
+ https://docs.q-ctrl.com/fire-opal/topics/fire-opals-qaoa-solver)
49
50
  """
50
51
 
51
52
  class IBMQ(BaseModel):
@@ -1,6 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
- from typing import Final, Literal
3
+ from typing import Literal
4
4
 
5
5
  from pydantic import Field
6
6
 
@@ -46,4 +46,4 @@ class HamiltonianCycle(UseCase):
46
46
  graph: dict[str, dict[str, dict[str, float]]] = Field(name="graph") # type: ignore[call-overload]
47
47
  directed: bool | None = False
48
48
  A: float = 1.0
49
- B: Final[float] = 0.0
49
+ B: float = 0.0
@@ -1,6 +1,7 @@
1
1
  from luna_quantum._core import Solution
2
2
  from luna_quantum.aqm_overwrites import Model
3
3
  from luna_quantum.client.interfaces.services.luna_solve_i import ILunaSolve
4
+ from luna_quantum.client.schemas.enums.status import StatusEnum
4
5
  from luna_quantum.solve.interfaces.usecases.model_get_solutions_usecase_i import (
5
6
  IModelGetSolutionUseCase,
6
7
  )
@@ -52,5 +53,7 @@ class ModelGetSolutionUseCase(IModelGetSolutionUseCase):
52
53
 
53
54
  # TODO THIS IS SUPER INEFFICIENT # noqa: FIX002, TD002, TD004
54
55
  return [
55
- self.client.solve_job.get_solution(solve_job_id=s.id) for s in solve_jobs
56
+ self.client.solve_job.get_solution(solve_job_id=s.id)
57
+ for s in solve_jobs
58
+ if s.status is StatusEnum.DONE
56
59
  ]
@@ -82,9 +82,7 @@ class SolveJobGetResultUseCase(ISolveJobGetResultUseCase):
82
82
  return None
83
83
  if solve_job.status == StatusEnum.FAILED:
84
84
  self.logger.error(
85
- "Solve job is failed."
86
- " See 'error_message'"
87
- " field in solve job object for further information."
85
+ f"Solve job failed with the error '{solve_job.error_message}'."
88
86
  )
89
87
  return None
90
88
  aq_solution: Solution = self.client.solve_job.get_solution(
@@ -0,0 +1,18 @@
1
+ """Transformations collection.
2
+
3
+ The `transformations` module provides a collection of transformations for converting
4
+ between various representations of optimization problems and their solutions.
5
+
6
+ Transformations generally convert between different representations of an optimization
7
+ model. For example, changing the Sense of a model.
8
+
9
+ Each transformation encapsulates the logic needed for transforming a model to a desired
10
+ output model with changed properties and the logic to convert a solution of the output
11
+ model back to a solution representation matching the input model.
12
+
13
+ In addition to the predefined transformations contained in this module.
14
+ One can implement their own transformations by implementing the `TransformationPass`
15
+ and `AnalysisPass` abstract classes. See the examples for further details.
16
+ """
17
+
18
+ from ._core.transformations import * # type: ignore[reportMissingImports] # noqa: F403
@@ -0,0 +1,258 @@
1
+ from abc import abstractmethod
2
+ from enum import Enum
3
+ from typing import Any, Literal, overload
4
+
5
+ from aqmodels import Model, Sense, Solution, Timing, Vtype
6
+
7
+ class BasePass:
8
+ @property
9
+ def name(self) -> str:
10
+ """Get the name of this pass."""
11
+ ...
12
+ @property
13
+ def requires(self) -> list[str]:
14
+ """Get a list of required passes that need to be run before this pass."""
15
+ ...
16
+
17
+ class TransformationPass(BasePass):
18
+ @property
19
+ @abstractmethod
20
+ def name(self) -> str:
21
+ """Get the name of this pass."""
22
+ ...
23
+ @property
24
+ def requires(self) -> list[str]:
25
+ """Get a list of required passes that need to be run before this pass."""
26
+ ...
27
+ @property
28
+ def invalidates(self) -> list[str]:
29
+ """Get a list of passes that are invalidated by this pass."""
30
+ ...
31
+ @abstractmethod
32
+ def run(self, model: Model, cache: AnalysisCache) -> tuple[Model, ActionType]:
33
+ """Run/Execute this transformation pass."""
34
+ ...
35
+ @abstractmethod
36
+ def backwards(self, solution: Solution, cache: AnalysisCache) -> Solution:
37
+ """Convert a solution back to fit this pass' input.
38
+
39
+ Convert a solution from a representation fitting this pass' output to
40
+ a solution representation fitting this pass' input.
41
+ """
42
+ ...
43
+
44
+ class AnalysisCache:
45
+ @overload
46
+ def __getitem__( # type: ignore[reportOverlappingOverload]
47
+ self, key: Literal["max-bias"]
48
+ ) -> MaxBias: ...
49
+ @overload
50
+ def __getitem__(self, key: str) -> dict[Any, Any]: ...
51
+ def __getitem__(self, key: str) -> Any:
52
+ """Get the analysis result for a specific analysis pass."""
53
+ ...
54
+
55
+ class AnalysisPass(BasePass):
56
+ @property
57
+ @abstractmethod
58
+ def name(self) -> str:
59
+ """Get the name of this pass."""
60
+ ...
61
+ @property
62
+ def requires(self) -> list[str]:
63
+ """Get a list of required passes that need to be run before this pass."""
64
+ ...
65
+ @abstractmethod
66
+ def run(self, model: Model, cache: AnalysisCache) -> float:
67
+ """Run/Execute this analysis pass."""
68
+ ...
69
+
70
+ class ActionType(Enum):
71
+ DidTransform = ...
72
+ """Indicate that the pass did transform the model."""
73
+ DidAnalysis = ...
74
+ """Indicate that the pass did analyse the model."""
75
+ Nothing = ...
76
+ """Indicate that the pass did NOT do anything."""
77
+
78
+ class ChangeSensePass(BasePass):
79
+ """A transformation pass to change the model's Sense to a target Sense."""
80
+
81
+ def __init__(self, sense: Sense) -> None:
82
+ """Transform the model's Sense to a target Sense.
83
+
84
+ Parameters
85
+ ----------
86
+ sense : Sense
87
+ The target sense of the model after calling the `run` method on it.
88
+ """
89
+ ...
90
+ @property
91
+ def sense(self) -> Sense:
92
+ """Get the specified target sense of this pass."""
93
+ ...
94
+
95
+ class MaxBias:
96
+ """An analysis pass result storing the max bias (coefficient) of a model."""
97
+
98
+ @property
99
+ def val(self) -> float:
100
+ """Get the value of the maxium bias."""
101
+ ...
102
+
103
+ class MaxBiasAnalysis(BasePass):
104
+ """An analysis pass computing the maximum bias contained in the model."""
105
+
106
+ def __init__(self) -> None: ...
107
+
108
+ class BinarySpinAnalysis(BasePass):
109
+ """An analysis pass noting down which variables need to be transformed."""
110
+
111
+ def __init__(self, vtype: Literal[Vtype.Binary, Vtype.Spin]) -> None: ...
112
+ @property
113
+ def vtype(self) -> Vtype:
114
+ """Get the target vtype."""
115
+ ...
116
+
117
+ class BinarySpinInfo:
118
+ @property
119
+ def old_vtype(self) -> Vtype:
120
+ """Get the source vtype."""
121
+ ...
122
+
123
+ @property
124
+ def new_vtype(self) -> Vtype:
125
+ """Get the target vtype."""
126
+ ...
127
+
128
+ @property
129
+ def map(self) -> dict[str, str]:
130
+ """Get the variable name mapping."""
131
+ ...
132
+
133
+ class BinarySpinPass(BasePass):
134
+ """An transformation pass changing the denoted variables to target."""
135
+
136
+ def __init__(self) -> None: ...
137
+
138
+ class LogElement:
139
+ """An element of the execution log of an intermediate representation (IR)."""
140
+
141
+ @property
142
+ def pass_name(self) -> str:
143
+ """The name of the pass."""
144
+ ...
145
+
146
+ @property
147
+ def timing(self) -> Timing:
148
+ """Timing information for this log element."""
149
+ ...
150
+
151
+ @property
152
+ def kind(self) -> ActionType | None:
153
+ """Transformation type information for this log element, if available."""
154
+ ...
155
+
156
+ class IR:
157
+ """The intermediate representation (IR) of a model after transformation.
158
+
159
+ The IR contains the resulting model after transformation (`ir.model`) as well
160
+ as the analysis cache (`ir.cache`) and an execution log (`ir.execution_log`).
161
+ """
162
+
163
+ @property
164
+ def model(self) -> Model:
165
+ """Get the model stored in the IR."""
166
+ ...
167
+
168
+ @property
169
+ def cache(self) -> AnalysisCache:
170
+ """Get the analysis cache stored the IR."""
171
+ ...
172
+
173
+ @property
174
+ def execution_log(self) -> list[LogElement]:
175
+ """Get the analysis cache stored the IR."""
176
+ ...
177
+
178
+ class PassManager:
179
+ """Manage and execute a sequence of passes on a model.
180
+
181
+ The PassManager implements a compiler-style pass pattern, enabling both
182
+ general-purpose and algorithm-specific manipulations of optimization
183
+ models. Each pass is an atomic operation (for example, ChangeSensePass)
184
+ that transforms the model or its intermediate representation (IR). The
185
+ PassManager runs each pass in order and produces a rich IR that records
186
+ the transformations applied and supports back-transformations.
187
+ """
188
+
189
+ def __init__(
190
+ self, passes: list[BasePass | TransformationPass | AnalysisPass]
191
+ ) -> None:
192
+ """Manage and execute a sequence of passes on a model.
193
+
194
+ The PassManager implements a compiler-style pass pattern, enabling both
195
+ general-purpose and algorithm-specific manipulations of optimization
196
+ models. Each pass is an atomic operation (for example, ChangeSensePass)
197
+ that transforms the model or its intermediate representation (IR). The
198
+ PassManager runs each pass in order and produces a rich IR that records
199
+ the transformations applied and supports back-transformations.
200
+
201
+ Parameters
202
+ ----------
203
+ passes : list[TransformationPass | AnalysisPass]
204
+ An ordered sequence of Pass instances to apply. Each Pass must conform to
205
+ the `TransformationPass` or `AnalysisPass` interface.
206
+ """
207
+ ...
208
+
209
+ def run(self, model: Model) -> IR:
210
+ """Apply all configures passes.
211
+
212
+ Apply all configured passes to the given model and return the
213
+ resulting intermediate representation.
214
+
215
+ Parameters
216
+ ----------
217
+ model : Model
218
+ The model to be transformed.
219
+
220
+ Returns
221
+ -------
222
+ IR
223
+ The intermediate representation of the model after transformation.
224
+ """
225
+ ...
226
+
227
+ def backwards(self, solution: Solution, ir: IR) -> Solution:
228
+ """Apply the back transformation to the given solution.
229
+
230
+ Parameters
231
+ ----------
232
+ solution : Solution
233
+ The solution to transform back to a representation fitting the original
234
+ (input) model of this `PassManager`.
235
+ ir : IR
236
+ The intermediate representation (IR) resulted from the `run` call.
237
+
238
+ Returns
239
+ -------
240
+ Solution
241
+ A solution object representing a solution to the original problem passed
242
+ to this `PassManager`'s run method.
243
+ """
244
+ ...
245
+
246
+ __all__ = [
247
+ "IR",
248
+ "ActionType",
249
+ "AnalysisCache",
250
+ "AnalysisPass",
251
+ "BasePass",
252
+ "ChangeSensePass",
253
+ "LogElement",
254
+ "MaxBias",
255
+ "MaxBiasAnalysis",
256
+ "PassManager",
257
+ "TransformationPass",
258
+ ]
@@ -1 +1,23 @@
1
- from ._core.translator import * # type: ignore[reportMissingImports, import-not-found,unused-ignore] # noqa: F403
1
+ """Translator collection.
2
+
3
+ The `translator` module provides a collection of translators for converting between
4
+ various formats related to optimization problems and their solutions.
5
+
6
+ Translators are categorized into two main groups:
7
+
8
+ 1. **Model Translators**: These handle conversions *to* and *from* the internal `Model`
9
+ representation. They enable interoperability between external formats
10
+ (e.g., QUBO, LP) and the standardized internal model format used within the system.
11
+
12
+ 2. **Solution Translators**: These support conversion *from* external solution formats
13
+ into the internal `Solution` representation. This enables solutions generated by
14
+ different solvers or formats to be interpreted and processed consistently within
15
+ the system. Note that these translators do not support conversion *from* the internal
16
+ solution to external formats.
17
+
18
+ Each translator encapsulates the logic needed for bidirectional format conversion,
19
+ ensuring consistency and modularity when integrating with diverse optimization
20
+ frameworks and solvers.
21
+ """
22
+
23
+ from ._core.translator import * # type: ignore[reportMissingImports] # noqa: F403