classiq 0.37.1__py3-none-any.whl → 0.39.0__py3-none-any.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.
- classiq/__init__.py +23 -24
- classiq/_analyzer_extras/_ipywidgets_async_extension.py +1 -1
- classiq/_analyzer_extras/interactive_hardware.py +3 -3
- classiq/_internals/api_wrapper.py +37 -17
- classiq/_internals/async_utils.py +1 -74
- classiq/_internals/authentication/device.py +9 -4
- classiq/_internals/authentication/password_manager.py +25 -10
- classiq/_internals/authentication/token_manager.py +2 -2
- classiq/_internals/client.py +24 -6
- classiq/_internals/jobs.py +10 -7
- classiq/analyzer/analyzer.py +29 -29
- classiq/analyzer/analyzer_utilities.py +5 -5
- classiq/analyzer/rb.py +4 -5
- classiq/analyzer/show_interactive_hack.py +6 -6
- classiq/applications/__init__.py +1 -8
- classiq/applications/chemistry/__init__.py +6 -0
- classiq/{applications_model_constructors → applications/chemistry}/chemistry_model_constructor.py +9 -16
- classiq/applications/combinatorial_helpers/allowed_constraints.py +20 -0
- classiq/applications/combinatorial_helpers/arithmetic/arithmetic_expression.py +35 -0
- classiq/applications/combinatorial_helpers/arithmetic/isolation.py +42 -0
- classiq/applications/combinatorial_helpers/combinatorial_problem_utils.py +150 -0
- classiq/applications/combinatorial_helpers/encoding_mapping.py +107 -0
- classiq/applications/combinatorial_helpers/encoding_utils.py +122 -0
- classiq/applications/combinatorial_helpers/memory.py +77 -0
- classiq/applications/combinatorial_helpers/optimization_model.py +162 -0
- classiq/applications/combinatorial_helpers/pauli_helpers/pauli_sparsing.py +31 -0
- classiq/applications/combinatorial_helpers/pauli_helpers/pauli_utils.py +75 -0
- classiq/applications/combinatorial_helpers/py.typed +0 -0
- classiq/applications/combinatorial_helpers/pyomo_utils.py +245 -0
- classiq/applications/combinatorial_helpers/solvers/__init__.py +0 -0
- classiq/applications/combinatorial_helpers/sympy_utils.py +22 -0
- classiq/applications/combinatorial_helpers/transformations/__init__.py +0 -0
- classiq/applications/combinatorial_helpers/transformations/encoding.py +187 -0
- classiq/applications/combinatorial_helpers/transformations/fixed_variables.py +142 -0
- classiq/applications/combinatorial_helpers/transformations/ising_converter.py +122 -0
- classiq/applications/combinatorial_helpers/transformations/penalty.py +32 -0
- classiq/applications/combinatorial_helpers/transformations/penalty_support.py +37 -0
- classiq/applications/combinatorial_helpers/transformations/sign_seperation.py +75 -0
- classiq/applications/combinatorial_helpers/transformations/slack_variables.py +88 -0
- classiq/applications/combinatorial_optimization/__init__.py +13 -2
- classiq/applications/combinatorial_optimization/combinatorial_optimization_model_constructor.py +134 -0
- classiq/applications/finance/__init__.py +3 -2
- classiq/{applications_model_constructors → applications/finance}/finance_model_constructor.py +27 -30
- classiq/applications/grover/__init__.py +11 -0
- classiq/{applications_model_constructors → applications/grover}/grover_model_constructor.py +20 -91
- classiq/applications/libraries/__init__.py +0 -0
- classiq/applications/libraries/qmci_library.py +35 -0
- classiq/applications/qnn/circuit_utils.py +2 -2
- classiq/applications/qnn/gradients/quantum_gradient.py +2 -2
- classiq/applications/qnn/types.py +2 -2
- classiq/applications/qsvm/__init__.py +5 -1
- classiq/applications/qsvm/qsvm.py +4 -7
- classiq/applications/qsvm/qsvm_data_generation.py +2 -5
- classiq/exceptions.py +43 -1
- classiq/execution/all_hardware_devices.py +13 -0
- classiq/executor.py +12 -10
- classiq/interface/_version.py +1 -1
- classiq/interface/analyzer/analysis_params.py +6 -3
- classiq/interface/analyzer/result.py +12 -8
- classiq/interface/applications/qsvm.py +17 -3
- classiq/interface/ast_node.py +23 -0
- classiq/interface/backend/backend_preferences.py +4 -2
- classiq/interface/backend/pydantic_backend.py +3 -1
- classiq/interface/backend/quantum_backend_providers.py +1 -0
- classiq/interface/chemistry/fermionic_operator.py +15 -13
- classiq/interface/chemistry/ground_state_problem.py +18 -3
- classiq/interface/chemistry/molecule.py +8 -6
- classiq/interface/chemistry/operator.py +20 -14
- classiq/interface/combinatorial_optimization/examples/ascending_sequence.py +1 -1
- classiq/interface/combinatorial_optimization/examples/greater_than_ilp.py +1 -1
- classiq/interface/combinatorial_optimization/examples/ilp.py +2 -1
- classiq/interface/combinatorial_optimization/examples/integer_portfolio_optimization.py +2 -2
- classiq/interface/combinatorial_optimization/examples/mds.py +2 -1
- classiq/interface/combinatorial_optimization/examples/mht.py +8 -3
- classiq/interface/combinatorial_optimization/examples/mis.py +4 -1
- classiq/interface/combinatorial_optimization/examples/mvc.py +2 -1
- classiq/interface/combinatorial_optimization/examples/set_cover.py +2 -1
- classiq/interface/combinatorial_optimization/examples/tsp.py +4 -3
- classiq/interface/combinatorial_optimization/examples/tsp_digraph.py +6 -2
- classiq/interface/combinatorial_optimization/mht_qaoa_input.py +9 -3
- classiq/interface/executor/aws_execution_cost.py +4 -3
- classiq/interface/executor/estimation.py +2 -2
- classiq/interface/executor/execution_preferences.py +5 -34
- classiq/interface/executor/execution_request.py +15 -48
- classiq/interface/executor/optimizer_preferences.py +22 -13
- classiq/interface/executor/{quantum_program.py → quantum_code.py} +21 -15
- classiq/interface/executor/quantum_instruction_set.py +2 -1
- classiq/interface/executor/register_initialization.py +1 -3
- classiq/interface/executor/result.py +41 -10
- classiq/interface/executor/vqe_result.py +2 -2
- classiq/interface/finance/function_input.py +17 -4
- classiq/interface/finance/gaussian_model_input.py +3 -1
- classiq/interface/finance/log_normal_model_input.py +3 -1
- classiq/interface/finance/model_input.py +2 -0
- classiq/interface/generator/amplitude_loading.py +6 -3
- classiq/interface/generator/application_apis/__init__.py +1 -0
- classiq/interface/generator/application_apis/arithmetic_declarations.py +14 -0
- classiq/interface/generator/arith/argument_utils.py +14 -4
- classiq/interface/generator/arith/arithmetic.py +3 -1
- classiq/interface/generator/arith/arithmetic_arg_type_validator.py +12 -13
- classiq/interface/generator/arith/arithmetic_expression_abc.py +4 -1
- classiq/interface/generator/arith/arithmetic_expression_parser.py +8 -2
- classiq/interface/generator/arith/arithmetic_expression_validator.py +16 -2
- classiq/interface/generator/arith/arithmetic_operations.py +5 -10
- classiq/interface/generator/arith/ast_node_rewrite.py +1 -1
- classiq/interface/generator/arith/binary_ops.py +202 -54
- classiq/interface/generator/arith/extremum_operations.py +5 -3
- classiq/interface/generator/arith/logical_ops.py +4 -2
- classiq/interface/generator/arith/machine_precision.py +3 -0
- classiq/interface/generator/arith/number_utils.py +34 -44
- classiq/interface/generator/arith/register_user_input.py +21 -1
- classiq/interface/generator/arith/unary_ops.py +16 -25
- classiq/interface/generator/builtin_api_builder.py +0 -5
- classiq/interface/generator/chemistry_function_params.py +4 -4
- classiq/interface/generator/commuting_pauli_exponentiation.py +3 -1
- classiq/interface/generator/compiler_keywords.py +4 -0
- classiq/interface/generator/complex_type.py +3 -10
- classiq/interface/generator/constant.py +2 -3
- classiq/interface/generator/control_state.py +5 -3
- classiq/interface/generator/credit_risk_example/linear_gci.py +10 -3
- classiq/interface/generator/credit_risk_example/weighted_adder.py +14 -4
- classiq/interface/generator/expressions/atomic_expression_functions.py +5 -3
- classiq/interface/generator/expressions/evaluated_expression.py +18 -4
- classiq/interface/generator/expressions/expression.py +3 -5
- classiq/interface/generator/expressions/qmod_qscalar_proxy.py +33 -0
- classiq/interface/generator/expressions/sympy_supported_expressions.py +2 -1
- classiq/interface/generator/finance.py +1 -1
- classiq/interface/generator/function_params.py +7 -6
- classiq/interface/generator/functions/__init__.py +2 -2
- classiq/interface/generator/functions/builtins/__init__.py +15 -0
- classiq/interface/generator/functions/builtins/core_library/__init__.py +14 -0
- classiq/interface/generator/functions/builtins/core_library/chemistry_functions.py +0 -0
- classiq/interface/generator/functions/builtins/internal_operators.py +62 -0
- classiq/interface/generator/functions/{core_lib_declarations/quantum_functions/std_lib_functions.py → builtins/open_lib_functions.py} +612 -219
- classiq/interface/generator/functions/builtins/quantum_operators.py +37 -0
- classiq/interface/generator/functions/classical_type.py +2 -4
- classiq/interface/generator/functions/foreign_function_definition.py +12 -4
- classiq/interface/generator/functions/function_declaration.py +2 -2
- classiq/interface/generator/functions/function_implementation.py +8 -4
- classiq/interface/generator/functions/native_function_definition.py +4 -2
- classiq/interface/generator/functions/register.py +4 -2
- classiq/interface/generator/functions/register_mapping_data.py +14 -10
- classiq/interface/generator/generated_circuit_data.py +2 -2
- classiq/interface/generator/grover_operator.py +5 -3
- classiq/interface/generator/hamiltonian_evolution/suzuki_trotter.py +5 -1
- classiq/interface/generator/hardware/hardware_data.py +6 -4
- classiq/interface/generator/hardware_efficient_ansatz.py +25 -8
- classiq/interface/generator/hartree_fock.py +13 -3
- classiq/interface/generator/linear_pauli_rotations.py +3 -1
- classiq/interface/generator/mcu.py +5 -3
- classiq/interface/generator/mcx.py +7 -5
- classiq/interface/generator/model/classical_main_validator.py +1 -1
- classiq/interface/generator/model/constraints.py +2 -1
- classiq/interface/generator/model/model.py +12 -20
- classiq/interface/generator/model/preferences/preferences.py +4 -3
- classiq/interface/generator/oracles/custom_oracle.py +4 -2
- classiq/interface/generator/oracles/oracle_abc.py +2 -2
- classiq/interface/generator/qpe.py +6 -4
- classiq/interface/generator/qsvm.py +5 -8
- classiq/interface/generator/quantum_function_call.py +21 -16
- classiq/interface/generator/{generated_circuit.py → quantum_program.py} +10 -14
- classiq/interface/generator/range_types.py +3 -1
- classiq/interface/generator/slice_parsing_utils.py +8 -3
- classiq/interface/generator/standard_gates/controlled_standard_gates.py +4 -2
- classiq/interface/generator/state_preparation/metrics.py +2 -1
- classiq/interface/generator/state_preparation/state_preparation.py +7 -5
- classiq/interface/generator/state_propagator.py +16 -5
- classiq/interface/generator/types/builtin_struct_declarations/__init__.py +0 -1
- classiq/interface/generator/types/struct_declaration.py +10 -7
- classiq/interface/generator/ucc.py +6 -4
- classiq/interface/generator/unitary_gate.py +7 -3
- classiq/interface/generator/validations/flow_graph.py +6 -4
- classiq/interface/generator/validations/validator_functions.py +6 -4
- classiq/interface/hardware.py +2 -2
- classiq/interface/helpers/custom_encoders.py +3 -0
- classiq/interface/helpers/pydantic_model_helpers.py +0 -6
- classiq/interface/helpers/validation_helpers.py +1 -1
- classiq/interface/helpers/versioned_model.py +4 -1
- classiq/interface/ide/show.py +2 -2
- classiq/interface/jobs.py +72 -3
- classiq/interface/model/bind_operation.py +18 -11
- classiq/interface/model/call_synthesis_data.py +68 -0
- classiq/interface/model/classical_if.py +13 -0
- classiq/interface/model/classical_parameter_declaration.py +2 -3
- classiq/interface/model/control.py +16 -0
- classiq/interface/model/handle_binding.py +3 -2
- classiq/interface/model/inplace_binary_operation.py +2 -2
- classiq/interface/model/invert.py +10 -0
- classiq/interface/model/model.py +29 -22
- classiq/interface/model/native_function_definition.py +3 -5
- classiq/interface/model/power.py +12 -0
- classiq/interface/model/quantum_expressions/amplitude_loading_operation.py +9 -4
- classiq/interface/model/quantum_expressions/control_state.py +2 -2
- classiq/interface/model/quantum_function_call.py +33 -142
- classiq/interface/model/quantum_function_declaration.py +8 -0
- classiq/interface/model/quantum_if_operation.py +4 -5
- classiq/interface/model/quantum_lambda_function.py +58 -0
- classiq/{quantum_register.py → interface/model/quantum_register.py} +17 -9
- classiq/interface/model/quantum_statement.py +3 -2
- classiq/interface/model/quantum_type.py +58 -59
- classiq/interface/model/quantum_variable_declaration.py +3 -3
- classiq/interface/model/repeat.py +13 -0
- classiq/interface/model/resolvers/function_call_resolver.py +26 -0
- classiq/interface/model/statement_block.py +49 -0
- classiq/interface/model/validations/handles_validator.py +16 -18
- classiq/interface/model/within_apply_operation.py +11 -0
- classiq/interface/pyomo_extension/pyomo_sympy_bimap.py +4 -1
- classiq/interface/server/routes.py +5 -4
- classiq/qmod/__init__.py +13 -6
- classiq/qmod/builtins/classical_execution_primitives.py +27 -36
- classiq/qmod/builtins/classical_functions.py +22 -12
- classiq/qmod/builtins/functions.py +272 -328
- classiq/qmod/builtins/operations.py +171 -35
- classiq/qmod/builtins/structs.py +15 -15
- classiq/qmod/cfunc.py +42 -0
- classiq/qmod/classical_function.py +6 -14
- classiq/qmod/declaration_inferrer.py +12 -21
- classiq/qmod/expression_query.py +23 -0
- classiq/qmod/model_state_container.py +2 -0
- classiq/qmod/native/__init__.py +0 -0
- classiq/qmod/native/expression_to_qmod.py +189 -0
- classiq/qmod/native/pretty_printer.py +340 -0
- classiq/qmod/qfunc.py +27 -0
- classiq/qmod/qmod_constant.py +100 -0
- classiq/qmod/qmod_parameter.py +36 -13
- classiq/qmod/qmod_struct.py +3 -3
- classiq/qmod/qmod_variable.py +148 -31
- classiq/qmod/quantum_callable.py +1 -0
- classiq/qmod/quantum_expandable.py +18 -19
- classiq/qmod/quantum_function.py +41 -8
- classiq/qmod/symbolic.py +48 -5
- classiq/qmod/symbolic_expr.py +9 -0
- classiq/qmod/utilities.py +13 -0
- classiq/qmod/write_qmod.py +39 -0
- {classiq-0.37.1.dist-info → classiq-0.39.0.dist-info}/METADATA +2 -1
- {classiq-0.37.1.dist-info → classiq-0.39.0.dist-info}/RECORD +244 -225
- {classiq-0.37.1.dist-info → classiq-0.39.0.dist-info}/WHEEL +1 -1
- classiq/applications/benchmarking/__init__.py +0 -9
- classiq/applications/benchmarking/mirror_benchmarking.py +0 -67
- classiq/applications/numpy_utils.py +0 -37
- classiq/applications_model_constructors/__init__.py +0 -17
- classiq/applications_model_constructors/combinatorial_optimization_model_constructor.py +0 -178
- classiq/applications_model_constructors/libraries/qmci_library.py +0 -109
- classiq/builtin_functions/__init__.py +0 -43
- classiq/builtin_functions/amplitude_loading.py +0 -3
- classiq/builtin_functions/binary_ops.py +0 -1
- classiq/builtin_functions/exponentiation.py +0 -5
- classiq/builtin_functions/qpe.py +0 -4
- classiq/builtin_functions/qsvm.py +0 -7
- classiq/builtin_functions/range_types.py +0 -5
- classiq/builtin_functions/standard_gates.py +0 -1
- classiq/builtin_functions/state_preparation.py +0 -6
- classiq/builtin_functions/suzuki_trotter.py +0 -3
- classiq/interface/generator/expressions/qmod_qnum_proxy.py +0 -22
- classiq/interface/generator/functions/core_lib_declarations/quantum_functions/__init__.py +0 -18
- classiq/interface/generator/functions/core_lib_declarations/quantum_operators.py +0 -169
- classiq/interface/generator/types/builtin_struct_declarations/qaoa_declarations.py +0 -23
- classiq/interface/generator/types/combinatorial_problem.py +0 -26
- classiq/interface/model/numeric_reinterpretation.py +0 -25
- classiq/interface/model/operator_synthesis_data.py +0 -48
- classiq/model/__init__.py +0 -14
- classiq/model/composite_function_generator.py +0 -33
- classiq/model/function_handler.py +0 -466
- classiq/model/function_handler.pyi +0 -152
- classiq/model/logic_flow.py +0 -149
- classiq/model/logic_flow_change_handler.py +0 -71
- classiq/model/model.py +0 -246
- classiq/quantum_functions/__init__.py +0 -17
- classiq/quantum_functions/annotation_parser.py +0 -207
- classiq/quantum_functions/decorators.py +0 -22
- classiq/quantum_functions/function_library.py +0 -181
- classiq/quantum_functions/function_parser.py +0 -74
- classiq/quantum_functions/quantum_function.py +0 -236
- /classiq/{applications_model_constructors/libraries → applications/combinatorial_helpers}/__init__.py +0 -0
- /classiq/{interface/generator/functions/core_lib_declarations → applications/combinatorial_helpers/arithmetic}/__init__.py +0 -0
- /classiq/{interface/generator/functions/core_lib_declarations/quantum_functions/chemistry_functions.py → applications/combinatorial_helpers/pauli_helpers/__init__.py} +0 -0
- /classiq/{applications_model_constructors → applications}/libraries/ampltitude_estimation_library.py +0 -0
- /classiq/{applications_model_constructors → applications/qsvm}/qsvm_model_constructor.py +0 -0
- /classiq/interface/generator/functions/{core_lib_declarations/quantum_functions → builtins/core_library}/atomic_quantum_functions.py +0 -0
- /classiq/interface/generator/functions/{core_lib_declarations/quantum_functions → builtins/core_library}/exponentiation_functions.py +0 -0
@@ -5,7 +5,7 @@ import pydantic
|
|
5
5
|
|
6
6
|
from classiq.interface.executor.execution_preferences import ExecutionPreferences
|
7
7
|
from classiq.interface.generator.constant import Constant
|
8
|
-
from classiq.interface.generator.function_params import IOName
|
8
|
+
from classiq.interface.generator.function_params import ArithmeticIODict, IOName
|
9
9
|
from classiq.interface.generator.functions import (
|
10
10
|
SynthesisNativeFunctionDefinition,
|
11
11
|
SynthesisPortDeclaration,
|
@@ -22,20 +22,14 @@ from classiq.interface.generator.quantum_function_call import (
|
|
22
22
|
WireDict,
|
23
23
|
WireName,
|
24
24
|
)
|
25
|
-
from classiq.interface.generator.types.combinatorial_problem import (
|
26
|
-
CombinatorialOptimizationStructDeclaration,
|
27
|
-
)
|
28
25
|
from classiq.interface.generator.types.struct_declaration import StructDeclaration
|
29
|
-
from classiq.interface.helpers.pydantic_model_helpers import
|
30
|
-
get_discriminator_field,
|
31
|
-
nameables_to_dict,
|
32
|
-
)
|
26
|
+
from classiq.interface.helpers.pydantic_model_helpers import nameables_to_dict
|
33
27
|
from classiq.interface.helpers.validation_helpers import is_list_unique
|
34
28
|
from classiq.interface.helpers.versioned_model import VersionedModel
|
29
|
+
from classiq.interface.model.quantum_register import QReg, QRegGenericAlias
|
35
30
|
|
36
31
|
from classiq import ForeignFunctionDefinition as SynthesisForeignFunctionDefinition
|
37
32
|
from classiq.exceptions import ClassiqValueError
|
38
|
-
from classiq.quantum_register import QReg, QRegGenericAlias
|
39
33
|
|
40
34
|
MAIN_FUNCTION_NAME = "main"
|
41
35
|
CLASSICAL_ENTRY_FUNCTION_NAME = "cmain"
|
@@ -45,10 +39,6 @@ DEFAULT_PORT_SIZE = 1
|
|
45
39
|
|
46
40
|
SerializedModel = NewType("SerializedModel", str)
|
47
41
|
|
48
|
-
ConcreteStructDeclaration = Union[
|
49
|
-
CombinatorialOptimizationStructDeclaration, StructDeclaration
|
50
|
-
]
|
51
|
-
|
52
42
|
# We need to define ConcreteFunctionData so pydantic will know
|
53
43
|
# what class to use when deserializing from object (pydantic attempts to
|
54
44
|
# parse as each of the classes in the Union, in order).
|
@@ -70,7 +60,7 @@ class ClassiqBaseModel(VersionedModel, ABC):
|
|
70
60
|
All the relevant data for evaluating execution in one place.
|
71
61
|
"""
|
72
62
|
|
73
|
-
types: List[
|
63
|
+
types: List[StructDeclaration] = pydantic.Field(
|
74
64
|
default_factory=list,
|
75
65
|
description="The user-defined custom function library.",
|
76
66
|
)
|
@@ -88,17 +78,18 @@ class ClassiqBaseModel(VersionedModel, ABC):
|
|
88
78
|
)
|
89
79
|
|
90
80
|
@pydantic.validator("types")
|
91
|
-
def types_validator(
|
92
|
-
cls, types: List[ConcreteStructDeclaration]
|
93
|
-
) -> List[ConcreteStructDeclaration]:
|
81
|
+
def types_validator(cls, types: List[StructDeclaration]) -> List[StructDeclaration]:
|
94
82
|
if not is_list_unique([struct_type.name for struct_type in types]):
|
95
|
-
raise
|
83
|
+
raise ClassiqValueError(TYPE_LIBRARY_DUPLICATED_TYPE_NAMES)
|
96
84
|
|
97
85
|
return types
|
98
86
|
|
99
87
|
|
100
88
|
class ExecutionModel(ClassiqBaseModel):
|
101
|
-
|
89
|
+
circuit_outputs: ArithmeticIODict = pydantic.Field(
|
90
|
+
description="Mapping between a measured register name and its arithmetic type",
|
91
|
+
default_factory=dict,
|
92
|
+
)
|
102
93
|
|
103
94
|
|
104
95
|
class SynthesisModel(ClassiqBaseModel):
|
@@ -106,7 +97,7 @@ class SynthesisModel(ClassiqBaseModel):
|
|
106
97
|
All the relevant data for generating quantum circuit in one place.
|
107
98
|
"""
|
108
99
|
|
109
|
-
kind: Literal["synthesis"] =
|
100
|
+
kind: Literal["synthesis"] = pydantic.Field(default="synthesis")
|
110
101
|
|
111
102
|
# Must be validated before logic_flow
|
112
103
|
functions: List[ConcreteFunctionDefinition] = pydantic.Field(
|
@@ -241,4 +232,5 @@ class SynthesisModel(ClassiqBaseModel):
|
|
241
232
|
constants=self.constants,
|
242
233
|
classical_execution_code=self.classical_execution_code,
|
243
234
|
execution_preferences=self.execution_preferences,
|
235
|
+
circuit_outputs=self.main_func.outputs,
|
244
236
|
)
|
@@ -21,6 +21,7 @@ from classiq.interface.hardware import Provider
|
|
21
21
|
from classiq.interface.helpers.custom_pydantic_types import PydanticMachinePrecision
|
22
22
|
|
23
23
|
from classiq._internals.enum_utils import StrEnum
|
24
|
+
from classiq.exceptions import ClassiqValueError
|
24
25
|
|
25
26
|
if TYPE_CHECKING:
|
26
27
|
VisualizationLevel: TypeAlias = Optional[int]
|
@@ -157,7 +158,7 @@ class Preferences(pydantic.BaseModel, extra=pydantic.Extra.forbid):
|
|
157
158
|
if generation_timeout_seconds is None or optimization_timeout_seconds is None:
|
158
159
|
return optimization_timeout_seconds
|
159
160
|
if optimization_timeout_seconds >= generation_timeout_seconds:
|
160
|
-
raise
|
161
|
+
raise ClassiqValueError(
|
161
162
|
f"Generation timeout ({generation_timeout_seconds})"
|
162
163
|
f"is greater than or equal to "
|
163
164
|
f"optimization timeout ({optimization_timeout_seconds}) "
|
@@ -176,7 +177,7 @@ class Preferences(pydantic.BaseModel, extra=pydantic.Extra.forbid):
|
|
176
177
|
cls, output_format: PydanticConstrainedQuantumFormatList, values: Dict[str, Any]
|
177
178
|
) -> PydanticConstrainedQuantumFormatList:
|
178
179
|
if len(output_format) != len(set(output_format)):
|
179
|
-
raise
|
180
|
+
raise ClassiqValueError(
|
180
181
|
f"output_format={output_format}\n"
|
181
182
|
"has at least one format that appears twice or more"
|
182
183
|
)
|
@@ -196,7 +197,7 @@ class Preferences(pydantic.BaseModel, extra=pydantic.Extra.forbid):
|
|
196
197
|
backend_name = values.get("backend_name")
|
197
198
|
backend_service_provider = values.get("backend_service_provider")
|
198
199
|
if (backend_name is None) != (backend_service_provider is None):
|
199
|
-
raise
|
200
|
+
raise ClassiqValueError(BACKEND_VALIDATION_ERROR_MESSAGE)
|
200
201
|
return values
|
201
202
|
|
202
203
|
@property
|
@@ -11,6 +11,8 @@ from classiq.interface.generator.oracles.oracle_abc import (
|
|
11
11
|
)
|
12
12
|
from classiq.interface.generator.user_defined_function_params import CustomFunction
|
13
13
|
|
14
|
+
from classiq.exceptions import ClassiqValueError
|
15
|
+
|
14
16
|
QubitState = str
|
15
17
|
|
16
18
|
|
@@ -39,12 +41,12 @@ class CustomOracle(OracleABC[QubitState]):
|
|
39
41
|
if set(custom_oracle_params.input_decls.keys()) != set(
|
40
42
|
custom_oracle_params.output_decls.keys()
|
41
43
|
):
|
42
|
-
raise
|
44
|
+
raise ClassiqValueError("Oracle IO names must be identical")
|
43
45
|
if any(
|
44
46
|
custom_oracle_params.output_decls[name].size != input_decl.size
|
45
47
|
for name, input_decl in custom_oracle_params.input_decls.items()
|
46
48
|
):
|
47
|
-
raise
|
49
|
+
raise ClassiqValueError("Oracle IO sizes must be identical")
|
48
50
|
return custom_oracle_params
|
49
51
|
|
50
52
|
def _get_register_transputs(self) -> ArithmeticIODict:
|
@@ -60,10 +60,10 @@ class OracleABC(abc.ABC, FunctionParams, Generic[ProblemResultType]):
|
|
60
60
|
pass
|
61
61
|
|
62
62
|
def variables(self) -> List[RegisterUserInput]:
|
63
|
-
return
|
63
|
+
return [
|
64
64
|
RegisterUserInput.from_arithmetic_info(info=info, name=name)
|
65
65
|
for name, info in self._inputs.items()
|
66
|
-
|
66
|
+
]
|
67
67
|
|
68
68
|
def _check_indices(self, indices: IOQubitMapping) -> None:
|
69
69
|
if set(indices.keys()) != {reg.name for reg in self.variables()}:
|
@@ -65,7 +65,7 @@ class ExponentiationSpecification(pydantic.BaseModel):
|
|
65
65
|
cls, values: Dict[str, Any]
|
66
66
|
) -> Dict[str, Any]:
|
67
67
|
if values.get("scaling") is None and values.get("max_depths") is None:
|
68
|
-
raise
|
68
|
+
raise ClassiqValueError("At least one specification must be provided.")
|
69
69
|
return values
|
70
70
|
|
71
71
|
|
@@ -131,7 +131,7 @@ class PhaseEstimation(FunctionParams):
|
|
131
131
|
if not unitary_params.is_powerable():
|
132
132
|
if isinstance(unitary_params, CustomFunction):
|
133
133
|
raise ClassiqMismatchIOsError(CUSTOM_FUNCTIONS_IO_MISMATCH_ERROR)
|
134
|
-
raise
|
134
|
+
raise ClassiqValueError(
|
135
135
|
f"Phase estimation of {unitary_params.discriminator()} is currently not supported."
|
136
136
|
)
|
137
137
|
return unitary_params
|
@@ -146,11 +146,13 @@ class PhaseEstimation(FunctionParams):
|
|
146
146
|
return exponentiation_specification
|
147
147
|
unitary_params = values.get("unitary_params")
|
148
148
|
if not isinstance(unitary_params, Exponentiation):
|
149
|
-
raise
|
149
|
+
raise ClassiqValueError(
|
150
150
|
"exponentiation_specification is only valid for Exponentiation unitary_params."
|
151
151
|
)
|
152
152
|
if exponentiation_specification.max_depths is not None and len(
|
153
153
|
exponentiation_specification.max_depths
|
154
154
|
) != values.get("size"):
|
155
|
-
raise
|
155
|
+
raise ClassiqValueError(
|
156
|
+
"Length of max_depths must match the provided size."
|
157
|
+
)
|
156
158
|
return exponentiation_specification
|
@@ -12,10 +12,9 @@ from classiq.interface.generator.function_params import (
|
|
12
12
|
from classiq.interface.helpers.hashable_pydantic_base_model import (
|
13
13
|
HashablePydanticBaseModel,
|
14
14
|
)
|
15
|
-
from classiq.interface.helpers.pydantic_model_helpers import get_discriminator_field
|
16
15
|
|
17
16
|
from classiq._internals.enum_utils import StrEnum
|
18
|
-
from classiq.exceptions import ClassiqQSVMError
|
17
|
+
from classiq.exceptions import ClassiqQSVMError, ClassiqValueError
|
19
18
|
|
20
19
|
VALID_PAULI_LETTERS = ("I", "X", "Y", "Z")
|
21
20
|
|
@@ -36,9 +35,7 @@ class QSVMFeatureMapDimensional(HashablePydanticBaseModel):
|
|
36
35
|
|
37
36
|
|
38
37
|
class QSVMFeatureMapPauli(QSVMFeatureMapDimensional):
|
39
|
-
map_type: Literal["pauli_feature_map"] =
|
40
|
-
"pauli_feature_map"
|
41
|
-
)
|
38
|
+
map_type: Literal["pauli_feature_map"] = pydantic.Field(default="pauli_feature_map")
|
42
39
|
reps: int = 2
|
43
40
|
entanglement: QSVMFeatureMapEntanglement = QSVMFeatureMapEntanglement.LINEAR
|
44
41
|
alpha: float = 2.0
|
@@ -51,15 +48,15 @@ class QSVMFeatureMapPauli(QSVMFeatureMapDimensional):
|
|
51
48
|
# iterate every letter in every string in the list of paulis
|
52
49
|
for s in paulis:
|
53
50
|
if not all(map(VALID_PAULI_LETTERS.__contains__, s.upper())):
|
54
|
-
raise
|
51
|
+
raise ClassiqValueError(
|
55
52
|
f"Invalid pauli string given: {s!r}. Expecting a combination of {VALID_PAULI_LETTERS}"
|
56
53
|
)
|
57
54
|
return list(map(str.upper, paulis))
|
58
55
|
|
59
56
|
|
60
57
|
class QSVMFeatureMapBlochSphere(QSVMFeatureMapDimensional):
|
61
|
-
map_type: Literal["bloch_sphere_feature_map"] =
|
62
|
-
"bloch_sphere_feature_map"
|
58
|
+
map_type: Literal["bloch_sphere_feature_map"] = pydantic.Field(
|
59
|
+
default="bloch_sphere_feature_map"
|
63
60
|
)
|
64
61
|
|
65
62
|
|
@@ -24,6 +24,7 @@ from pydantic import BaseModel, Extra
|
|
24
24
|
|
25
25
|
from classiq.interface.generator import function_param_list, function_params as f_params
|
26
26
|
from classiq.interface.generator.arith.arithmetic import Arithmetic
|
27
|
+
from classiq.interface.generator.compiler_keywords import EXPANDED_KEYWORD
|
27
28
|
from classiq.interface.generator.control_state import ControlState
|
28
29
|
from classiq.interface.generator.function_params import (
|
29
30
|
NAME_REGEX,
|
@@ -79,7 +80,7 @@ class WirePair(HashablePydanticBaseModel):
|
|
79
80
|
out_wire: WireName
|
80
81
|
|
81
82
|
|
82
|
-
SUFFIX_RANDOMIZER = random.Random() #
|
83
|
+
SUFFIX_RANDOMIZER = random.Random() # noqa: S311
|
83
84
|
|
84
85
|
|
85
86
|
def split_wire_pair_to_wires(
|
@@ -90,8 +91,7 @@ def split_wire_pair_to_wires(
|
|
90
91
|
|
91
92
|
def randomize_suffix(suffix_len: int = DEFAULT_SUFFIX_LEN) -> str:
|
92
93
|
return "".join(
|
93
|
-
SUFFIX_RANDOMIZER.choice(_ALPHANUM_CHARACTERS)
|
94
|
-
for _ in range(suffix_len) # nosec B311
|
94
|
+
SUFFIX_RANDOMIZER.choice(_ALPHANUM_CHARACTERS) for _ in range(suffix_len)
|
95
95
|
)
|
96
96
|
|
97
97
|
|
@@ -218,20 +218,23 @@ class SynthesisQuantumFunctionCall(BaseModel):
|
|
218
218
|
if name is not None:
|
219
219
|
match = re.fullmatch(pattern=NAME_REGEX, string=name)
|
220
220
|
if match is None:
|
221
|
-
raise
|
221
|
+
raise ClassiqValueError(BAD_CALL_NAME_ERROR_MSG)
|
222
222
|
return name
|
223
223
|
|
224
224
|
function = values.get("function")
|
225
225
|
|
226
226
|
params = values.get("function_params")
|
227
|
-
if
|
228
|
-
|
229
|
-
|
227
|
+
if (
|
228
|
+
isinstance(params, CustomFunction)
|
229
|
+
and function == CustomFunction.discriminator()
|
230
|
+
and params.name != ""
|
231
|
+
):
|
232
|
+
function = params.name
|
230
233
|
|
231
234
|
suffix = f"{SUFFIX_MARKER}_{randomize_suffix()}"
|
232
235
|
if not function or params is None:
|
233
236
|
return name if name else suffix
|
234
|
-
return f"{function}_{suffix}"
|
237
|
+
return f"{function.split(f'_{EXPANDED_KEYWORD}')[0]}_{suffix}"
|
235
238
|
|
236
239
|
@pydantic.root_validator(pre=True)
|
237
240
|
def validate_composite_name(cls, values: Dict[str, Any]) -> Dict[str, Any]:
|
@@ -285,7 +288,7 @@ class SynthesisQuantumFunctionCall(BaseModel):
|
|
285
288
|
if invalid_slicings:
|
286
289
|
error_msg.append(f"{BAD_INPUT_SLICING_MSG}: {invalid_slicings}")
|
287
290
|
if error_msg:
|
288
|
-
raise
|
291
|
+
raise ClassiqValueError("\n".join(error_msg))
|
289
292
|
|
290
293
|
@pydantic.validator("strict_zero_ios")
|
291
294
|
def _validate_arithmetic_cannot_strict_zero_ios(
|
@@ -352,7 +355,7 @@ class SynthesisQuantumFunctionCall(BaseModel):
|
|
352
355
|
if not SynthesisQuantumFunctionCall._register_validate_slices(
|
353
356
|
slices_dict[name], widths[name]
|
354
357
|
):
|
355
|
-
raise
|
358
|
+
raise ClassiqValueError(BAD_INPUT_SLICING_MSG)
|
356
359
|
|
357
360
|
@staticmethod
|
358
361
|
def _register_validate_slices(slices: List[slice], reg_width: int) -> bool:
|
@@ -384,7 +387,7 @@ class SynthesisQuantumFunctionCall(BaseModel):
|
|
384
387
|
return dict()
|
385
388
|
if isinstance(params, CustomFunction):
|
386
389
|
if not isinstance(inputs, dict):
|
387
|
-
raise
|
390
|
+
raise ClassiqValueError(CUSTOM_FUNCTION_SINGLE_IO_ERROR)
|
388
391
|
return inputs
|
389
392
|
|
390
393
|
if isinstance(inputs, str):
|
@@ -442,7 +445,7 @@ class SynthesisQuantumFunctionCall(BaseModel):
|
|
442
445
|
if invalid_slicings:
|
443
446
|
error_msg.append(f"{BAD_OUTPUT_SLICING_MSG}: {invalid_slicings}")
|
444
447
|
if error_msg:
|
445
|
-
raise
|
448
|
+
raise ClassiqValueError("\n".join(error_msg))
|
446
449
|
|
447
450
|
@pydantic.validator("outputs")
|
448
451
|
def _validate_outputs(cls, outputs: IOType, values: Dict[str, Any]) -> IOType:
|
@@ -454,7 +457,7 @@ class SynthesisQuantumFunctionCall(BaseModel):
|
|
454
457
|
return outputs
|
455
458
|
if isinstance(params, CustomFunction):
|
456
459
|
if not isinstance(outputs, dict):
|
457
|
-
raise
|
460
|
+
raise ClassiqValueError(CUSTOM_FUNCTION_SINGLE_IO_ERROR)
|
458
461
|
return outputs
|
459
462
|
|
460
463
|
if isinstance(outputs, str):
|
@@ -494,7 +497,7 @@ class SynthesisQuantumFunctionCall(BaseModel):
|
|
494
497
|
if power != 1 and not function_params.is_powerable(
|
495
498
|
values.get("strict_zero_ios")
|
496
499
|
):
|
497
|
-
raise
|
500
|
+
raise ClassiqValueError("Cannot power this operator")
|
498
501
|
return power
|
499
502
|
|
500
503
|
@staticmethod
|
@@ -519,7 +522,7 @@ class SynthesisQuantumFunctionCall(BaseModel):
|
|
519
522
|
io_wire=io_wire,
|
520
523
|
function_name=type(params).__name__,
|
521
524
|
)
|
522
|
-
raise
|
525
|
+
raise ClassiqValueError(error_message)
|
523
526
|
|
524
527
|
@staticmethod
|
525
528
|
def _get_invalid_ios(
|
@@ -610,7 +613,9 @@ class SynthesisQuantumFunctionCall(BaseModel):
|
|
610
613
|
control_state.name in self.inputs_dict
|
611
614
|
or control_state.name in self.outputs_dict
|
612
615
|
):
|
613
|
-
raise
|
616
|
+
raise ClassiqValueError(
|
617
|
+
f"Control name: {control_state.name} already exists"
|
618
|
+
)
|
614
619
|
|
615
620
|
inputs, outputs = dict(self.inputs_dict), dict(self.outputs_dict)
|
616
621
|
inputs.update({control_state.name: input_wire})
|
@@ -6,7 +6,7 @@ from typing import Dict, List, Optional, Tuple, Union
|
|
6
6
|
import pydantic
|
7
7
|
from typing_extensions import TypeAlias
|
8
8
|
|
9
|
-
from classiq.interface.executor import
|
9
|
+
from classiq.interface.executor import quantum_code
|
10
10
|
from classiq.interface.executor.quantum_instruction_set import QuantumInstructionSet
|
11
11
|
from classiq.interface.executor.register_initialization import RegisterInitialization
|
12
12
|
from classiq.interface.generator.circuit_code.circuit_code import CircuitCodeInterface
|
@@ -21,7 +21,7 @@ from classiq.interface.generator.generated_circuit_data import (
|
|
21
21
|
GeneratedCircuitData,
|
22
22
|
)
|
23
23
|
from classiq.interface.generator.hardware.hardware_data import SynthesisHardwareData
|
24
|
-
from classiq.interface.generator.model.model import ExecutionModel
|
24
|
+
from classiq.interface.generator.model.model import ExecutionModel
|
25
25
|
from classiq.interface.generator.synthesis_metadata.synthesis_duration import (
|
26
26
|
SynthesisStepDurations,
|
27
27
|
)
|
@@ -51,11 +51,11 @@ def get_uuid_as_str() -> str:
|
|
51
51
|
return str(uuid.uuid4())
|
52
52
|
|
53
53
|
|
54
|
-
class
|
54
|
+
class QuantumProgram(VersionedModel, CircuitCodeInterface):
|
55
55
|
hardware_data: SynthesisHardwareData
|
56
56
|
initial_values: Optional[InitialConditions]
|
57
57
|
data: GeneratedCircuitData
|
58
|
-
model:
|
58
|
+
model: ExecutionModel
|
59
59
|
transpiled_circuit: Optional[TranspiledCircuitData]
|
60
60
|
creation_time: str = pydantic.Field(default_factory=datetime.utcnow().isoformat)
|
61
61
|
synthesis_duration: Optional[SynthesisStepDurations]
|
@@ -81,15 +81,15 @@ class GeneratedCircuit(VersionedModel, CircuitCodeInterface):
|
|
81
81
|
)
|
82
82
|
return self.program_circuit.get_code(instruction_set), instruction_set
|
83
83
|
|
84
|
-
def to_base_program(self) ->
|
84
|
+
def to_base_program(self) -> quantum_code.QuantumBaseCode:
|
85
85
|
code, syntax = self._default_program_code()
|
86
|
-
return
|
86
|
+
return quantum_code.QuantumBaseCode(code=code, syntax=syntax)
|
87
87
|
|
88
88
|
def to_program(
|
89
89
|
self,
|
90
90
|
initial_values: Optional[InitialConditions] = None,
|
91
91
|
instruction_set: Optional[QuantumInstructionSet] = None,
|
92
|
-
) ->
|
92
|
+
) -> quantum_code.QuantumCode:
|
93
93
|
initial_values = initial_values or self.initial_values
|
94
94
|
|
95
95
|
if instruction_set is not None:
|
@@ -106,7 +106,7 @@ class GeneratedCircuit(VersionedModel, CircuitCodeInterface):
|
|
106
106
|
)
|
107
107
|
else:
|
108
108
|
registers_initialization = None
|
109
|
-
return
|
109
|
+
return quantum_code.QuantumCode(
|
110
110
|
code=code,
|
111
111
|
syntax=syntax,
|
112
112
|
output_qubits_map=self.data.qubit_mapping.physical_outputs,
|
@@ -136,7 +136,7 @@ class GeneratedCircuit(VersionedModel, CircuitCodeInterface):
|
|
136
136
|
|
137
137
|
def save_results(self, filename: Optional[Union[str, Path]] = None) -> None:
|
138
138
|
"""
|
139
|
-
Saves
|
139
|
+
Saves quantum program results as json.
|
140
140
|
Parameters:
|
141
141
|
filename (Union[str, Path]): Optional, path + filename of file.
|
142
142
|
If filename supplied add `.json` suffix.
|
@@ -151,7 +151,7 @@ class GeneratedCircuit(VersionedModel, CircuitCodeInterface):
|
|
151
151
|
file.write(self.json(indent=4))
|
152
152
|
|
153
153
|
@classmethod
|
154
|
-
def from_qprog(cls, qprog: str) -> "
|
154
|
+
def from_qprog(cls, qprog: str) -> "QuantumProgram":
|
155
155
|
return cls.parse_raw(qprog)
|
156
156
|
|
157
157
|
@property
|
@@ -165,7 +165,3 @@ class GeneratedCircuit(VersionedModel, CircuitCodeInterface):
|
|
165
165
|
if self.transpiled_circuit and self._can_use_transpiled_code
|
166
166
|
else self
|
167
167
|
)
|
168
|
-
|
169
|
-
@property
|
170
|
-
def execution_model(self) -> ExecutionModel:
|
171
|
-
return self.model.classical_model()
|
@@ -4,6 +4,8 @@ from typing import Any, Dict, Generic, Optional, TypeVar
|
|
4
4
|
import pydantic
|
5
5
|
from pydantic.generics import GenericModel
|
6
6
|
|
7
|
+
from classiq.exceptions import ClassiqValueError
|
8
|
+
|
7
9
|
RangeType = TypeVar("RangeType", int, float)
|
8
10
|
|
9
11
|
# math.isclose is symmetric and well equipped to avoid unwanted scenarios while numpy's isn't
|
@@ -30,7 +32,7 @@ class Range(GenericModel, Generic[RangeType]):
|
|
30
32
|
and upper_bound is not None
|
31
33
|
and lower_bound > upper_bound
|
32
34
|
):
|
33
|
-
raise
|
35
|
+
raise ClassiqValueError("lower bound must not be greater than upper bound")
|
34
36
|
|
35
37
|
return values
|
36
38
|
|
@@ -3,6 +3,8 @@ from typing import Match, Optional, Tuple
|
|
3
3
|
|
4
4
|
from classiq.interface.generator.function_params import NAME_REGEX
|
5
5
|
|
6
|
+
from classiq.exceptions import ClassiqValueError
|
7
|
+
|
6
8
|
NAME = "name"
|
7
9
|
SLICING = "slicing"
|
8
10
|
SEPARATOR = ":"
|
@@ -33,9 +35,12 @@ def get_slice(slicing: Optional[str]) -> slice:
|
|
33
35
|
|
34
36
|
if len(split) == 1:
|
35
37
|
index_block = split[0]
|
36
|
-
|
37
|
-
|
38
|
-
|
38
|
+
try:
|
39
|
+
index = int(index_block)
|
40
|
+
except ValueError:
|
41
|
+
raise ClassiqValueError(
|
42
|
+
f"Index {index_block!r} is not an integer"
|
43
|
+
) from None
|
39
44
|
stop = index + 1 if index != -1 else None
|
40
45
|
return slice(index, stop, None)
|
41
46
|
|
@@ -9,6 +9,8 @@ from classiq.interface.generator.standard_gates.standard_gates import (
|
|
9
9
|
_StandardGate,
|
10
10
|
)
|
11
11
|
|
12
|
+
from classiq.exceptions import ClassiqValueError
|
13
|
+
|
12
14
|
CONTROLLED_GATE_CONTROL: str = "CTRL"
|
13
15
|
CONTROLLED_GATE_TARGET: str = DEFAULT_STANDARD_GATE_ARG_NAME
|
14
16
|
DEFAULT_NUM_CTRL_QUBITS: int = 1
|
@@ -58,12 +60,12 @@ class ControlledGateWithState(ControlledGate): # type: ignore[misc]
|
|
58
60
|
ctrl_state = ctrl_state if ctrl_state is not None else "1" * num_ctrl_qubits
|
59
61
|
|
60
62
|
if isinstance(ctrl_state, str) and len(ctrl_state) != num_ctrl_qubits:
|
61
|
-
raise
|
63
|
+
raise ClassiqValueError(
|
62
64
|
f"Invalid control state: {ctrl_state!r}. "
|
63
65
|
f"Expected {num_ctrl_qubits} qubits"
|
64
66
|
)
|
65
67
|
elif isinstance(ctrl_state, int) and ctrl_state >= 2**num_ctrl_qubits:
|
66
|
-
raise
|
68
|
+
raise ClassiqValueError(
|
67
69
|
f"Invalid control state: {ctrl_state}. "
|
68
70
|
f"Expected value between 0 and {2**num_ctrl_qubits-1}"
|
69
71
|
)
|
@@ -5,6 +5,7 @@ from classiq.interface.generator.preferences.optimization import (
|
|
5
5
|
)
|
6
6
|
|
7
7
|
from classiq._internals.enum_utils import StrEnum
|
8
|
+
from classiq.exceptions import ClassiqValueError
|
8
9
|
|
9
10
|
_AMPLITUDE_SUPPORTING_METRICS: FrozenSet = frozenset(
|
10
11
|
{"L2", "L1", "MAX_PROBABILITY", "TOTAL_VARIATION"}
|
@@ -30,7 +31,7 @@ class Metrics(StrEnum):
|
|
30
31
|
try:
|
31
32
|
return Metrics(sp_opt_method.value)
|
32
33
|
except ValueError:
|
33
|
-
raise
|
34
|
+
raise ClassiqValueError(
|
34
35
|
f"Failed to convert {sp_opt_method} to an error metric"
|
35
36
|
) from None
|
36
37
|
|
@@ -21,6 +21,8 @@ from classiq.interface.generator.validations.validator_functions import (
|
|
21
21
|
validate_amplitudes,
|
22
22
|
)
|
23
23
|
|
24
|
+
from classiq.exceptions import ClassiqValueError
|
25
|
+
|
24
26
|
|
25
27
|
class StatePreparation(StatePreparationABC):
|
26
28
|
amplitudes: Optional[Amplitudes] = pydantic.Field(
|
@@ -46,7 +48,7 @@ class StatePreparation(StatePreparationABC):
|
|
46
48
|
if amplitudes.ndim == 1:
|
47
49
|
return validate_amplitudes(tuple(amplitudes))
|
48
50
|
|
49
|
-
raise
|
51
|
+
raise ClassiqValueError(
|
50
52
|
"Invalid amplitudes were given, please ensure the amplitude is a vector of float in the form of either tuple or list or numpy array"
|
51
53
|
)
|
52
54
|
|
@@ -64,7 +66,7 @@ class StatePreparation(StatePreparationABC):
|
|
64
66
|
if probabilities.ndim == 1:
|
65
67
|
return PMF(pmf=probabilities.tolist())
|
66
68
|
|
67
|
-
raise
|
69
|
+
raise ClassiqValueError(
|
68
70
|
"Invalid probabilities were given, please ensure the probabilities is a vector of float in the form of either tuple or list or numpy array"
|
69
71
|
)
|
70
72
|
|
@@ -80,7 +82,7 @@ class StatePreparation(StatePreparationABC):
|
|
80
82
|
if not Metrics(metric).supports_amplitudes
|
81
83
|
}
|
82
84
|
if unsupported_metrics:
|
83
|
-
raise
|
85
|
+
raise ClassiqValueError(
|
84
86
|
f"{unsupported_metrics} are not supported for amplitude preparation"
|
85
87
|
)
|
86
88
|
return error_metric
|
@@ -93,7 +95,7 @@ class StatePreparation(StatePreparationABC):
|
|
93
95
|
amplitudes = values.get("amplitudes")
|
94
96
|
probabilities = values.get("probabilities")
|
95
97
|
if amplitudes is not None and probabilities is not None:
|
96
|
-
raise
|
98
|
+
raise ClassiqValueError(
|
97
99
|
"StatePreparation can't get both probabilities and amplitudes"
|
98
100
|
)
|
99
101
|
return values
|
@@ -102,5 +104,5 @@ class StatePreparation(StatePreparationABC):
|
|
102
104
|
def num_state_qubits(self) -> int:
|
103
105
|
distribution = self.probabilities or self.amplitudes
|
104
106
|
if distribution is None:
|
105
|
-
raise
|
107
|
+
raise ClassiqValueError("Must have either probabilities or amplitudes")
|
106
108
|
return num_of_qubits(distribution)
|
@@ -1,4 +1,4 @@
|
|
1
|
-
from typing import List
|
1
|
+
from typing import Any, Dict, List
|
2
2
|
|
3
3
|
import numpy as np
|
4
4
|
import pydantic
|
@@ -11,6 +11,8 @@ from classiq.interface.generator.function_params import (
|
|
11
11
|
DEFAULT_OUTPUT_NAME,
|
12
12
|
)
|
13
13
|
|
14
|
+
from classiq.exceptions import ClassiqValueError
|
15
|
+
|
14
16
|
|
15
17
|
class StatePropagator(function_params.FunctionParams):
|
16
18
|
"""
|
@@ -33,16 +35,25 @@ class StatePropagator(function_params.FunctionParams):
|
|
33
35
|
)
|
34
36
|
|
35
37
|
@pydantic.validator("start_state_vector", always=True)
|
36
|
-
def validate_start_state(
|
38
|
+
def validate_start_state(
|
39
|
+
cls, start_state_vector: List[Complex], values: Dict[str, Any]
|
40
|
+
) -> List[Complex]:
|
37
41
|
end_state_vector = values.get("end_state_vector")
|
42
|
+
if end_state_vector is None:
|
43
|
+
raise ClassiqValueError(
|
44
|
+
"Cannot validate start_start_vector without end_state_vector"
|
45
|
+
)
|
46
|
+
|
38
47
|
num_qubits = cls._num_qubits(end_state_vector)
|
39
48
|
if len(start_state_vector) == 0:
|
40
|
-
default_start_state_vector = [0.0 for _ in range(2**num_qubits)]
|
41
|
-
default_start_state_vector[0] = 1.0
|
49
|
+
default_start_state_vector = [Complex(0.0) for _ in range(2**num_qubits)]
|
50
|
+
default_start_state_vector[0] = Complex(1.0)
|
42
51
|
start_state_vector = default_start_state_vector
|
43
52
|
|
44
53
|
if len(start_state_vector) != len(end_state_vector):
|
45
|
-
raise
|
54
|
+
raise ClassiqValueError(
|
55
|
+
"Start and end state vectors are of non-equal length"
|
56
|
+
)
|
46
57
|
|
47
58
|
return start_state_vector
|
48
59
|
|