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.
- luna_quantum/__init__.py +121 -0
- luna_quantum/__init__.pyi +85 -0
- luna_quantum/_core.cpython-314-darwin.so +0 -0
- luna_quantum/_core.pyi +4185 -0
- luna_quantum/algorithms/__init__.py +1 -0
- luna_quantum/aqm_overwrites/__init__.py +3 -0
- luna_quantum/aqm_overwrites/model.py +184 -0
- luna_quantum/backends/__init__.py +1 -0
- luna_quantum/client/__init__.py +0 -0
- luna_quantum/client/controllers/__init__.py +4 -0
- luna_quantum/client/controllers/luna_http_client.py +37 -0
- luna_quantum/client/controllers/luna_platform_client.py +256 -0
- luna_quantum/client/controllers/luna_q.py +67 -0
- luna_quantum/client/controllers/luna_solve.py +129 -0
- luna_quantum/client/error/__init__.py +0 -0
- luna_quantum/client/error/luna_api_key_invalid_error.py +10 -0
- luna_quantum/client/error/luna_api_key_missing_error.py +10 -0
- luna_quantum/client/error/luna_error.py +2 -0
- luna_quantum/client/error/luna_server_error.py +20 -0
- luna_quantum/client/error/timeout_error.py +12 -0
- luna_quantum/client/error/transformation_error.py +18 -0
- luna_quantum/client/error/utils/__init__.py +0 -0
- luna_quantum/client/error/utils/http_error_utils.py +112 -0
- luna_quantum/client/interfaces/__init__.py +4 -0
- luna_quantum/client/interfaces/clients/__init__.py +25 -0
- luna_quantum/client/interfaces/clients/circuit_rest_client_i.py +68 -0
- luna_quantum/client/interfaces/clients/info_rest_client_i.py +53 -0
- luna_quantum/client/interfaces/clients/model_rest_client_i.py +139 -0
- luna_quantum/client/interfaces/clients/qpu_token_rest_client_i.py +364 -0
- luna_quantum/client/interfaces/clients/rest_client_i.py +21 -0
- luna_quantum/client/interfaces/clients/solve_job_rest_client_i.py +201 -0
- luna_quantum/client/interfaces/clients/users_rest_client_i.py +29 -0
- luna_quantum/client/interfaces/services/__init__.py +0 -0
- luna_quantum/client/interfaces/services/luna_q_i.py +34 -0
- luna_quantum/client/interfaces/services/luna_solve_i.py +72 -0
- luna_quantum/client/interfaces/services/service_i.py +56 -0
- luna_quantum/client/rest_client/__init__.py +15 -0
- luna_quantum/client/rest_client/circuit_rest_client.py +107 -0
- luna_quantum/client/rest_client/info_rest_client.py +74 -0
- luna_quantum/client/rest_client/model_rest_client.py +216 -0
- luna_quantum/client/rest_client/qpu_token_rest_client.py +508 -0
- luna_quantum/client/rest_client/solve_job_rest_client.py +286 -0
- luna_quantum/client/rest_client/users_rest_client.py +35 -0
- luna_quantum/client/schemas/__init__.py +26 -0
- luna_quantum/client/schemas/circuit.py +48 -0
- luna_quantum/client/schemas/create/__init__.py +15 -0
- luna_quantum/client/schemas/create/circuit.py +30 -0
- luna_quantum/client/schemas/create/optimization.py +39 -0
- luna_quantum/client/schemas/create/qpu_token.py +22 -0
- luna_quantum/client/schemas/create/qpu_token_time_quota.py +35 -0
- luna_quantum/client/schemas/create/qpu_token_time_quota_update.py +24 -0
- luna_quantum/client/schemas/create/qubo.py +19 -0
- luna_quantum/client/schemas/create/solve_job_create.py +43 -0
- luna_quantum/client/schemas/enums/__init__.py +0 -0
- luna_quantum/client/schemas/enums/call_style.py +13 -0
- luna_quantum/client/schemas/enums/circuit.py +42 -0
- luna_quantum/client/schemas/enums/model_format.py +11 -0
- luna_quantum/client/schemas/enums/problem.py +50 -0
- luna_quantum/client/schemas/enums/qpu_token_type.py +20 -0
- luna_quantum/client/schemas/enums/sense.py +8 -0
- luna_quantum/client/schemas/enums/status.py +40 -0
- luna_quantum/client/schemas/enums/timeframe.py +11 -0
- luna_quantum/client/schemas/error_message.py +14 -0
- luna_quantum/client/schemas/model_metadata.py +35 -0
- luna_quantum/client/schemas/qpu_token/__init__.py +0 -0
- luna_quantum/client/schemas/qpu_token/qpu_token.py +154 -0
- luna_quantum/client/schemas/qpu_token/qpu_token_source.py +19 -0
- luna_quantum/client/schemas/qpu_token/qpu_token_time_quota.py +30 -0
- luna_quantum/client/schemas/qpu_token/token_provider.py +132 -0
- luna_quantum/client/schemas/representation.py +19 -0
- luna_quantum/client/schemas/solution.py +106 -0
- luna_quantum/client/schemas/solve_job.py +50 -0
- luna_quantum/client/schemas/solver_info.py +11 -0
- luna_quantum/client/schemas/user.py +11 -0
- luna_quantum/client/schemas/wrappers/__init__.py +5 -0
- luna_quantum/client/schemas/wrappers/datetime_wrapper.py +32 -0
- luna_quantum/client/utils/__init__.py +0 -0
- luna_quantum/client/utils/qpu_token_utils.py +147 -0
- luna_quantum/config.py +11 -0
- luna_quantum/decorators.py +248 -0
- luna_quantum/errors.py +34 -0
- luna_quantum/errors.pyi +287 -0
- luna_quantum/exceptions/__init__.py +0 -0
- luna_quantum/exceptions/base_luna_quantum_error.py +2 -0
- luna_quantum/exceptions/patch_class_field_exists_error.py +10 -0
- luna_quantum/factories/__init__.py +4 -0
- luna_quantum/factories/luna_solve_client_factory.py +100 -0
- luna_quantum/factories/usecase_factory.py +457 -0
- luna_quantum/py.typed +0 -0
- luna_quantum/solve/__init__.py +13 -0
- luna_quantum/solve/default_token.py +304 -0
- luna_quantum/solve/domain/__init__.py +0 -0
- luna_quantum/solve/domain/abstract/__init__.py +4 -0
- luna_quantum/solve/domain/abstract/luna_algorithm.py +205 -0
- luna_quantum/solve/domain/abstract/qpu_token_backend.py +34 -0
- luna_quantum/solve/domain/model_metadata.py +56 -0
- luna_quantum/solve/domain/solve_job.py +196 -0
- luna_quantum/solve/errors/__init__.py +0 -0
- luna_quantum/solve/errors/incompatible_backend_error.py +15 -0
- luna_quantum/solve/errors/model_metadata_missing_error.py +11 -0
- luna_quantum/solve/errors/solve_base_error.py +5 -0
- luna_quantum/solve/errors/token_missing_error.py +11 -0
- luna_quantum/solve/interfaces/__init__.py +0 -0
- luna_quantum/solve/interfaces/algorithm_i.py +49 -0
- luna_quantum/solve/interfaces/backend_i.py +28 -0
- luna_quantum/solve/interfaces/usecases/__init__.py +55 -0
- luna_quantum/solve/interfaces/usecases/model_delete_usecase_i.py +27 -0
- luna_quantum/solve/interfaces/usecases/model_fetch_metadata_usecase_i.py +33 -0
- luna_quantum/solve/interfaces/usecases/model_get_solutions_usecase_i.py +33 -0
- luna_quantum/solve/interfaces/usecases/model_get_solve_jobs_usecase_i.py +33 -0
- luna_quantum/solve/interfaces/usecases/model_load_by_id_usecase_i.py +32 -0
- luna_quantum/solve/interfaces/usecases/model_load_by_metadata_usecase_i.py +37 -0
- luna_quantum/solve/interfaces/usecases/model_load_metadata_by_hash_usecase_i.py +38 -0
- luna_quantum/solve/interfaces/usecases/model_save_usecase_i.py +36 -0
- luna_quantum/solve/interfaces/usecases/solve_job_cancel_usecase_i.py +33 -0
- luna_quantum/solve/interfaces/usecases/solve_job_create_usecase_i.py +44 -0
- luna_quantum/solve/interfaces/usecases/solve_job_delete_usecase_i.py +32 -0
- luna_quantum/solve/interfaces/usecases/solve_job_fetch_updates_usecase_i.py +38 -0
- luna_quantum/solve/interfaces/usecases/solve_job_get_result_usecase_i.py +63 -0
- luna_quantum/solve/parameters/__init__.py +0 -0
- luna_quantum/solve/parameters/algorithms/__init__.py +51 -0
- luna_quantum/solve/parameters/algorithms/base_params/__init__.py +24 -0
- luna_quantum/solve/parameters/algorithms/base_params/decomposer.py +57 -0
- luna_quantum/solve/parameters/algorithms/base_params/qaoa_circuit_params.py +95 -0
- luna_quantum/solve/parameters/algorithms/base_params/quantum_annealing_params.py +79 -0
- luna_quantum/solve/parameters/algorithms/base_params/scipy_optimizer.py +122 -0
- luna_quantum/solve/parameters/algorithms/base_params/simulated_annealing_params.py +106 -0
- luna_quantum/solve/parameters/algorithms/base_params/tabu_kerberos_params.py +39 -0
- luna_quantum/solve/parameters/algorithms/base_params/tabu_search_params.py +129 -0
- luna_quantum/solve/parameters/algorithms/flexible_parameter_algorithm.py +59 -0
- luna_quantum/solve/parameters/algorithms/genetic_algorithms/__init__.py +4 -0
- luna_quantum/solve/parameters/algorithms/genetic_algorithms/qaga.py +131 -0
- luna_quantum/solve/parameters/algorithms/genetic_algorithms/saga.py +139 -0
- luna_quantum/solve/parameters/algorithms/lq_fda/__init__.py +3 -0
- luna_quantum/solve/parameters/algorithms/lq_fda/fujits_da_base.py +85 -0
- luna_quantum/solve/parameters/algorithms/lq_fda/fujitsu_da_v3c.py +155 -0
- luna_quantum/solve/parameters/algorithms/optimization_solvers/__init__.py +3 -0
- luna_quantum/solve/parameters/algorithms/optimization_solvers/scip.py +51 -0
- luna_quantum/solve/parameters/algorithms/quantum_annealing/__init__.py +19 -0
- luna_quantum/solve/parameters/algorithms/quantum_annealing/kerberos.py +149 -0
- luna_quantum/solve/parameters/algorithms/quantum_annealing/leap_hybrid_bqm.py +75 -0
- luna_quantum/solve/parameters/algorithms/quantum_annealing/leap_hybrid_cqm.py +75 -0
- luna_quantum/solve/parameters/algorithms/quantum_annealing/parallel_tempering_qpu.py +139 -0
- luna_quantum/solve/parameters/algorithms/quantum_annealing/population_annealing_qpu.py +109 -0
- luna_quantum/solve/parameters/algorithms/quantum_annealing/qbsolv_like_qpu.py +111 -0
- luna_quantum/solve/parameters/algorithms/quantum_annealing/quantum_annealing.py +121 -0
- luna_quantum/solve/parameters/algorithms/quantum_annealing/repeated_reverse_quantum_annealing.py +174 -0
- luna_quantum/solve/parameters/algorithms/quantum_gate/__init__.py +6 -0
- luna_quantum/solve/parameters/algorithms/quantum_gate/flex_qaoa/__init__.py +26 -0
- luna_quantum/solve/parameters/algorithms/quantum_gate/flex_qaoa/config.py +80 -0
- luna_quantum/solve/parameters/algorithms/quantum_gate/flex_qaoa/flex_qaoa.py +226 -0
- luna_quantum/solve/parameters/algorithms/quantum_gate/flex_qaoa/optimizers.py +99 -0
- luna_quantum/solve/parameters/algorithms/quantum_gate/flex_qaoa/pipeline.py +87 -0
- luna_quantum/solve/parameters/algorithms/quantum_gate/qaoa.py +102 -0
- luna_quantum/solve/parameters/algorithms/quantum_gate/qaoa_fo.py +69 -0
- luna_quantum/solve/parameters/algorithms/quantum_gate/vqe.py +108 -0
- luna_quantum/solve/parameters/algorithms/search_algorithms/__init__.py +5 -0
- luna_quantum/solve/parameters/algorithms/search_algorithms/dialectic_search.py +136 -0
- luna_quantum/solve/parameters/algorithms/search_algorithms/qbsolv_like_tabu_search.py +117 -0
- luna_quantum/solve/parameters/algorithms/search_algorithms/tabu_search.py +126 -0
- luna_quantum/solve/parameters/algorithms/simulated_annealing/__init__.py +13 -0
- luna_quantum/solve/parameters/algorithms/simulated_annealing/parallel_tempering.py +131 -0
- luna_quantum/solve/parameters/algorithms/simulated_annealing/population_annealing.py +95 -0
- luna_quantum/solve/parameters/algorithms/simulated_annealing/qbsolv_like_simulated_annealing.py +141 -0
- luna_quantum/solve/parameters/algorithms/simulated_annealing/repeated_reverse_simulated_annealing.py +172 -0
- luna_quantum/solve/parameters/algorithms/simulated_annealing/simulated_annealing.py +126 -0
- luna_quantum/solve/parameters/backends/__init__.py +22 -0
- luna_quantum/solve/parameters/backends/aqarios.py +17 -0
- luna_quantum/solve/parameters/backends/aws/__init__.py +11 -0
- luna_quantum/solve/parameters/backends/aws/aws.py +36 -0
- luna_quantum/solve/parameters/backends/aws/aws_backend_base.py +74 -0
- luna_quantum/solve/parameters/backends/aws/ionq.py +43 -0
- luna_quantum/solve/parameters/backends/aws/iqm.py +31 -0
- luna_quantum/solve/parameters/backends/aws/rigetti.py +31 -0
- luna_quantum/solve/parameters/backends/dwave.py +17 -0
- luna_quantum/solve/parameters/backends/dwave_qpu.py +166 -0
- luna_quantum/solve/parameters/backends/fda.py +17 -0
- luna_quantum/solve/parameters/backends/ibm.py +138 -0
- luna_quantum/solve/parameters/backends/qctrl.py +103 -0
- luna_quantum/solve/parameters/backends/zib.py +17 -0
- luna_quantum/solve/parameters/constants.py +11 -0
- luna_quantum/solve/parameters/mixins/__init__.py +0 -0
- luna_quantum/solve/parameters/mixins/fujitsu_common_params_mixin.py +239 -0
- luna_quantum/solve/parameters/mixins/fujitsu_v2_mixin.py +70 -0
- luna_quantum/solve/parameters/mixins/qbsolv_like_mixin.py +60 -0
- luna_quantum/solve/use_cases/__init__.py +119 -0
- luna_quantum/solve/use_cases/arbitrage_edge_based.py +50 -0
- luna_quantum/solve/use_cases/arbitrage_node_based.py +55 -0
- luna_quantum/solve/use_cases/base.py +7 -0
- luna_quantum/solve/use_cases/binary_integer_linear_programming.py +54 -0
- luna_quantum/solve/use_cases/binary_paint_shop_problem.py +37 -0
- luna_quantum/solve/use_cases/credit_scoring_feature_selection.py +40 -0
- luna_quantum/solve/use_cases/dynamic_portfolio_optimization.py +64 -0
- luna_quantum/solve/use_cases/exact_cover.py +51 -0
- luna_quantum/solve/use_cases/flight_gate_assignment.py +79 -0
- luna_quantum/solve/use_cases/graph_coloring.py +42 -0
- luna_quantum/solve/use_cases/graph_isomorphism.py +52 -0
- luna_quantum/solve/use_cases/graph_partitioning.py +46 -0
- luna_quantum/solve/use_cases/hamiltonian_cycle.py +49 -0
- luna_quantum/solve/use_cases/induced_subgraph_isomorphism.py +50 -0
- luna_quantum/solve/use_cases/job_shop_scheduling.py +44 -0
- luna_quantum/solve/use_cases/k_medoids_clustering.py +49 -0
- luna_quantum/solve/use_cases/knapsack_integer_weights.py +56 -0
- luna_quantum/solve/use_cases/linear_regression.py +60 -0
- luna_quantum/solve/use_cases/lmwcs.py +84 -0
- luna_quantum/solve/use_cases/longest_path.py +50 -0
- luna_quantum/solve/use_cases/market_graph_clustering.py +61 -0
- luna_quantum/solve/use_cases/max2sat.py +54 -0
- luna_quantum/solve/use_cases/max3sat.py +55 -0
- luna_quantum/solve/use_cases/max_clique.py +60 -0
- luna_quantum/solve/use_cases/max_cut.py +48 -0
- luna_quantum/solve/use_cases/max_independent_set.py +37 -0
- luna_quantum/solve/use_cases/minimal_maximal_matching.py +54 -0
- luna_quantum/solve/use_cases/minimal_spanning_tree.py +90 -0
- luna_quantum/solve/use_cases/minimum_vertex_cover.py +45 -0
- luna_quantum/solve/use_cases/number_partitioning.py +32 -0
- luna_quantum/solve/use_cases/portfolio_optimization.py +46 -0
- luna_quantum/solve/use_cases/portfolio_optimization_ib_tv.py +63 -0
- luna_quantum/solve/use_cases/quadratic_assignment.py +49 -0
- luna_quantum/solve/use_cases/quadratic_knapsack.py +48 -0
- luna_quantum/solve/use_cases/satellite_scheduling.py +73 -0
- luna_quantum/solve/use_cases/sensor_placement.py +58 -0
- luna_quantum/solve/use_cases/set_cover.py +56 -0
- luna_quantum/solve/use_cases/set_packing.py +54 -0
- luna_quantum/solve/use_cases/set_partitioning.py +52 -0
- luna_quantum/solve/use_cases/subgraph_isomorphism.py +55 -0
- luna_quantum/solve/use_cases/subset_sum.py +37 -0
- luna_quantum/solve/use_cases/support_vector_machine.py +64 -0
- luna_quantum/solve/use_cases/traffic_flow.py +35 -0
- luna_quantum/solve/use_cases/travelling_salesman_problem.py +53 -0
- luna_quantum/solve/use_cases/type_aliases.py +9 -0
- luna_quantum/solve/use_cases/weighted_max_cut.py +37 -0
- luna_quantum/solve/usecases/__init__.py +45 -0
- luna_quantum/solve/usecases/model_delete_usecase.py +49 -0
- luna_quantum/solve/usecases/model_fetch_metadata_usecase.py +50 -0
- luna_quantum/solve/usecases/model_get_solution_usecase.py +59 -0
- luna_quantum/solve/usecases/model_get_solve_jobs_usecase.py +62 -0
- luna_quantum/solve/usecases/model_load_by_id_usecase.py +47 -0
- luna_quantum/solve/usecases/model_load_by_metadata_usecase.py +52 -0
- luna_quantum/solve/usecases/model_load_metadata_by_hash_usecase.py +51 -0
- luna_quantum/solve/usecases/model_save_usecase.py +63 -0
- luna_quantum/solve/usecases/solve_job_cancel_usecase.py +51 -0
- luna_quantum/solve/usecases/solve_job_create_usecase.py +112 -0
- luna_quantum/solve/usecases/solve_job_delete_usecase.py +38 -0
- luna_quantum/solve/usecases/solve_job_fetch_updates_usecase.py +49 -0
- luna_quantum/solve/usecases/solve_job_get_result_usecase.py +95 -0
- luna_quantum/transformations.py +18 -0
- luna_quantum/transformations.pyi +371 -0
- luna_quantum/translator.py +23 -0
- luna_quantum/translator.pyi +869 -0
- luna_quantum/util/__init__.py +0 -0
- luna_quantum/util/active_waiting.py +79 -0
- luna_quantum/util/class_patcher.py +164 -0
- luna_quantum/util/debug_info.py +52 -0
- luna_quantum/util/log_utils.py +187 -0
- luna_quantum/util/pretty_base.py +67 -0
- luna_quantum/util/pydantic_utils.py +38 -0
- luna_quantum/utils.py +3 -0
- luna_quantum/utils.pyi +67 -0
- luna_quantum-1.0.8rc2.dist-info/METADATA +36 -0
- luna_quantum-1.0.8rc2.dist-info/RECORD +264 -0
- luna_quantum-1.0.8rc2.dist-info/WHEEL +4 -0
- luna_quantum-1.0.8rc2.dist-info/licenses/LICENSE +176 -0
- 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,)
|