classiq 0.51.0__py3-none-any.whl → 0.52.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/_internals/api_wrapper.py +41 -15
- classiq/_internals/authentication/auth0.py +20 -4
- classiq/_internals/authentication/password_manager.py +16 -4
- classiq/_internals/client.py +2 -2
- classiq/_internals/host_checker.py +5 -3
- classiq/_internals/jobs.py +3 -3
- classiq/analyzer/analyzer_utilities.py +1 -1
- classiq/applications/chemistry/ground_state_problem.py +1 -1
- classiq/applications/combinatorial_helpers/pyomo_utils.py +3 -1
- classiq/applications/qnn/gradients/quantum_gradient.py +1 -1
- classiq/applications/qnn/qlayer.py +2 -2
- classiq/execution/__init__.py +3 -0
- classiq/execution/execution_session.py +2 -2
- classiq/execution/iqcc.py +63 -0
- classiq/execution/jobs.py +2 -2
- classiq/executor.py +2 -2
- classiq/interface/_version.py +1 -1
- classiq/interface/analyzer/analysis_params.py +19 -9
- classiq/interface/analyzer/cytoscape_graph.py +10 -3
- classiq/interface/analyzer/result.py +6 -5
- classiq/interface/applications/qsvm.py +13 -12
- classiq/interface/backend/backend_preferences.py +78 -105
- classiq/interface/backend/ionq/ionq_quantum_program.py +12 -19
- classiq/interface/backend/pydantic_backend.py +24 -12
- classiq/interface/backend/quantum_backend_providers.py +2 -0
- classiq/interface/chemistry/fermionic_operator.py +7 -7
- classiq/interface/chemistry/ground_state_problem.py +23 -18
- classiq/interface/chemistry/molecule.py +10 -5
- classiq/interface/chemistry/operator.py +71 -44
- classiq/interface/combinatorial_optimization/mht_qaoa_input.py +2 -1
- classiq/interface/debug_info/debug_info.py +3 -4
- classiq/interface/execution/iqcc.py +21 -0
- classiq/interface/execution/jobs.py +10 -10
- classiq/interface/executor/aws_execution_cost.py +37 -20
- classiq/interface/executor/execution_preferences.py +1 -2
- classiq/interface/executor/execution_request.py +2 -2
- classiq/interface/executor/execution_result.py +4 -2
- classiq/interface/executor/iqae_result.py +1 -1
- classiq/interface/executor/optimizer_preferences.py +14 -10
- classiq/interface/executor/quantum_code.py +21 -16
- classiq/interface/executor/register_initialization.py +10 -10
- classiq/interface/executor/result.py +19 -16
- classiq/interface/executor/vqe_result.py +1 -1
- classiq/interface/finance/function_input.py +27 -18
- classiq/interface/finance/log_normal_model_input.py +2 -2
- classiq/interface/finance/model_input.py +3 -2
- classiq/interface/generator/amplitude_loading.py +8 -6
- classiq/interface/generator/arith/argument_utils.py +24 -0
- classiq/interface/generator/arith/arithmetic.py +5 -3
- classiq/interface/generator/arith/arithmetic_expression_abc.py +36 -14
- classiq/interface/generator/arith/arithmetic_operations.py +6 -3
- classiq/interface/generator/arith/binary_ops.py +88 -63
- classiq/interface/generator/arith/extremum_operations.py +22 -13
- classiq/interface/generator/arith/logical_ops.py +6 -4
- classiq/interface/generator/arith/number_utils.py +3 -3
- classiq/interface/generator/arith/register_user_input.py +32 -17
- classiq/interface/generator/arith/unary_ops.py +5 -4
- classiq/interface/generator/chemistry_function_params.py +2 -1
- classiq/interface/generator/circuit_code/circuit_code.py +2 -1
- classiq/interface/generator/commuting_pauli_exponentiation.py +6 -5
- classiq/interface/generator/complex_type.py +14 -18
- classiq/interface/generator/control_state.py +32 -26
- classiq/interface/generator/expressions/expression.py +6 -5
- classiq/interface/generator/expressions/qmod_qscalar_proxy.py +3 -3
- classiq/interface/generator/function_params.py +22 -39
- classiq/interface/generator/functions/classical_function_declaration.py +1 -1
- classiq/interface/generator/functions/classical_type.py +32 -23
- classiq/interface/generator/functions/concrete_types.py +8 -7
- classiq/interface/generator/functions/function_declaration.py +4 -5
- classiq/interface/generator/functions/type_name.py +5 -4
- classiq/interface/generator/generated_circuit_data.py +9 -6
- classiq/interface/generator/grover_diffuser.py +26 -18
- classiq/interface/generator/grover_operator.py +32 -22
- classiq/interface/generator/hamiltonian_evolution/exponentiation.py +3 -4
- classiq/interface/generator/hamiltonian_evolution/qdrift.py +4 -4
- classiq/interface/generator/hamiltonian_evolution/suzuki_trotter.py +8 -7
- classiq/interface/generator/hardware/hardware_data.py +27 -26
- classiq/interface/generator/hardware_efficient_ansatz.py +11 -6
- classiq/interface/generator/hartree_fock.py +2 -1
- classiq/interface/generator/identity.py +7 -2
- classiq/interface/generator/linear_pauli_rotations.py +27 -14
- classiq/interface/generator/mcu.py +15 -12
- classiq/interface/generator/mcx.py +18 -10
- classiq/interface/generator/model/constraints.py +4 -2
- classiq/interface/generator/model/model.py +2 -1
- classiq/interface/generator/model/preferences/preferences.py +30 -32
- classiq/interface/generator/oracles/custom_oracle.py +13 -10
- classiq/interface/generator/piecewise_linear_amplitude_loading.py +37 -21
- classiq/interface/generator/qpe.py +38 -26
- classiq/interface/generator/qsvm.py +4 -4
- classiq/interface/generator/quantum_function_call.py +57 -44
- classiq/interface/generator/quantum_program.py +8 -6
- classiq/interface/generator/range_types.py +10 -11
- classiq/interface/generator/standard_gates/controlled_standard_gates.py +9 -5
- classiq/interface/generator/standard_gates/standard_angle_metaclass.py +2 -6
- classiq/interface/generator/standard_gates/u_gate.py +7 -10
- classiq/interface/generator/state_preparation/computational_basis_state_preparation.py +2 -1
- classiq/interface/generator/state_preparation/distributions.py +12 -12
- classiq/interface/generator/state_preparation/state_preparation.py +22 -16
- classiq/interface/generator/types/enum_declaration.py +2 -1
- classiq/interface/generator/ucc.py +2 -1
- classiq/interface/generator/unitary_gate.py +2 -1
- classiq/interface/generator/user_defined_function_params.py +3 -0
- classiq/interface/generator/visitor.py +1 -1
- classiq/interface/hardware.py +18 -3
- classiq/interface/helpers/custom_pydantic_types.py +38 -47
- classiq/interface/helpers/pydantic_model_helpers.py +3 -2
- classiq/interface/helpers/versioned_model.py +1 -4
- classiq/interface/ide/ide_data.py +5 -5
- classiq/interface/ide/visual_model.py +5 -5
- classiq/interface/interface_version.py +1 -1
- classiq/interface/jobs.py +12 -22
- classiq/interface/model/bind_operation.py +2 -1
- classiq/interface/model/classical_parameter_declaration.py +10 -4
- classiq/interface/model/handle_binding.py +20 -24
- classiq/interface/model/inplace_binary_operation.py +16 -9
- classiq/interface/model/model.py +21 -11
- classiq/interface/model/port_declaration.py +10 -7
- classiq/interface/model/quantum_expressions/arithmetic_operation.py +6 -4
- classiq/interface/model/quantum_function_declaration.py +22 -11
- classiq/interface/model/quantum_statement.py +6 -7
- classiq/interface/model/quantum_type.py +22 -19
- classiq/interface/model/statement_block.py +9 -9
- classiq/interface/server/global_versions.py +4 -5
- classiq/interface/server/routes.py +8 -0
- classiq/model_expansions/evaluators/parameter_types.py +3 -3
- classiq/model_expansions/expression_renamer.py +1 -1
- classiq/model_expansions/quantum_operations/control.py +11 -12
- classiq/model_expansions/quantum_operations/emitter.py +22 -0
- classiq/model_expansions/quantum_operations/expression_operation.py +2 -20
- classiq/model_expansions/quantum_operations/inplace_binary_operation.py +65 -14
- classiq/model_expansions/quantum_operations/invert.py +1 -1
- classiq/model_expansions/quantum_operations/phase.py +4 -5
- classiq/model_expansions/quantum_operations/power.py +1 -1
- classiq/model_expansions/quantum_operations/quantum_assignment_operation.py +50 -9
- classiq/model_expansions/quantum_operations/variable_decleration.py +2 -2
- classiq/model_expansions/quantum_operations/within_apply.py +1 -1
- classiq/qmod/builtins/__init__.py +1 -3
- classiq/qmod/builtins/functions/__init__.py +4 -0
- classiq/qmod/builtins/functions/arithmetic.py +10 -0
- classiq/qmod/create_model_function.py +14 -8
- classiq/qmod/quantum_expandable.py +22 -9
- classiq/qmod/quantum_function.py +1 -1
- classiq/qmod/semantics/static_semantics_visitor.py +3 -1
- classiq/qmod/type_attribute_remover.py +1 -1
- classiq/qmod/write_qmod.py +2 -4
- classiq/synthesis.py +11 -13
- {classiq-0.51.0.dist-info → classiq-0.52.0.dist-info}/METADATA +3 -2
- {classiq-0.51.0.dist-info → classiq-0.52.0.dist-info}/RECORD +150 -148
- {classiq-0.51.0.dist-info → classiq-0.52.0.dist-info}/WHEEL +0 -0
@@ -59,13 +59,15 @@ def _get_formatted_utc_current_time() -> str:
|
|
59
59
|
|
60
60
|
class QuantumProgram(VersionedModel, CircuitCodeInterface):
|
61
61
|
hardware_data: SynthesisHardwareData
|
62
|
-
initial_values: Optional[InitialConditions]
|
62
|
+
initial_values: Optional[InitialConditions] = pydantic.Field(default=None)
|
63
63
|
data: GeneratedCircuitData
|
64
64
|
model: ExecutionModel
|
65
|
-
transpiled_circuit: Optional[TranspiledCircuitData]
|
65
|
+
transpiled_circuit: Optional[TranspiledCircuitData] = pydantic.Field(default=None)
|
66
66
|
creation_time: str = pydantic.Field(default_factory=_get_formatted_utc_current_time)
|
67
|
-
synthesis_duration: Optional[SynthesisStepDurations]
|
68
|
-
debug_info: Optional[List[FunctionDebugInfoInterface]]
|
67
|
+
synthesis_duration: Optional[SynthesisStepDurations] = pydantic.Field(default=None)
|
68
|
+
debug_info: Optional[List[FunctionDebugInfoInterface]] = pydantic.Field(
|
69
|
+
default=None
|
70
|
+
)
|
69
71
|
program_id: str = pydantic.Field(default_factory=get_uuid_as_str)
|
70
72
|
execution_primitives_input: Optional[PrimitivesInput] = pydantic.Field(default=None)
|
71
73
|
|
@@ -154,7 +156,7 @@ class QuantumProgram(VersionedModel, CircuitCodeInterface):
|
|
154
156
|
filename = f"synthesised_circuit_{self.creation_time}.json"
|
155
157
|
|
156
158
|
with open(filename, "w") as file:
|
157
|
-
file.write(self.
|
159
|
+
file.write(self.model_dump_json(indent=4))
|
158
160
|
|
159
161
|
@classmethod
|
160
162
|
def from_qprog(cls, qprog: str) -> "QuantumProgram":
|
@@ -167,7 +169,7 @@ class QuantumProgram(VersionedModel, CircuitCodeInterface):
|
|
167
169
|
Returns:
|
168
170
|
QuantumProgram: The `QuantumProgram` instance.
|
169
171
|
"""
|
170
|
-
return cls.
|
172
|
+
return cls.model_validate_json(qprog)
|
171
173
|
|
172
174
|
@property
|
173
175
|
def _can_use_transpiled_code(self) -> bool:
|
@@ -1,8 +1,9 @@
|
|
1
1
|
import math
|
2
|
-
from typing import
|
2
|
+
from typing import Generic, Optional, TypeVar
|
3
3
|
|
4
4
|
import pydantic
|
5
|
-
from pydantic
|
5
|
+
from pydantic import BaseModel, ConfigDict
|
6
|
+
from typing_extensions import Self
|
6
7
|
|
7
8
|
from classiq.interface.exceptions import ClassiqValueError
|
8
9
|
|
@@ -15,17 +16,15 @@ DEF_ATOL: float = 1e-08
|
|
15
16
|
DEF_RTOL: float = 1e-05
|
16
17
|
|
17
18
|
|
18
|
-
class Range(
|
19
|
+
class Range(BaseModel, Generic[RangeType]):
|
19
20
|
lower_bound: Optional[RangeType] = None
|
20
21
|
upper_bound: Optional[RangeType] = None
|
22
|
+
model_config = ConfigDict(frozen=True)
|
21
23
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
def _validate_bounds_order(cls, values: Dict[str, Any]) -> Dict[str, Any]:
|
27
|
-
lower_bound = values.get("lower_bound")
|
28
|
-
upper_bound = values.get("upper_bound")
|
24
|
+
@pydantic.model_validator(mode="after")
|
25
|
+
def _validate_bounds_order(self) -> Self:
|
26
|
+
lower_bound = self.lower_bound
|
27
|
+
upper_bound = self.upper_bound
|
29
28
|
|
30
29
|
if (
|
31
30
|
lower_bound is not None
|
@@ -34,7 +33,7 @@ class Range(GenericModel, Generic[RangeType]):
|
|
34
33
|
):
|
35
34
|
raise ClassiqValueError("lower bound must not be greater than upper bound")
|
36
35
|
|
37
|
-
return
|
36
|
+
return self
|
38
37
|
|
39
38
|
def is_lower_bound_sat_by(
|
40
39
|
self, value: float, atol: float = DEF_ATOL, rtol: float = DEF_RTOL
|
@@ -1,6 +1,7 @@
|
|
1
|
-
from typing import
|
1
|
+
from typing import Literal, Optional, Union
|
2
2
|
|
3
3
|
import pydantic
|
4
|
+
from pydantic_core.core_schema import ValidationInfo
|
4
5
|
|
5
6
|
from classiq.interface.exceptions import ClassiqValueError
|
6
7
|
from classiq.interface.generator.arith.register_user_input import RegisterUserInput
|
@@ -48,14 +49,17 @@ class ControlledGateWithState(ControlledGate): # type: ignore[misc]
|
|
48
49
|
ctrl_state: CtrlState = pydantic.Field(
|
49
50
|
description="The control state in decimal or as a bit string (e.g. '1011'). If not specified, the control "
|
50
51
|
"state is 2**num_ctrl_qubits - 1.\n"
|
51
|
-
"The gate will be performed if the state of the control qubits matches the control state"
|
52
|
+
"The gate will be performed if the state of the control qubits matches the control state",
|
53
|
+
default=None,
|
54
|
+
validate_default=True,
|
52
55
|
)
|
53
56
|
|
54
|
-
@pydantic.
|
57
|
+
@pydantic.field_validator("ctrl_state")
|
58
|
+
@classmethod
|
55
59
|
def _validate_ctrl_state(
|
56
|
-
cls, ctrl_state: CtrlState,
|
60
|
+
cls, ctrl_state: CtrlState, info: ValidationInfo
|
57
61
|
) -> CtrlState:
|
58
|
-
num_ctrl_qubits: int =
|
62
|
+
num_ctrl_qubits: int = info.data.get("num_ctrl_qubits", DEFAULT_NUM_CTRL_QUBITS)
|
59
63
|
ctrl_state = ctrl_state if ctrl_state is not None else "1" * num_ctrl_qubits
|
60
64
|
|
61
65
|
if isinstance(ctrl_state, str) and len(ctrl_state) != num_ctrl_qubits:
|
@@ -2,7 +2,7 @@ from typing import Any
|
|
2
2
|
|
3
3
|
import pydantic
|
4
4
|
|
5
|
-
from classiq.interface.generator.
|
5
|
+
from classiq.interface.generator.function_params import FunctionParamsNumericParameter
|
6
6
|
|
7
7
|
PydanticMetaClass: Any = type(pydantic.BaseModel)
|
8
8
|
|
@@ -16,14 +16,10 @@ class MyMetaAngledClass(type):
|
|
16
16
|
@staticmethod
|
17
17
|
def _create_new_namespace(namespace: dict, **kwargs: Any) -> dict:
|
18
18
|
angles = kwargs.get("angles", [])
|
19
|
-
annotations = {angle:
|
20
|
-
fields = {
|
21
|
-
angle: pydantic.fields.FieldInfo(is_exec_param=True) for angle in angles
|
22
|
-
}
|
19
|
+
annotations = {angle: FunctionParamsNumericParameter for angle in angles}
|
23
20
|
original_annotations = namespace.get("__annotations__", {})
|
24
21
|
return {
|
25
22
|
**namespace,
|
26
|
-
**fields,
|
27
23
|
**{"__annotations__": {**original_annotations, **annotations}},
|
28
24
|
}
|
29
25
|
|
@@ -2,7 +2,7 @@ import pydantic
|
|
2
2
|
|
3
3
|
from classiq.interface.generator import function_params
|
4
4
|
from classiq.interface.generator.arith.register_user_input import RegisterUserInput
|
5
|
-
from classiq.interface.generator.
|
5
|
+
from classiq.interface.generator.function_params import FunctionParamsNumericParameter
|
6
6
|
from classiq.interface.generator.standard_gates.standard_gates import (
|
7
7
|
DEFAULT_STANDARD_GATE_ARG_NAME,
|
8
8
|
)
|
@@ -18,24 +18,20 @@ class UGate(function_params.FunctionParams):
|
|
18
18
|
e^(i*phi)*sin(theta/2) & e^(i*(phi+lam))*cos(theta/2) \\
|
19
19
|
"""
|
20
20
|
|
21
|
-
theta:
|
21
|
+
theta: FunctionParamsNumericParameter = pydantic.Field(
|
22
22
|
description="Angle to rotate by the Y-axis.",
|
23
|
-
is_exec_param=True,
|
24
23
|
)
|
25
24
|
|
26
|
-
phi:
|
25
|
+
phi: FunctionParamsNumericParameter = pydantic.Field(
|
27
26
|
description="First angle to rotate by the Z-axis.",
|
28
|
-
is_exec_param=True,
|
29
27
|
)
|
30
28
|
|
31
|
-
lam:
|
29
|
+
lam: FunctionParamsNumericParameter = pydantic.Field(
|
32
30
|
description="Second angle to rotate by the Z-axis.",
|
33
|
-
is_exec_param=True,
|
34
31
|
)
|
35
32
|
|
36
|
-
gam:
|
33
|
+
gam: FunctionParamsNumericParameter = pydantic.Field(
|
37
34
|
description="Angle to apply phase gate by.",
|
38
|
-
is_exec_param=True,
|
39
35
|
)
|
40
36
|
|
41
37
|
_inputs = pydantic.PrivateAttr(
|
@@ -56,5 +52,6 @@ class UGate(function_params.FunctionParams):
|
|
56
52
|
@property
|
57
53
|
def is_parametric(self) -> bool:
|
58
54
|
return not all(
|
59
|
-
isinstance(getattr(self, angle), (float, int))
|
55
|
+
isinstance(getattr(self, angle), (float, int))
|
56
|
+
for angle in ["theta", "phi", "lam", "gam"]
|
60
57
|
)
|
@@ -12,7 +12,8 @@ class ComputationalBasisStatePreparation(StatePreparationABC):
|
|
12
12
|
description="binary computational state to create"
|
13
13
|
)
|
14
14
|
|
15
|
-
@pydantic.
|
15
|
+
@pydantic.field_validator("computational_state")
|
16
|
+
@classmethod
|
16
17
|
def _validate_computational_state(
|
17
18
|
cls, computational_state: PydanticNonEmptyString
|
18
19
|
) -> PydanticNonEmptyString:
|
@@ -1,7 +1,8 @@
|
|
1
|
-
from typing import Collection, Tuple, Union
|
1
|
+
from typing import Collection, Sequence, Tuple, Union
|
2
2
|
|
3
3
|
import pydantic
|
4
4
|
from numpy.typing import ArrayLike
|
5
|
+
from pydantic import ConfigDict
|
5
6
|
|
6
7
|
from classiq.interface.generator.validations.validator_functions import (
|
7
8
|
validate_probabilities,
|
@@ -11,20 +12,21 @@ from classiq.interface.helpers.custom_pydantic_types import PydanticProbabilityF
|
|
11
12
|
|
12
13
|
class PMF(pydantic.BaseModel):
|
13
14
|
pmf: Tuple[PydanticProbabilityFloat, ...]
|
14
|
-
_validate_amplitudes = pydantic.validator("pmf", allow_reuse=True)(
|
15
|
-
validate_probabilities
|
16
|
-
)
|
17
15
|
|
18
|
-
|
19
|
-
|
16
|
+
@pydantic.field_validator("pmf")
|
17
|
+
@classmethod
|
18
|
+
def _validate_pmf(
|
19
|
+
cls, pmf: Tuple[PydanticProbabilityFloat, ...]
|
20
|
+
) -> Sequence[PydanticProbabilityFloat]:
|
21
|
+
return validate_probabilities(cls, pmf)
|
22
|
+
|
23
|
+
model_config = ConfigDict(frozen=True)
|
20
24
|
|
21
25
|
|
22
26
|
class GaussianMoments(pydantic.BaseModel):
|
23
27
|
mu: float
|
24
28
|
sigma: pydantic.PositiveFloat
|
25
|
-
|
26
|
-
class Config:
|
27
|
-
frozen = True
|
29
|
+
model_config = ConfigDict(frozen=True)
|
28
30
|
|
29
31
|
|
30
32
|
class GaussianMixture(pydantic.BaseModel):
|
@@ -32,9 +34,7 @@ class GaussianMixture(pydantic.BaseModel):
|
|
32
34
|
num_qubits: pydantic.PositiveInt = pydantic.Field(
|
33
35
|
description="Number of qubits for the provided state."
|
34
36
|
)
|
35
|
-
|
36
|
-
class Config:
|
37
|
-
frozen = True
|
37
|
+
model_config = ConfigDict(frozen=True)
|
38
38
|
|
39
39
|
|
40
40
|
Probabilities = Union[PMF, GaussianMixture]
|
@@ -1,7 +1,9 @@
|
|
1
|
-
from typing import
|
1
|
+
from typing import Dict, Optional, Union
|
2
2
|
|
3
3
|
import numpy as np
|
4
4
|
import pydantic
|
5
|
+
from pydantic_core.core_schema import ValidationInfo
|
6
|
+
from typing_extensions import Self
|
5
7
|
|
6
8
|
from classiq.interface.exceptions import ClassiqValueError
|
7
9
|
from classiq.interface.generator.range_types import NonNegativeFloatRange
|
@@ -25,10 +27,14 @@ from classiq.interface.generator.validations.validator_functions import (
|
|
25
27
|
|
26
28
|
class StatePreparation(StatePreparationABC):
|
27
29
|
amplitudes: Optional[Amplitudes] = pydantic.Field(
|
28
|
-
description="vector of probabilities",
|
30
|
+
description="vector of probabilities",
|
31
|
+
default=None,
|
32
|
+
validate_default=True,
|
29
33
|
)
|
30
34
|
probabilities: Optional[Probabilities] = pydantic.Field(
|
31
|
-
description="vector of amplitudes",
|
35
|
+
description="vector of amplitudes",
|
36
|
+
default=None,
|
37
|
+
validate_default=True,
|
32
38
|
)
|
33
39
|
error_metric: Dict[Metrics, NonNegativeFloatRange] = pydantic.Field(
|
34
40
|
default_factory=lambda: {
|
@@ -37,7 +43,8 @@ class StatePreparation(StatePreparationABC):
|
|
37
43
|
)
|
38
44
|
# The order of validations is important: amplitudes, probabilities, error_metric
|
39
45
|
|
40
|
-
@pydantic.
|
46
|
+
@pydantic.field_validator("amplitudes", mode="before")
|
47
|
+
@classmethod
|
41
48
|
def _initialize_amplitudes(
|
42
49
|
cls, amplitudes: Optional[FlexibleAmplitudes]
|
43
50
|
) -> Optional[Amplitudes]:
|
@@ -51,7 +58,8 @@ class StatePreparation(StatePreparationABC):
|
|
51
58
|
"Invalid amplitudes were given, please ensure the amplitude is a vector of float in the form of either tuple or list or numpy array"
|
52
59
|
)
|
53
60
|
|
54
|
-
@pydantic.
|
61
|
+
@pydantic.field_validator("probabilities", mode="before")
|
62
|
+
@classmethod
|
55
63
|
def _initialize_probabilities(
|
56
64
|
cls, probabilities: Optional[FlexibleProbabilities]
|
57
65
|
) -> Optional[Union[PMF, GaussianMixture, dict]]:
|
@@ -69,11 +77,12 @@ class StatePreparation(StatePreparationABC):
|
|
69
77
|
"Invalid probabilities were given, please ensure the probabilities is a vector of float in the form of either tuple or list or numpy array"
|
70
78
|
)
|
71
79
|
|
72
|
-
@pydantic.
|
80
|
+
@pydantic.field_validator("error_metric", mode="before")
|
81
|
+
@classmethod
|
73
82
|
def _validate_error_metric(
|
74
|
-
cls, error_metric: Dict[Metrics, NonNegativeFloatRange],
|
83
|
+
cls, error_metric: Dict[Metrics, NonNegativeFloatRange], info: ValidationInfo
|
75
84
|
) -> Dict[Metrics, NonNegativeFloatRange]:
|
76
|
-
if not
|
85
|
+
if not info.data.get("amplitudes"):
|
77
86
|
return error_metric
|
78
87
|
unsupported_metrics = {
|
79
88
|
Metrics(metric).value
|
@@ -86,18 +95,15 @@ class StatePreparation(StatePreparationABC):
|
|
86
95
|
)
|
87
96
|
return error_metric
|
88
97
|
|
89
|
-
@pydantic.
|
90
|
-
def _validate_either_probabilities_or_amplitudes(
|
91
|
-
|
92
|
-
|
93
|
-
) -> Optional[Union[PMF, GaussianMixture, dict]]:
|
94
|
-
amplitudes = values.get("amplitudes")
|
95
|
-
probabilities = values.get("probabilities")
|
98
|
+
@pydantic.model_validator(mode="after")
|
99
|
+
def _validate_either_probabilities_or_amplitudes(self) -> Self:
|
100
|
+
amplitudes = self.amplitudes
|
101
|
+
probabilities = self.probabilities
|
96
102
|
if amplitudes is not None and probabilities is not None:
|
97
103
|
raise ClassiqValueError(
|
98
104
|
"StatePreparation can't get both probabilities and amplitudes"
|
99
105
|
)
|
100
|
-
return
|
106
|
+
return self
|
101
107
|
|
102
108
|
@property
|
103
109
|
def num_state_qubits(self) -> int:
|
@@ -16,7 +16,8 @@ class EnumDeclaration(HashableASTNode):
|
|
16
16
|
description="Dictionary of member names and their values",
|
17
17
|
)
|
18
18
|
|
19
|
-
@pydantic.
|
19
|
+
@pydantic.field_validator("members")
|
20
|
+
@classmethod
|
20
21
|
def _validate_members(cls, members: Dict[str, int]) -> Dict[str, int]:
|
21
22
|
underscore_members = [
|
22
23
|
member for member in members.keys() if member.startswith("_")
|
@@ -41,7 +41,8 @@ class UCC(ChemistryFunctionParams):
|
|
41
41
|
description="Prefix for the generated parameters",
|
42
42
|
)
|
43
43
|
|
44
|
-
@pydantic.
|
44
|
+
@pydantic.field_validator("excitations")
|
45
|
+
@classmethod
|
45
46
|
def _validate_excitations(cls, excitations: EXCITATIONS_TYPE) -> EXCITATIONS_TYPE:
|
46
47
|
if isinstance(excitations, int):
|
47
48
|
if excitations not in _EXCITATIONS_DICT.values():
|
@@ -25,7 +25,8 @@ class UnitaryGate(function_params.FunctionParams):
|
|
25
25
|
)
|
26
26
|
|
27
27
|
# TODO - decide if to include assertion on the unitarity of the matrix. It is already done in Qiskit and could be computationally expensive
|
28
|
-
@pydantic.
|
28
|
+
@pydantic.field_validator("data")
|
29
|
+
@classmethod
|
29
30
|
def validate_data(cls, data: DataArray) -> DataArray:
|
30
31
|
data_np = np.array(data, dtype=object)
|
31
32
|
if data_np.ndim != 2:
|
@@ -1,6 +1,7 @@
|
|
1
1
|
from typing import Mapping
|
2
2
|
|
3
3
|
import pydantic
|
4
|
+
from pydantic import ConfigDict
|
4
5
|
|
5
6
|
from classiq.interface.generator.arith.register_user_input import RegisterArithmeticInfo
|
6
7
|
from classiq.interface.generator.function_params import ArithmeticIODict, FunctionParams
|
@@ -11,6 +12,8 @@ class CustomFunction(FunctionParams):
|
|
11
12
|
A user-defined custom function parameters object.
|
12
13
|
"""
|
13
14
|
|
15
|
+
model_config = ConfigDict(frozen=True, extra="forbid")
|
16
|
+
|
14
17
|
_name: str = pydantic.PrivateAttr(default="")
|
15
18
|
|
16
19
|
input_decls: ArithmeticIODict = pydantic.Field(
|
classiq/interface/hardware.py
CHANGED
@@ -2,9 +2,20 @@ import datetime
|
|
2
2
|
from typing import TYPE_CHECKING, List, Optional, Tuple
|
3
3
|
|
4
4
|
import pydantic
|
5
|
+
from typing_extensions import Annotated
|
5
6
|
|
6
7
|
from classiq.interface.enum_utils import StrEnum
|
7
8
|
|
9
|
+
QueueTime = Annotated[
|
10
|
+
Optional[datetime.timedelta],
|
11
|
+
pydantic.PlainSerializer(
|
12
|
+
lambda _timedelta: (
|
13
|
+
_timedelta.total_seconds() if _timedelta is not None else None
|
14
|
+
),
|
15
|
+
return_type=Optional[float],
|
16
|
+
),
|
17
|
+
]
|
18
|
+
|
8
19
|
|
9
20
|
class Provider(StrEnum):
|
10
21
|
"""
|
@@ -22,6 +33,7 @@ class Provider(StrEnum):
|
|
22
33
|
OQC = "OQC"
|
23
34
|
INTEL = "Intel"
|
24
35
|
AQT = "AQT"
|
36
|
+
IQCC = "IQCC"
|
25
37
|
|
26
38
|
@property
|
27
39
|
def id(self) -> "ProviderIDEnum":
|
@@ -55,8 +67,11 @@ class HardwareStatus(pydantic.BaseModel):
|
|
55
67
|
default_factory=lambda: datetime.datetime.now(tz=datetime.UTC)
|
56
68
|
)
|
57
69
|
availability: AvailabilityStatus
|
58
|
-
queue_time:
|
59
|
-
|
70
|
+
queue_time: QueueTime = pydantic.Field(
|
71
|
+
default=None,
|
72
|
+
description="The estimated queue time for the hardware in seconds.",
|
73
|
+
)
|
74
|
+
pending_jobs: Optional[int] = None
|
60
75
|
|
61
76
|
|
62
77
|
if TYPE_CHECKING:
|
@@ -72,7 +87,7 @@ class HardwareInformation(pydantic.BaseModel):
|
|
72
87
|
display_name: str
|
73
88
|
device_type: DeviceType
|
74
89
|
number_of_qubits: int
|
75
|
-
connectivity_map: Optional[List[ConnectivityMapEntry]]
|
90
|
+
connectivity_map: Optional[List[ConnectivityMapEntry]] = None
|
76
91
|
basis_gates: List[str]
|
77
92
|
status: HardwareStatus
|
78
93
|
|
@@ -1,6 +1,8 @@
|
|
1
1
|
from typing import TYPE_CHECKING, Any, List, Tuple
|
2
2
|
|
3
3
|
import pydantic
|
4
|
+
from pydantic import Field, StrictStr, StringConstraints
|
5
|
+
from typing_extensions import Annotated
|
4
6
|
|
5
7
|
from classiq.interface.generator.arith.number_utils import MAXIMAL_MACHINE_PRECISION
|
6
8
|
from classiq.interface.generator.parameters import ParameterComplexType
|
@@ -13,13 +15,9 @@ if TYPE_CHECKING:
|
|
13
15
|
PydanticLargerThanOneInteger = int
|
14
16
|
PydanticMachinePrecision = int
|
15
17
|
else:
|
18
|
+
PydanticLargerThanOneInteger = Annotated[int, Field(gt=1)]
|
16
19
|
|
17
|
-
|
18
|
-
gt = 1
|
19
|
-
|
20
|
-
class PydanticMachinePrecision(pydantic.ConstrainedInt):
|
21
|
-
gt = 0
|
22
|
-
le = MAXIMAL_MACHINE_PRECISION
|
20
|
+
PydanticMachinePrecision = Annotated[int, Field(gt=0, le=MAXIMAL_MACHINE_PRECISION)]
|
23
21
|
|
24
22
|
|
25
23
|
# Probability float types
|
@@ -28,93 +26,86 @@ if TYPE_CHECKING:
|
|
28
26
|
PydanticNonOneProbabilityFloat = float
|
29
27
|
PydanticNonZeroProbabilityFloat = float
|
30
28
|
else:
|
29
|
+
PydanticProbabilityFloat = Annotated[float, Field(ge=0.0, le=1.0)]
|
31
30
|
|
32
|
-
|
33
|
-
ge = 0.0
|
34
|
-
le = 1.0
|
35
|
-
|
36
|
-
class PydanticNonOneProbabilityFloat(pydantic.ConstrainedFloat):
|
37
|
-
ge = 0.0
|
38
|
-
lt = 1.0
|
31
|
+
PydanticNonOneProbabilityFloat = Annotated[float, Field(ge=0.0, lt=1.0)]
|
39
32
|
|
40
|
-
|
41
|
-
gt = 0.0
|
42
|
-
le = 1.0
|
33
|
+
PydanticNonZeroProbabilityFloat = Annotated[float, Field(gt=0.0, le=1.0)]
|
43
34
|
|
44
35
|
|
45
36
|
# CVAR parameter types
|
46
37
|
if TYPE_CHECKING:
|
47
38
|
PydanticAlphaParamCVAR = float
|
48
39
|
else:
|
49
|
-
|
50
|
-
class PydanticAlphaParamCVAR(pydantic.ConstrainedFloat):
|
51
|
-
gt = 0.0
|
52
|
-
le = 1.0
|
40
|
+
PydanticAlphaParamCVAR = Annotated[float, Field(gt=0.0, le=1.0)]
|
53
41
|
|
54
42
|
|
55
43
|
# General string types
|
56
44
|
if TYPE_CHECKING:
|
57
45
|
PydanticNonEmptyString = str
|
58
46
|
else:
|
59
|
-
PydanticNonEmptyString =
|
47
|
+
PydanticNonEmptyString = Annotated[str, Field(min_length=1)]
|
60
48
|
|
61
49
|
# Name string types
|
62
50
|
if TYPE_CHECKING:
|
63
51
|
PydanticFunctionNameStr = str
|
64
52
|
else:
|
65
|
-
PydanticFunctionNameStr =
|
66
|
-
strict=True,
|
67
|
-
|
53
|
+
PydanticFunctionNameStr = Annotated[
|
54
|
+
str, Field(strict=True, pattern="^([A-Za-z][A-Za-z0-9_]*)$")
|
55
|
+
]
|
68
56
|
|
69
57
|
if TYPE_CHECKING:
|
70
58
|
PydanticPauliMonomial = tuple
|
71
59
|
else:
|
72
|
-
PydanticPauliMonomial =
|
60
|
+
PydanticPauliMonomial = Annotated[List[Any], Field(min_length=2, max_length=2)]
|
73
61
|
|
74
62
|
if TYPE_CHECKING:
|
75
63
|
PydanticPauliMonomialStr = str
|
76
64
|
else:
|
77
|
-
PydanticPauliMonomialStr =
|
78
|
-
|
79
|
-
|
65
|
+
PydanticPauliMonomialStr = Annotated[
|
66
|
+
StrictStr,
|
67
|
+
StringConstraints(strip_whitespace=True, min_length=1, pattern="^[IXYZ]+$"),
|
68
|
+
]
|
80
69
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
PydanticPauliList = pydantic.conlist(item_type=tuple, min_items=1)
|
70
|
+
PydanticPauliList = Annotated[
|
71
|
+
List[Tuple[PydanticPauliMonomialStr, ParameterComplexType]], Field(min_length=1)
|
72
|
+
]
|
85
73
|
|
86
74
|
if TYPE_CHECKING:
|
87
75
|
PydanticFloatTuple = Tuple[float, float]
|
88
76
|
else:
|
89
|
-
PydanticFloatTuple =
|
77
|
+
PydanticFloatTuple = Annotated[List[float], Field(min_length=2, max_length=2)]
|
90
78
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
PydanticNonNegIntTuple = pydantic.conlist(
|
95
|
-
item_type=pydantic.NonNegativeInt, min_items=2, max_items=2
|
96
|
-
)
|
79
|
+
PydanticNonNegIntTuple = Annotated[
|
80
|
+
List[pydantic.NonNegativeInt], Field(min_length=2, max_length=2)
|
81
|
+
]
|
97
82
|
|
98
83
|
if TYPE_CHECKING:
|
99
84
|
PydanticExpressionStr = str
|
100
85
|
else:
|
101
|
-
PydanticExpressionStr =
|
102
|
-
|
103
|
-
|
86
|
+
PydanticExpressionStr = Annotated[
|
87
|
+
str,
|
88
|
+
StringConstraints(
|
89
|
+
strip_whitespace=True, min_length=1, max_length=MAX_EXPRESSION_SIZE
|
90
|
+
),
|
91
|
+
]
|
104
92
|
if TYPE_CHECKING:
|
105
93
|
AtomType = Tuple[str, List[float]]
|
106
94
|
else:
|
107
|
-
AtomType =
|
95
|
+
AtomType = Annotated[List[Any], Field(min_length=2, max_length=2)]
|
108
96
|
|
109
97
|
|
110
98
|
if TYPE_CHECKING:
|
111
99
|
PydanticDataDogUuid = str
|
112
100
|
else:
|
113
|
-
PydanticDataDogUuid =
|
114
|
-
|
115
|
-
|
101
|
+
PydanticDataDogUuid = Annotated[
|
102
|
+
str,
|
103
|
+
Field(
|
104
|
+
pattern=r"^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$"
|
105
|
+
),
|
106
|
+
]
|
116
107
|
|
117
108
|
if TYPE_CHECKING:
|
118
109
|
PydanticDataDogGo = int
|
119
110
|
else:
|
120
|
-
PydanticDataDogGo =
|
111
|
+
PydanticDataDogGo = Annotated[int, Field(ge=0)]
|
@@ -2,9 +2,10 @@ from typing import Any, Dict, Protocol, Sequence, TypeVar
|
|
2
2
|
|
3
3
|
|
4
4
|
def values_with_discriminator(
|
5
|
-
values:
|
5
|
+
values: Any, discriminator: str, discriminator_value: Any
|
6
6
|
) -> Dict[str, Any]:
|
7
|
-
values
|
7
|
+
if isinstance(values, dict):
|
8
|
+
values.setdefault(discriminator, discriminator_value)
|
8
9
|
return values
|
9
10
|
|
10
11
|
|
@@ -1,10 +1,7 @@
|
|
1
1
|
import pydantic
|
2
2
|
|
3
3
|
from classiq.interface._version import VERSION
|
4
|
-
from classiq.interface.helpers.custom_encoders import CUSTOM_ENCODERS
|
5
4
|
|
6
5
|
|
7
|
-
class VersionedModel(
|
8
|
-
pydantic.BaseModel, extra=pydantic.Extra.forbid, json_encoders=CUSTOM_ENCODERS
|
9
|
-
):
|
6
|
+
class VersionedModel(pydantic.BaseModel):
|
10
7
|
version: str = pydantic.Field(default=VERSION)
|
@@ -13,8 +13,8 @@ Depth = int
|
|
13
13
|
|
14
14
|
class IDEDataQubit(pydantic.BaseModel):
|
15
15
|
id: int
|
16
|
-
numChildren: Optional[int]
|
17
|
-
name: Optional[str]
|
16
|
+
numChildren: Optional[int] = None
|
17
|
+
name: Optional[str] = None
|
18
18
|
|
19
19
|
|
20
20
|
class IDEQubitDef(pydantic.BaseModel):
|
@@ -75,9 +75,9 @@ class IDEDataOperation(pydantic.BaseModel):
|
|
75
75
|
|
76
76
|
|
77
77
|
class IDEDataProperties(pydantic.BaseModel):
|
78
|
-
color: Optional[str]
|
79
|
-
rightLabel: Optional[str]
|
80
|
-
leftLabel: Optional[str]
|
78
|
+
color: Optional[str] = None
|
79
|
+
rightLabel: Optional[str] = None
|
80
|
+
leftLabel: Optional[str] = None
|
81
81
|
|
82
82
|
|
83
83
|
class RegisterData(pydantic.BaseModel):
|