luna-quantum 1.0.8rc2__cp314-cp314-macosx_11_0_arm64.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 (264) hide show
  1. luna_quantum/__init__.py +121 -0
  2. luna_quantum/__init__.pyi +85 -0
  3. luna_quantum/_core.cpython-314-darwin.so +0 -0
  4. luna_quantum/_core.pyi +4185 -0
  5. luna_quantum/algorithms/__init__.py +1 -0
  6. luna_quantum/aqm_overwrites/__init__.py +3 -0
  7. luna_quantum/aqm_overwrites/model.py +184 -0
  8. luna_quantum/backends/__init__.py +1 -0
  9. luna_quantum/client/__init__.py +0 -0
  10. luna_quantum/client/controllers/__init__.py +4 -0
  11. luna_quantum/client/controllers/luna_http_client.py +37 -0
  12. luna_quantum/client/controllers/luna_platform_client.py +256 -0
  13. luna_quantum/client/controllers/luna_q.py +67 -0
  14. luna_quantum/client/controllers/luna_solve.py +129 -0
  15. luna_quantum/client/error/__init__.py +0 -0
  16. luna_quantum/client/error/luna_api_key_invalid_error.py +10 -0
  17. luna_quantum/client/error/luna_api_key_missing_error.py +10 -0
  18. luna_quantum/client/error/luna_error.py +2 -0
  19. luna_quantum/client/error/luna_server_error.py +20 -0
  20. luna_quantum/client/error/timeout_error.py +12 -0
  21. luna_quantum/client/error/transformation_error.py +18 -0
  22. luna_quantum/client/error/utils/__init__.py +0 -0
  23. luna_quantum/client/error/utils/http_error_utils.py +112 -0
  24. luna_quantum/client/interfaces/__init__.py +4 -0
  25. luna_quantum/client/interfaces/clients/__init__.py +25 -0
  26. luna_quantum/client/interfaces/clients/circuit_rest_client_i.py +68 -0
  27. luna_quantum/client/interfaces/clients/info_rest_client_i.py +53 -0
  28. luna_quantum/client/interfaces/clients/model_rest_client_i.py +139 -0
  29. luna_quantum/client/interfaces/clients/qpu_token_rest_client_i.py +364 -0
  30. luna_quantum/client/interfaces/clients/rest_client_i.py +21 -0
  31. luna_quantum/client/interfaces/clients/solve_job_rest_client_i.py +201 -0
  32. luna_quantum/client/interfaces/clients/users_rest_client_i.py +29 -0
  33. luna_quantum/client/interfaces/services/__init__.py +0 -0
  34. luna_quantum/client/interfaces/services/luna_q_i.py +34 -0
  35. luna_quantum/client/interfaces/services/luna_solve_i.py +72 -0
  36. luna_quantum/client/interfaces/services/service_i.py +56 -0
  37. luna_quantum/client/rest_client/__init__.py +15 -0
  38. luna_quantum/client/rest_client/circuit_rest_client.py +107 -0
  39. luna_quantum/client/rest_client/info_rest_client.py +74 -0
  40. luna_quantum/client/rest_client/model_rest_client.py +216 -0
  41. luna_quantum/client/rest_client/qpu_token_rest_client.py +508 -0
  42. luna_quantum/client/rest_client/solve_job_rest_client.py +286 -0
  43. luna_quantum/client/rest_client/users_rest_client.py +35 -0
  44. luna_quantum/client/schemas/__init__.py +26 -0
  45. luna_quantum/client/schemas/circuit.py +48 -0
  46. luna_quantum/client/schemas/create/__init__.py +15 -0
  47. luna_quantum/client/schemas/create/circuit.py +30 -0
  48. luna_quantum/client/schemas/create/optimization.py +39 -0
  49. luna_quantum/client/schemas/create/qpu_token.py +22 -0
  50. luna_quantum/client/schemas/create/qpu_token_time_quota.py +35 -0
  51. luna_quantum/client/schemas/create/qpu_token_time_quota_update.py +24 -0
  52. luna_quantum/client/schemas/create/qubo.py +19 -0
  53. luna_quantum/client/schemas/create/solve_job_create.py +43 -0
  54. luna_quantum/client/schemas/enums/__init__.py +0 -0
  55. luna_quantum/client/schemas/enums/call_style.py +13 -0
  56. luna_quantum/client/schemas/enums/circuit.py +42 -0
  57. luna_quantum/client/schemas/enums/model_format.py +11 -0
  58. luna_quantum/client/schemas/enums/problem.py +50 -0
  59. luna_quantum/client/schemas/enums/qpu_token_type.py +20 -0
  60. luna_quantum/client/schemas/enums/sense.py +8 -0
  61. luna_quantum/client/schemas/enums/status.py +40 -0
  62. luna_quantum/client/schemas/enums/timeframe.py +11 -0
  63. luna_quantum/client/schemas/error_message.py +14 -0
  64. luna_quantum/client/schemas/model_metadata.py +35 -0
  65. luna_quantum/client/schemas/qpu_token/__init__.py +0 -0
  66. luna_quantum/client/schemas/qpu_token/qpu_token.py +154 -0
  67. luna_quantum/client/schemas/qpu_token/qpu_token_source.py +19 -0
  68. luna_quantum/client/schemas/qpu_token/qpu_token_time_quota.py +30 -0
  69. luna_quantum/client/schemas/qpu_token/token_provider.py +132 -0
  70. luna_quantum/client/schemas/representation.py +19 -0
  71. luna_quantum/client/schemas/solution.py +106 -0
  72. luna_quantum/client/schemas/solve_job.py +50 -0
  73. luna_quantum/client/schemas/solver_info.py +11 -0
  74. luna_quantum/client/schemas/user.py +11 -0
  75. luna_quantum/client/schemas/wrappers/__init__.py +5 -0
  76. luna_quantum/client/schemas/wrappers/datetime_wrapper.py +32 -0
  77. luna_quantum/client/utils/__init__.py +0 -0
  78. luna_quantum/client/utils/qpu_token_utils.py +147 -0
  79. luna_quantum/config.py +11 -0
  80. luna_quantum/decorators.py +248 -0
  81. luna_quantum/errors.py +34 -0
  82. luna_quantum/errors.pyi +287 -0
  83. luna_quantum/exceptions/__init__.py +0 -0
  84. luna_quantum/exceptions/base_luna_quantum_error.py +2 -0
  85. luna_quantum/exceptions/patch_class_field_exists_error.py +10 -0
  86. luna_quantum/factories/__init__.py +4 -0
  87. luna_quantum/factories/luna_solve_client_factory.py +100 -0
  88. luna_quantum/factories/usecase_factory.py +457 -0
  89. luna_quantum/py.typed +0 -0
  90. luna_quantum/solve/__init__.py +13 -0
  91. luna_quantum/solve/default_token.py +304 -0
  92. luna_quantum/solve/domain/__init__.py +0 -0
  93. luna_quantum/solve/domain/abstract/__init__.py +4 -0
  94. luna_quantum/solve/domain/abstract/luna_algorithm.py +205 -0
  95. luna_quantum/solve/domain/abstract/qpu_token_backend.py +34 -0
  96. luna_quantum/solve/domain/model_metadata.py +56 -0
  97. luna_quantum/solve/domain/solve_job.py +196 -0
  98. luna_quantum/solve/errors/__init__.py +0 -0
  99. luna_quantum/solve/errors/incompatible_backend_error.py +15 -0
  100. luna_quantum/solve/errors/model_metadata_missing_error.py +11 -0
  101. luna_quantum/solve/errors/solve_base_error.py +5 -0
  102. luna_quantum/solve/errors/token_missing_error.py +11 -0
  103. luna_quantum/solve/interfaces/__init__.py +0 -0
  104. luna_quantum/solve/interfaces/algorithm_i.py +49 -0
  105. luna_quantum/solve/interfaces/backend_i.py +28 -0
  106. luna_quantum/solve/interfaces/usecases/__init__.py +55 -0
  107. luna_quantum/solve/interfaces/usecases/model_delete_usecase_i.py +27 -0
  108. luna_quantum/solve/interfaces/usecases/model_fetch_metadata_usecase_i.py +33 -0
  109. luna_quantum/solve/interfaces/usecases/model_get_solutions_usecase_i.py +33 -0
  110. luna_quantum/solve/interfaces/usecases/model_get_solve_jobs_usecase_i.py +33 -0
  111. luna_quantum/solve/interfaces/usecases/model_load_by_id_usecase_i.py +32 -0
  112. luna_quantum/solve/interfaces/usecases/model_load_by_metadata_usecase_i.py +37 -0
  113. luna_quantum/solve/interfaces/usecases/model_load_metadata_by_hash_usecase_i.py +38 -0
  114. luna_quantum/solve/interfaces/usecases/model_save_usecase_i.py +36 -0
  115. luna_quantum/solve/interfaces/usecases/solve_job_cancel_usecase_i.py +33 -0
  116. luna_quantum/solve/interfaces/usecases/solve_job_create_usecase_i.py +44 -0
  117. luna_quantum/solve/interfaces/usecases/solve_job_delete_usecase_i.py +32 -0
  118. luna_quantum/solve/interfaces/usecases/solve_job_fetch_updates_usecase_i.py +38 -0
  119. luna_quantum/solve/interfaces/usecases/solve_job_get_result_usecase_i.py +63 -0
  120. luna_quantum/solve/parameters/__init__.py +0 -0
  121. luna_quantum/solve/parameters/algorithms/__init__.py +51 -0
  122. luna_quantum/solve/parameters/algorithms/base_params/__init__.py +24 -0
  123. luna_quantum/solve/parameters/algorithms/base_params/decomposer.py +57 -0
  124. luna_quantum/solve/parameters/algorithms/base_params/qaoa_circuit_params.py +95 -0
  125. luna_quantum/solve/parameters/algorithms/base_params/quantum_annealing_params.py +79 -0
  126. luna_quantum/solve/parameters/algorithms/base_params/scipy_optimizer.py +122 -0
  127. luna_quantum/solve/parameters/algorithms/base_params/simulated_annealing_params.py +106 -0
  128. luna_quantum/solve/parameters/algorithms/base_params/tabu_kerberos_params.py +39 -0
  129. luna_quantum/solve/parameters/algorithms/base_params/tabu_search_params.py +129 -0
  130. luna_quantum/solve/parameters/algorithms/flexible_parameter_algorithm.py +59 -0
  131. luna_quantum/solve/parameters/algorithms/genetic_algorithms/__init__.py +4 -0
  132. luna_quantum/solve/parameters/algorithms/genetic_algorithms/qaga.py +131 -0
  133. luna_quantum/solve/parameters/algorithms/genetic_algorithms/saga.py +139 -0
  134. luna_quantum/solve/parameters/algorithms/lq_fda/__init__.py +3 -0
  135. luna_quantum/solve/parameters/algorithms/lq_fda/fujits_da_base.py +85 -0
  136. luna_quantum/solve/parameters/algorithms/lq_fda/fujitsu_da_v3c.py +155 -0
  137. luna_quantum/solve/parameters/algorithms/optimization_solvers/__init__.py +3 -0
  138. luna_quantum/solve/parameters/algorithms/optimization_solvers/scip.py +51 -0
  139. luna_quantum/solve/parameters/algorithms/quantum_annealing/__init__.py +19 -0
  140. luna_quantum/solve/parameters/algorithms/quantum_annealing/kerberos.py +149 -0
  141. luna_quantum/solve/parameters/algorithms/quantum_annealing/leap_hybrid_bqm.py +75 -0
  142. luna_quantum/solve/parameters/algorithms/quantum_annealing/leap_hybrid_cqm.py +75 -0
  143. luna_quantum/solve/parameters/algorithms/quantum_annealing/parallel_tempering_qpu.py +139 -0
  144. luna_quantum/solve/parameters/algorithms/quantum_annealing/population_annealing_qpu.py +109 -0
  145. luna_quantum/solve/parameters/algorithms/quantum_annealing/qbsolv_like_qpu.py +111 -0
  146. luna_quantum/solve/parameters/algorithms/quantum_annealing/quantum_annealing.py +121 -0
  147. luna_quantum/solve/parameters/algorithms/quantum_annealing/repeated_reverse_quantum_annealing.py +174 -0
  148. luna_quantum/solve/parameters/algorithms/quantum_gate/__init__.py +6 -0
  149. luna_quantum/solve/parameters/algorithms/quantum_gate/flex_qaoa/__init__.py +26 -0
  150. luna_quantum/solve/parameters/algorithms/quantum_gate/flex_qaoa/config.py +80 -0
  151. luna_quantum/solve/parameters/algorithms/quantum_gate/flex_qaoa/flex_qaoa.py +226 -0
  152. luna_quantum/solve/parameters/algorithms/quantum_gate/flex_qaoa/optimizers.py +99 -0
  153. luna_quantum/solve/parameters/algorithms/quantum_gate/flex_qaoa/pipeline.py +87 -0
  154. luna_quantum/solve/parameters/algorithms/quantum_gate/qaoa.py +102 -0
  155. luna_quantum/solve/parameters/algorithms/quantum_gate/qaoa_fo.py +69 -0
  156. luna_quantum/solve/parameters/algorithms/quantum_gate/vqe.py +108 -0
  157. luna_quantum/solve/parameters/algorithms/search_algorithms/__init__.py +5 -0
  158. luna_quantum/solve/parameters/algorithms/search_algorithms/dialectic_search.py +136 -0
  159. luna_quantum/solve/parameters/algorithms/search_algorithms/qbsolv_like_tabu_search.py +117 -0
  160. luna_quantum/solve/parameters/algorithms/search_algorithms/tabu_search.py +126 -0
  161. luna_quantum/solve/parameters/algorithms/simulated_annealing/__init__.py +13 -0
  162. luna_quantum/solve/parameters/algorithms/simulated_annealing/parallel_tempering.py +131 -0
  163. luna_quantum/solve/parameters/algorithms/simulated_annealing/population_annealing.py +95 -0
  164. luna_quantum/solve/parameters/algorithms/simulated_annealing/qbsolv_like_simulated_annealing.py +141 -0
  165. luna_quantum/solve/parameters/algorithms/simulated_annealing/repeated_reverse_simulated_annealing.py +172 -0
  166. luna_quantum/solve/parameters/algorithms/simulated_annealing/simulated_annealing.py +126 -0
  167. luna_quantum/solve/parameters/backends/__init__.py +22 -0
  168. luna_quantum/solve/parameters/backends/aqarios.py +17 -0
  169. luna_quantum/solve/parameters/backends/aws/__init__.py +11 -0
  170. luna_quantum/solve/parameters/backends/aws/aws.py +36 -0
  171. luna_quantum/solve/parameters/backends/aws/aws_backend_base.py +74 -0
  172. luna_quantum/solve/parameters/backends/aws/ionq.py +43 -0
  173. luna_quantum/solve/parameters/backends/aws/iqm.py +31 -0
  174. luna_quantum/solve/parameters/backends/aws/rigetti.py +31 -0
  175. luna_quantum/solve/parameters/backends/dwave.py +17 -0
  176. luna_quantum/solve/parameters/backends/dwave_qpu.py +166 -0
  177. luna_quantum/solve/parameters/backends/fda.py +17 -0
  178. luna_quantum/solve/parameters/backends/ibm.py +138 -0
  179. luna_quantum/solve/parameters/backends/qctrl.py +103 -0
  180. luna_quantum/solve/parameters/backends/zib.py +17 -0
  181. luna_quantum/solve/parameters/constants.py +11 -0
  182. luna_quantum/solve/parameters/mixins/__init__.py +0 -0
  183. luna_quantum/solve/parameters/mixins/fujitsu_common_params_mixin.py +239 -0
  184. luna_quantum/solve/parameters/mixins/fujitsu_v2_mixin.py +70 -0
  185. luna_quantum/solve/parameters/mixins/qbsolv_like_mixin.py +60 -0
  186. luna_quantum/solve/use_cases/__init__.py +119 -0
  187. luna_quantum/solve/use_cases/arbitrage_edge_based.py +50 -0
  188. luna_quantum/solve/use_cases/arbitrage_node_based.py +55 -0
  189. luna_quantum/solve/use_cases/base.py +7 -0
  190. luna_quantum/solve/use_cases/binary_integer_linear_programming.py +54 -0
  191. luna_quantum/solve/use_cases/binary_paint_shop_problem.py +37 -0
  192. luna_quantum/solve/use_cases/credit_scoring_feature_selection.py +40 -0
  193. luna_quantum/solve/use_cases/dynamic_portfolio_optimization.py +64 -0
  194. luna_quantum/solve/use_cases/exact_cover.py +51 -0
  195. luna_quantum/solve/use_cases/flight_gate_assignment.py +79 -0
  196. luna_quantum/solve/use_cases/graph_coloring.py +42 -0
  197. luna_quantum/solve/use_cases/graph_isomorphism.py +52 -0
  198. luna_quantum/solve/use_cases/graph_partitioning.py +46 -0
  199. luna_quantum/solve/use_cases/hamiltonian_cycle.py +49 -0
  200. luna_quantum/solve/use_cases/induced_subgraph_isomorphism.py +50 -0
  201. luna_quantum/solve/use_cases/job_shop_scheduling.py +44 -0
  202. luna_quantum/solve/use_cases/k_medoids_clustering.py +49 -0
  203. luna_quantum/solve/use_cases/knapsack_integer_weights.py +56 -0
  204. luna_quantum/solve/use_cases/linear_regression.py +60 -0
  205. luna_quantum/solve/use_cases/lmwcs.py +84 -0
  206. luna_quantum/solve/use_cases/longest_path.py +50 -0
  207. luna_quantum/solve/use_cases/market_graph_clustering.py +61 -0
  208. luna_quantum/solve/use_cases/max2sat.py +54 -0
  209. luna_quantum/solve/use_cases/max3sat.py +55 -0
  210. luna_quantum/solve/use_cases/max_clique.py +60 -0
  211. luna_quantum/solve/use_cases/max_cut.py +48 -0
  212. luna_quantum/solve/use_cases/max_independent_set.py +37 -0
  213. luna_quantum/solve/use_cases/minimal_maximal_matching.py +54 -0
  214. luna_quantum/solve/use_cases/minimal_spanning_tree.py +90 -0
  215. luna_quantum/solve/use_cases/minimum_vertex_cover.py +45 -0
  216. luna_quantum/solve/use_cases/number_partitioning.py +32 -0
  217. luna_quantum/solve/use_cases/portfolio_optimization.py +46 -0
  218. luna_quantum/solve/use_cases/portfolio_optimization_ib_tv.py +63 -0
  219. luna_quantum/solve/use_cases/quadratic_assignment.py +49 -0
  220. luna_quantum/solve/use_cases/quadratic_knapsack.py +48 -0
  221. luna_quantum/solve/use_cases/satellite_scheduling.py +73 -0
  222. luna_quantum/solve/use_cases/sensor_placement.py +58 -0
  223. luna_quantum/solve/use_cases/set_cover.py +56 -0
  224. luna_quantum/solve/use_cases/set_packing.py +54 -0
  225. luna_quantum/solve/use_cases/set_partitioning.py +52 -0
  226. luna_quantum/solve/use_cases/subgraph_isomorphism.py +55 -0
  227. luna_quantum/solve/use_cases/subset_sum.py +37 -0
  228. luna_quantum/solve/use_cases/support_vector_machine.py +64 -0
  229. luna_quantum/solve/use_cases/traffic_flow.py +35 -0
  230. luna_quantum/solve/use_cases/travelling_salesman_problem.py +53 -0
  231. luna_quantum/solve/use_cases/type_aliases.py +9 -0
  232. luna_quantum/solve/use_cases/weighted_max_cut.py +37 -0
  233. luna_quantum/solve/usecases/__init__.py +45 -0
  234. luna_quantum/solve/usecases/model_delete_usecase.py +49 -0
  235. luna_quantum/solve/usecases/model_fetch_metadata_usecase.py +50 -0
  236. luna_quantum/solve/usecases/model_get_solution_usecase.py +59 -0
  237. luna_quantum/solve/usecases/model_get_solve_jobs_usecase.py +62 -0
  238. luna_quantum/solve/usecases/model_load_by_id_usecase.py +47 -0
  239. luna_quantum/solve/usecases/model_load_by_metadata_usecase.py +52 -0
  240. luna_quantum/solve/usecases/model_load_metadata_by_hash_usecase.py +51 -0
  241. luna_quantum/solve/usecases/model_save_usecase.py +63 -0
  242. luna_quantum/solve/usecases/solve_job_cancel_usecase.py +51 -0
  243. luna_quantum/solve/usecases/solve_job_create_usecase.py +112 -0
  244. luna_quantum/solve/usecases/solve_job_delete_usecase.py +38 -0
  245. luna_quantum/solve/usecases/solve_job_fetch_updates_usecase.py +49 -0
  246. luna_quantum/solve/usecases/solve_job_get_result_usecase.py +95 -0
  247. luna_quantum/transformations.py +18 -0
  248. luna_quantum/transformations.pyi +371 -0
  249. luna_quantum/translator.py +23 -0
  250. luna_quantum/translator.pyi +869 -0
  251. luna_quantum/util/__init__.py +0 -0
  252. luna_quantum/util/active_waiting.py +79 -0
  253. luna_quantum/util/class_patcher.py +164 -0
  254. luna_quantum/util/debug_info.py +52 -0
  255. luna_quantum/util/log_utils.py +187 -0
  256. luna_quantum/util/pretty_base.py +67 -0
  257. luna_quantum/util/pydantic_utils.py +38 -0
  258. luna_quantum/utils.py +3 -0
  259. luna_quantum/utils.pyi +67 -0
  260. luna_quantum-1.0.8rc2.dist-info/METADATA +36 -0
  261. luna_quantum-1.0.8rc2.dist-info/RECORD +264 -0
  262. luna_quantum-1.0.8rc2.dist-info/WHEEL +4 -0
  263. luna_quantum-1.0.8rc2.dist-info/licenses/LICENSE +176 -0
  264. luna_quantum-1.0.8rc2.dist-info/licenses/NOTICE +13 -0
@@ -0,0 +1,80 @@
1
+ from typing import Literal
2
+
3
+ from pydantic import BaseModel, Field, field_validator
4
+
5
+ from luna_quantum.solve.errors.solve_base_error import SolveBaseError
6
+
7
+
8
+ class MixerTypeError(SolveBaseError):
9
+ """Custom Mixer type exception."""
10
+
11
+ def __init__(self) -> None:
12
+ super().__init__("XY-mixer type can only occur once.")
13
+
14
+
15
+ class XYMixer(BaseModel):
16
+ """XY-mixer configuration.
17
+
18
+ Attributes
19
+ ----------
20
+ types: list[Literal["even", "odd", "last"]]
21
+ XY-ring-mixer pipeline
22
+ """
23
+
24
+ types: list[Literal["even", "odd", "last"]] = Field(
25
+ default=["even", "odd", "last"],
26
+ description="XY-ring-mixer types and order.",
27
+ )
28
+
29
+ @field_validator("types")
30
+ @classmethod
31
+ def _validate_type_once(
32
+ cls, v: list[Literal["even", "odd", "last"]]
33
+ ) -> list[Literal["even", "odd", "last"]]:
34
+ if len(set(v)) < len(v):
35
+ raise MixerTypeError
36
+ return v
37
+
38
+
39
+ class AdvancedConfig(BaseModel):
40
+ """Additional FlexQAOA algorithm configuration.
41
+
42
+ Attributes
43
+ ----------
44
+ mixer: XYMixer | Dict
45
+ Mixer types in XY-ring-mixer. Default: `["even", "odd", "last"]`
46
+ parallel_indicators: bool
47
+ Toggle to apply indicator functions in parallel. Does not affect sampling
48
+ performance of QAOA, but only circuit metrics, like number of qubits and
49
+ circuit depth.
50
+ discard_slack: bool
51
+ Discard slack qubits in evaluation, i.e. only measure on the binary variables of
52
+ the initial problem. This requires an auxilary cost function that penalizes
53
+ infeasible solutions.
54
+ infeas_penalty: float | None
55
+ Penalty for infeasible solutions if `discard_slack` is activated. By defalt,
56
+ 10 times the max absolute intial bias is chosen.
57
+ """
58
+
59
+ mixer: XYMixer = Field(
60
+ default_factory=lambda: XYMixer(),
61
+ description='Mixer types in XY-ring-mixer. Default: `["even", "odd", "last"]`',
62
+ )
63
+ parallel_indicators: bool = Field(
64
+ default=True,
65
+ description="Toggle to apply indicator functions in parallel. Does not affect "
66
+ "sampling performance of QAOA, but only circuit metrics, "
67
+ "like number of qubits and circuit depth.",
68
+ )
69
+ discard_slack: bool = Field(
70
+ default=False,
71
+ description="Discard slack qubits in evaluation, i.e. only measure on the "
72
+ "binary variables of the initial problem. This requires an auxilary cost "
73
+ "function that penalizes infeasible solutions.",
74
+ )
75
+ infeas_penalty: float | None = Field(
76
+ default=None,
77
+ ge=0,
78
+ description="Penalty for infeasible solutions if `discard_slack` is activated."
79
+ "By defalt, 10 times the max absolute intial bias is chosen.",
80
+ )
@@ -0,0 +1,226 @@
1
+ from __future__ import annotations
2
+
3
+ from pydantic import BaseModel, Field, model_validator
4
+
5
+ from luna_quantum.solve.domain.abstract.luna_algorithm import LunaAlgorithm
6
+ from luna_quantum.solve.errors.solve_base_error import SolveBaseError
7
+ from luna_quantum.solve.parameters.algorithms.base_params.qaoa_circuit_params import (
8
+ BasicQAOAParams,
9
+ LinearQAOAParams,
10
+ RandomQAOAParams,
11
+ )
12
+ from luna_quantum.solve.parameters.algorithms.base_params.scipy_optimizer import (
13
+ ScipyOptimizerParams,
14
+ )
15
+ from luna_quantum.solve.parameters.backends.aqarios import Aqarios
16
+
17
+ from .config import AdvancedConfig
18
+ from .optimizers import (
19
+ CombinedOptimizerParams,
20
+ InterpolateOptimizerParams,
21
+ LinearOptimizerParams,
22
+ )
23
+ from .pipeline import PipelineParams
24
+
25
+
26
+ class QAOAParameterOptimizerError(SolveBaseError):
27
+ """QAOA cirucit parameters mismatch with optimizer exception."""
28
+
29
+ def __init__(
30
+ self,
31
+ optimizer: ScipyOptimizerParams
32
+ | LinearOptimizerParams
33
+ | CombinedOptimizerParams
34
+ | InterpolateOptimizerParams
35
+ | None,
36
+ params: BasicQAOAParams | LinearQAOAParams | RandomQAOAParams,
37
+ extra: str = "",
38
+ ) -> None:
39
+ super().__init__(
40
+ f"Parameter Mismatch of {optimizer.__class__} and {params.__class__}"
41
+ + ((". " + extra) if extra else "")
42
+ )
43
+
44
+
45
+ class InterpolateOptimizerError(SolveBaseError):
46
+ """Interpolate optimizer error when final number of reps is too small."""
47
+
48
+ def __init__(self, reps_end: int, reps_start: int) -> None:
49
+ super().__init__(f"{reps_end=} needs to be larger than {reps_start=}.")
50
+
51
+
52
+ class QAOAParameterDepthMismatchError(SolveBaseError):
53
+ """QAOA circuit params mismatch the specified reps."""
54
+
55
+ def __init__(self, params_reps: int, reps: int) -> None:
56
+ super().__init__(f"{params_reps=} needs to match {reps=}.")
57
+
58
+
59
+ class FlexQAOA(LunaAlgorithm[Aqarios], BaseModel):
60
+ """The FlexQAOA Algorithm for constrained quantum optimization.
61
+
62
+ The FlexQAOA is an extension to the default QAOA with the capabilities to encode
63
+ inequality constriants with indicator functions as well as one-hot constraints
64
+ through XY-mixers. This algorithm will dynamically extract all constraints from the
65
+ given constraint input optimization model, and construct an accoring QAOA circuit.
66
+ Currently only simulation of the circuit is supported. But due to the constrained
67
+ nature, the subspace of the Hilbertspace required for simulation is smaller,
68
+ depending on the problem instance. This allows for simulation of problems with
69
+ more qubits than ordinary state vector simulation allows. For now, the simulation
70
+ size is limited to Hilbertspaces with less <= 2**18 dimensions.
71
+
72
+ The FlexQAOA allows for a dynamic circuit construction depending on input paramters.
73
+ Central to this is the pipeline parameter which allows for different configurations.
74
+
75
+ For instance, if one likes to explore ordinary QUBO simulation with all constraints
76
+ represented as quadratic penalties, the `one_hot` and `indicator_function` options
77
+ need to be manually disabled
78
+ ```
79
+ pipeline = {"one_hot": None, "indicator_function": None}
80
+ ```
81
+
82
+ If no indicator function is employed, but the input problem contains inequality
83
+ constraints, slack variables are added to the optimization problem. FlexQAOA allows
84
+ for a configuration that discards slack variables as their assignment is not
85
+ necessarily of interest. This option can be enbled by setting
86
+ ```
87
+ qaoa_config = {"discard_slack": True}
88
+ ```
89
+
90
+ Following the standard protocol for QAOA, a classical optimizer is required that
91
+ tunes the variational parameters of the circuit. Besides the classical
92
+ `ScipyOptimizer` other optimizers are also featured, allowing for optimizing only a
93
+ linear schedule, starting with optimizing for a linear schedule followed by
94
+ individual parameter fine tuning, and interpolating between different QAOA circuit
95
+ depts.
96
+
97
+ Attributes
98
+ ----------
99
+ shots: int
100
+ Number of sampled shots.
101
+ reps: int
102
+ Number of QAOA layer repetitions
103
+ pipeline: PipelineParams | Dict
104
+ The pipeline defines the selected features for QAOA circuit generation. By
105
+ default, all supported features are enabled (one-hot constraints, inequality
106
+ constraints and quadratic penalties).
107
+ optimizer: ScipyOptimizerParams | LinearOptimizerParams | CombinedOptimizerParams |\
108
+ InterpolateOptimizerParams | None | Dict
109
+ The classical optimizer for parameter tuning. Default: ScipyOptimizer. Setting
110
+ to `None` disables the optimization, leading to an evaluation of the initial
111
+ parameters.
112
+ qaoa_config: AdvancedConfig | Dict
113
+ Additional options for the QAOA circuit and evalutation
114
+ initial_params: LinearQAOAParams | BasicQAOAParams | RandomQAOAParams | Dict
115
+ Custom QAOA variational circuit parameters. By default linear
116
+ increasing/decreasing parameters for the selected `reps` are generated.
117
+ """
118
+
119
+ shots: int = Field(default=1024, ge=1, description="Number of sampled shots.")
120
+ reps: int = Field(default=1, ge=1, description="Number of QAOA layer repetitions")
121
+ pipeline: PipelineParams = Field(
122
+ default_factory=lambda: PipelineParams(),
123
+ description="The pipeline defines the selected features for QAOA circuit "
124
+ "generation. By default, all supported features are enabled "
125
+ "(one-hot constraints, inequality constraints and quadratic penalties).",
126
+ )
127
+ optimizer: (
128
+ ScipyOptimizerParams
129
+ | LinearOptimizerParams
130
+ | CombinedOptimizerParams
131
+ | InterpolateOptimizerParams
132
+ | None
133
+ ) = Field(
134
+ default_factory=lambda: ScipyOptimizerParams(),
135
+ description="The classical optimizer. Default: ScipyOptimizer",
136
+ )
137
+ qaoa_config: AdvancedConfig = Field(
138
+ default_factory=lambda: AdvancedConfig(),
139
+ description="Additional options for the QAOA circuit and evalutation",
140
+ )
141
+ initial_params: LinearQAOAParams | BasicQAOAParams | RandomQAOAParams = Field(
142
+ default_factory=lambda: LinearQAOAParams(delta_beta=0.5, delta_gamma=0.5),
143
+ description="Custom QAOA circuit parameters. By default linear "
144
+ "increasing/decreasing parameters for the selected `reps` are generated.",
145
+ )
146
+
147
+ @model_validator(mode="after")
148
+ def _check_param_type(self) -> FlexQAOA:
149
+ if isinstance(self.optimizer, LinearOptimizerParams) and isinstance(
150
+ self.initial_params, BasicQAOAParams
151
+ ):
152
+ raise QAOAParameterOptimizerError(self.optimizer, self.initial_params)
153
+ if isinstance(self.optimizer, CombinedOptimizerParams) and isinstance(
154
+ self.initial_params, BasicQAOAParams
155
+ ):
156
+ raise QAOAParameterOptimizerError(self.optimizer, self.initial_params)
157
+ if (
158
+ isinstance(self.optimizer, InterpolateOptimizerParams)
159
+ and isinstance(self.optimizer.optimizer, LinearOptimizerParams)
160
+ and isinstance(self.initial_params, BasicQAOAParams)
161
+ ):
162
+ raise QAOAParameterOptimizerError(
163
+ self.optimizer,
164
+ self.initial_params,
165
+ extra="LinearOptimizer used in InterpolateOptimizer.",
166
+ )
167
+ if (
168
+ isinstance(self.optimizer, InterpolateOptimizerParams)
169
+ and self.optimizer.reps_end < self.reps
170
+ ):
171
+ raise InterpolateOptimizerError(self.optimizer.reps_end, self.reps)
172
+ return self
173
+
174
+ @model_validator(mode="after")
175
+ def _check_depth(self) -> FlexQAOA:
176
+ if (
177
+ isinstance(self.initial_params, BasicQAOAParams)
178
+ and self.initial_params.reps != self.reps
179
+ ):
180
+ raise QAOAParameterDepthMismatchError(self.initial_params.reps, self.reps)
181
+ return self
182
+
183
+ @property
184
+ def algorithm_name(self) -> str:
185
+ """
186
+ Returns the name of the algorithm.
187
+
188
+ This abstract property method is intended to be overridden by subclasses.
189
+ It should provide the name of the algorithm being implemented.
190
+
191
+ Returns
192
+ -------
193
+ str
194
+ The name of the algorithm.
195
+ """
196
+ return "FlexQAOA"
197
+
198
+ @classmethod
199
+ def get_default_backend(cls) -> Aqarios:
200
+ """
201
+ Return the default backend implementation.
202
+
203
+ This property must be implemented by subclasses to provide
204
+ the default backend instance to use when no specific backend
205
+ is specified.
206
+
207
+ Returns
208
+ -------
209
+ IBackend
210
+ An instance of a class implementing the IBackend interface that serves
211
+ as the default backend.
212
+ """
213
+ return Aqarios()
214
+
215
+ @classmethod
216
+ def get_compatible_backends(cls) -> tuple[type[Aqarios]]:
217
+ """
218
+ Check at runtime if the used backend is compatible with the solver.
219
+
220
+ Returns
221
+ -------
222
+ tuple[type[IBackend], ...]
223
+ True if the backend is compatible with the solver, False otherwise.
224
+
225
+ """
226
+ return (Aqarios,)
@@ -0,0 +1,99 @@
1
+ from typing import Literal
2
+
3
+ from pydantic import BaseModel, Field
4
+
5
+ from luna_quantum.solve.parameters.algorithms.base_params.scipy_optimizer import (
6
+ ScipyOptimizerParams,
7
+ )
8
+
9
+
10
+ class LinearOptimizerParams(ScipyOptimizerParams):
11
+ """Optimizer for tuning a linear schedule of QAOA parameters.
12
+
13
+ Optimizes onyl two parameters: `delta_beta` and `delta_gamma` with the default
14
+ ScipyOptimizer.
15
+
16
+ Wrapper for scipy.optimize.minimize. See
17
+ [SciPy minimize documentation](
18
+ https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.minimize.html)
19
+ for more information of the available methods and parameters.
20
+
21
+ Attributes
22
+ ----------
23
+ method: ScipyOptimizerMethod
24
+ Type of solver. See
25
+ [SciPy minimize documentation](
26
+ https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.minimize.html)
27
+ for supported methods.
28
+ tol: float | None
29
+ Tolerance for termination.
30
+ bounds: None | tuple[float, float] | list[tuple[float, float]]
31
+ Bounds on variables for Nelder-Mead, L-BFGS-B, TNC, SLSQP, Powell,
32
+ trust-constr, COBYLA, and COBYQA methods. None is used to specify no bounds,
33
+ `(min, max)` is used to specify bounds for all variables. A sequence of
34
+ `(min, max)` can be used to specify bounds for each parameter individually.
35
+ jac: None | Literal["2-point", "3-point", "cs"]
36
+ Method for computing the gradient vector. Only for CG, BFGS, Newton-CG,
37
+ L-BFGS-B, TNC, SLSQP, dogleg, trust-ncg, trust-krylov, trust-exact and
38
+ trust-constr.
39
+ hess: None | Literal["2-point", "3-point", "cs"]
40
+ Method for computing the Hessian matrix. Only for Newton-CG, dogleg, trust-ncg,
41
+ trust-krylov, trust-exact and trust-constr.
42
+ maxiter: int
43
+ Maximum number of iterations to perform. Depending on the method
44
+ each iteration may use several function evaluations. Will be ignored for TNC
45
+ optimizer. Default: 100
46
+ options: dict[str, float]
47
+ A dictionary of solver options.
48
+ """
49
+
50
+ optimizer_type: Literal["linear"] = "linear"
51
+
52
+
53
+ class CombinedOptimizerParams(BaseModel):
54
+ """Combination of LinearOptimizer and ScipyOptimizer.
55
+
56
+ Optimizer that first performs an optimization of the linear schedule and then
57
+ fine tunes individual parameters.
58
+
59
+
60
+ Attributes
61
+ ----------
62
+ linear: LinearOptimizerParams | Dict
63
+ Parameters of the linear optimizer.
64
+ fine_tune: ScipyOptimizerParams | Dict
65
+ Parameters of the fine tuning optimizer.
66
+ """
67
+
68
+ optimizer_type: Literal["combined"] = "combined"
69
+ linear: LinearOptimizerParams = Field(
70
+ default_factory=lambda: LinearOptimizerParams()
71
+ )
72
+ fine_tune: ScipyOptimizerParams = Field(
73
+ default_factory=lambda: ScipyOptimizerParams()
74
+ )
75
+
76
+
77
+ class InterpolateOptimizerParams(BaseModel):
78
+ """Optimizer with sequentially increasing number of QAOA layers.
79
+
80
+ Optimizer that starts with `reps` iteration and interpolates sequentially in
81
+ `reps_step` steps to `reps_end`. In between it performs a full optimization routine
82
+ tunes individual parameters.
83
+
84
+ Attributes
85
+ ----------
86
+ optimiezr: LinearOptimizerParams | ScipyOptimizerParams | Dict
87
+ Parameters of the optimizer.
88
+ reps_step: int
89
+ Number of QAOA layers added for one interpolation.
90
+ reps_end: int
91
+ Final number of QAOA layers to be reached.
92
+ """
93
+
94
+ optimizer_type: Literal["interpolate"] = "interpolate"
95
+ optimizer: ScipyOptimizerParams | LinearOptimizerParams = Field(
96
+ default_factory=lambda: ScipyOptimizerParams()
97
+ )
98
+ reps_step: int = Field(default=1, ge=1)
99
+ reps_end: int = Field(default=10, ge=1)
@@ -0,0 +1,87 @@
1
+ from pydantic import BaseModel, Field
2
+
3
+
4
+ class OneHotParams(BaseModel):
5
+ """Implements one-hot constraints through XY-mixers."""
6
+
7
+
8
+ class IndicatorFunctionParams(BaseModel):
9
+ """Implements inequality constraints via indicator functions.
10
+
11
+ Attributes
12
+ ----------
13
+ penalty: float | None
14
+ Custom penalty factor for indicator functions. If none set, automatically
15
+ determined through upper and lower bounds.
16
+ penalty_scaling: float
17
+ Scaling of automatically determined penalty factor. Default: 2
18
+ """
19
+
20
+ penalty: float | None = Field(
21
+ default=None,
22
+ ge=0,
23
+ description="Custom penalty factor for indicator functions. If none set, "
24
+ "automatically determined through upper and lower bounds.",
25
+ )
26
+ penalty_scaling: float = Field(
27
+ default=2,
28
+ ge=0,
29
+ description="Scaling of automatically determined penalty factor. Default: 2",
30
+ )
31
+
32
+
33
+ class QuadraticPenaltyParams(BaseModel):
34
+ """Implements all constraints through quadratic penalties.
35
+
36
+ Adds penalty terms to the objective. Adds slack variables for inequality constraints
37
+ if neccessaray.
38
+
39
+ Attributes
40
+ ----------
41
+ penalty: float | None
42
+ Custom penalty factor for quadratic penalty terms. If none is set, it is
43
+ automatically determined by taking 10 times the maximum absolute initial bias.
44
+ """
45
+
46
+ penalty: float | None = Field(
47
+ default=None,
48
+ ge=0,
49
+ description="Custom penalty factor for quadratic penalty terms. If none set, "
50
+ "automatically determined by taking 10 times the maximum absolute initial "
51
+ "bias.",
52
+ )
53
+
54
+
55
+ class PipelineParams(BaseModel):
56
+ """Defines the modular Constrained QAOA Pipeline.
57
+
58
+ By default all features are enabled.
59
+
60
+ Attributes
61
+ ----------
62
+ indicator_function: IndicatorFunctionParams | Dict | None
63
+ Whether to implement inequality constraints with indicator functions. Disable
64
+ with setting to `None`.
65
+ one_hot: OneHotParams | Dict | None
66
+ Whether to implement inequality constraints with indicator functions. Disable
67
+ with setting to `None`.
68
+ quadratic_penalty: QuadraticPenaltyParams | Dict | None
69
+ Whether to implement inequality constraints with indicator functions. Disable
70
+ with setting to `None`.
71
+ """
72
+
73
+ indicator_function: IndicatorFunctionParams | None = Field(
74
+ default_factory=lambda: IndicatorFunctionParams(),
75
+ description="Whether to implement inequality constraints with indicator "
76
+ "functions. Disable with setting to `None`.",
77
+ )
78
+ one_hot: OneHotParams | None = Field(
79
+ default_factory=lambda: OneHotParams(),
80
+ description="Whether to implement inequality constraints with indicator "
81
+ "functions. Disable with setting to `None`.",
82
+ )
83
+ quadratic_penalty: QuadraticPenaltyParams | None = Field(
84
+ default_factory=lambda: QuadraticPenaltyParams(),
85
+ description="Whether to implement inequality constraints with indicator "
86
+ "functions. Disable with setting to `None`.",
87
+ )
@@ -0,0 +1,102 @@
1
+ from pydantic import Field
2
+
3
+ from luna_quantum.solve.domain.abstract import LunaAlgorithm
4
+ from luna_quantum.solve.parameters.algorithms.base_params.qaoa_circuit_params import (
5
+ BasicQAOAParams,
6
+ LinearQAOAParams,
7
+ RandomQAOAParams,
8
+ )
9
+ from luna_quantum.solve.parameters.algorithms.base_params.scipy_optimizer import (
10
+ ScipyOptimizerParams,
11
+ )
12
+ from luna_quantum.solve.parameters.backends import AWS, IBM, IQM, IonQ, Rigetti
13
+
14
+
15
+ class QAOA(LunaAlgorithm[AWS | IonQ | IQM | Rigetti | IBM]):
16
+ """
17
+ Quantum Approximate Optimization Algorithm (QAOA).
18
+
19
+ QAOA is a hybrid quantum-classical algorithm for solving combinatorial optimization
20
+ problems. It works by preparing a quantum state through alternating applications of
21
+ problem-specific (cost) and mixing Hamiltonians, controlled by variational
22
+ parameters that are optimized classically to maximize the probability of measuring
23
+ the optimal solution.
24
+
25
+ QAOA is particularly suited for problems that can be encoded as quadratic
26
+ unconstrained binary optimization (QUBO) or Ising models, such as MaxCut, TSP, and
27
+ portfolio optimization.
28
+
29
+ Attributes
30
+ ----------
31
+ reps : int
32
+ Number of QAOA layers (p). Each layer consists of applying both the cost and
33
+ mixing Hamiltonians with different variational parameters. Higher values
34
+ generally lead to better solutions but increase circuit depth and quantum
35
+ resources required. Default is 1.
36
+ shots : int
37
+ Number of measurement samples to collect per circuit execution. Higher values
38
+ reduce statistical noise but increase runtime. Default is 1024.
39
+ optimizer : ScipyOptimizerParams | Dict
40
+ Configuration for the classical optimization routine that updates the
41
+ variational parameters. Default is a ScipyOptimizer instance with default
42
+ settings. See ScipyOptimizerParams class for details of contained parameters.
43
+ initial_params: LinearQAOAParams | BasicQAOAParams | RandomQAOAParams | Dict
44
+ Custom QAOA variational circuit parameters. By default linear
45
+ increasing/decreasing parameters for the selected `reps` are generated.
46
+ """
47
+
48
+ reps: int = Field(default=1, ge=1)
49
+ shots: int = Field(default=1024, ge=1)
50
+ optimizer: ScipyOptimizerParams = Field(
51
+ default_factory=lambda: ScipyOptimizerParams()
52
+ )
53
+ initial_params: RandomQAOAParams | BasicQAOAParams | LinearQAOAParams = Field(
54
+ default_factory=lambda: LinearQAOAParams(delta_beta=0.5, delta_gamma=0.5)
55
+ )
56
+
57
+ @property
58
+ def algorithm_name(self) -> str:
59
+ """
60
+ Returns the name of the algorithm.
61
+
62
+ This abstract property method is intended to be overridden by subclasses.
63
+ It should provide the name of the algorithm being implemented.
64
+
65
+ Returns
66
+ -------
67
+ str
68
+ The name of the algorithm.
69
+ """
70
+ return "QAOA"
71
+
72
+ @classmethod
73
+ def get_default_backend(cls) -> AWS | IonQ | IQM | Rigetti | IBM:
74
+ """
75
+ Return the default backend implementation.
76
+
77
+ This property must be implemented by subclasses to provide
78
+ the default backend instance to use when no specific backend
79
+ is specified.
80
+
81
+ Returns
82
+ -------
83
+ IBackend
84
+ An instance of a class implementing the IBackend interface that serves
85
+ as the default backend.
86
+ """
87
+ return IBM()
88
+
89
+ @classmethod
90
+ def get_compatible_backends(
91
+ cls,
92
+ ) -> tuple[type[AWS | IonQ | IQM | Rigetti | IBM], ...]:
93
+ """
94
+ Check at runtime if the used backend is compatible with the solver.
95
+
96
+ Returns
97
+ -------
98
+ tuple[type[IBackend], ...]
99
+ True if the backend is compatible with the solver, False otherwise.
100
+
101
+ """
102
+ return AWS, IonQ, IQM, Rigetti, IBM
@@ -0,0 +1,69 @@
1
+ from luna_quantum.solve.domain.abstract import LunaAlgorithm
2
+ from luna_quantum.solve.parameters.backends import Qctrl
3
+
4
+
5
+ class QAOA_FO(LunaAlgorithm[Qctrl]): # noqa: N801
6
+ """
7
+ Quantum Approximate Optimization Algorithm via Fire Opal (QAOA_FO).
8
+
9
+ QAOA_FO is Q-CTRL's implementation of the Quantum Approximate Optimization Algorithm
10
+ (QAOA) through their Fire Opal framework. It is a hybrid quantum-classical algorithm
11
+ for solving combinatorial optimization problems with enhanced performance through
12
+ Q-CTRL's error mitigation and control techniques. For more details, please refer
13
+ to the `Fire Opal QAOA documentation <https://docs.q-ctrl.com/fire-opal/execute/run-algorithms/solve-optimization-problems/fire-opals-qaoa-solver>`_.
14
+
15
+ The algorithm works by preparing a quantum state through alternating applications of
16
+ problem-specific (cost) and mixing Hamiltonians, controlled by variational
17
+ parameters that are optimized classically to maximize the probability of measuring
18
+ the optimal solution.
19
+
20
+ QAOA_FO leverages Q-CTRL's expertise in quantum control to improve circuit fidelity
21
+ and optimization performance. It is particularly suited for problems that can be
22
+ encoded as quadratic unconstrained binary optimization (QUBO) or Ising models,
23
+ such as MaxCut, TSP, and portfolio optimization.
24
+ """
25
+
26
+ @property
27
+ def algorithm_name(self) -> str:
28
+ """
29
+ Returns the name of the algorithm.
30
+
31
+ This abstract property method is intended to be overridden by subclasses.
32
+ It should provide the name of the algorithm being implemented.
33
+
34
+ Returns
35
+ -------
36
+ str
37
+ The name of the algorithm.
38
+ """
39
+ return "QAOA_FO"
40
+
41
+ @classmethod
42
+ def get_default_backend(cls) -> Qctrl:
43
+ """
44
+ Return the default backend implementation.
45
+
46
+ This property must be implemented by subclasses to provide
47
+ the default backend instance to use when no specific backend
48
+ is specified.
49
+
50
+ Returns
51
+ -------
52
+ IBackend
53
+ An instance of a class implementing the IBackend interface that serves
54
+ as the default backend.
55
+ """
56
+ return Qctrl()
57
+
58
+ @classmethod
59
+ def get_compatible_backends(cls) -> tuple[type[Qctrl]]:
60
+ """
61
+ Check at runtime if the used backend is compatible with the solver.
62
+
63
+ Returns
64
+ -------
65
+ tuple[type[IBackend], ...]
66
+ True if the backend is compatible with the solver, False otherwise.
67
+
68
+ """
69
+ return (Qctrl,)