classiq 0.39.0__py3-none-any.whl → 0.40.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 +1 -0
- classiq/applications/chemistry/chemistry_model_constructor.py +1 -1
- classiq/applications/combinatorial_helpers/combinatorial_problem_utils.py +5 -6
- classiq/applications/combinatorial_helpers/optimization_model.py +7 -6
- classiq/applications/combinatorial_helpers/pauli_helpers/pauli_utils.py +0 -10
- classiq/applications/combinatorial_optimization/__init__.py +2 -0
- classiq/applications/combinatorial_optimization/combinatorial_optimization_model_constructor.py +2 -2
- classiq/interface/_version.py +1 -1
- classiq/interface/backend/backend_preferences.py +5 -5
- classiq/interface/backend/quantum_backend_providers.py +7 -7
- classiq/interface/executor/execution_preferences.py +4 -9
- classiq/interface/generator/application_apis/chemistry_declarations.py +2 -4
- classiq/interface/generator/application_apis/finance_declarations.py +1 -1
- classiq/interface/generator/arith/arithmetic_expression_validator.py +2 -0
- classiq/interface/generator/expressions/qmod_qarray_proxy.py +82 -0
- classiq/interface/generator/expressions/qmod_qscalar_proxy.py +21 -0
- classiq/interface/generator/expressions/qmod_sized_proxy.py +22 -0
- classiq/interface/generator/functions/builtins/core_library/atomic_quantum_functions.py +8 -6
- classiq/interface/generator/functions/builtins/core_library/exponentiation_functions.py +10 -4
- classiq/interface/generator/functions/builtins/open_lib_functions.py +624 -76
- classiq/interface/generator/functions/classical_type.py +29 -17
- classiq/interface/generator/model/preferences/preferences.py +4 -2
- classiq/interface/model/control.py +104 -8
- classiq/interface/model/quantum_type.py +6 -5
- classiq/interface/model/resolvers/function_call_resolver.py +0 -5
- classiq/interface/model/statement_block.py +1 -4
- classiq/qmod/__init__.py +6 -2
- classiq/qmod/builtins/classical_functions.py +30 -35
- classiq/qmod/builtins/functions.py +213 -153
- classiq/qmod/builtins/operations.py +78 -24
- classiq/qmod/builtins/structs.py +50 -48
- classiq/qmod/declaration_inferrer.py +30 -18
- classiq/qmod/native/expression_to_qmod.py +5 -4
- classiq/qmod/native/pretty_printer.py +7 -14
- classiq/qmod/qmod_constant.py +7 -7
- classiq/qmod/qmod_parameter.py +54 -33
- classiq/qmod/qmod_struct.py +2 -2
- classiq/qmod/qmod_variable.py +40 -29
- classiq/qmod/quantum_callable.py +7 -4
- classiq/qmod/quantum_expandable.py +19 -13
- classiq/qmod/quantum_function.py +25 -2
- classiq/qmod/symbolic.py +78 -68
- classiq/qmod/symbolic_expr.py +1 -1
- classiq/qmod/symbolic_type.py +1 -4
- classiq/qmod/utilities.py +29 -0
- {classiq-0.39.0.dist-info → classiq-0.40.0.dist-info}/METADATA +1 -1
- {classiq-0.39.0.dist-info → classiq-0.40.0.dist-info}/RECORD +48 -50
- classiq/interface/executor/error_mitigation.py +0 -6
- classiq/interface/generator/functions/builtins/core_library/chemistry_functions.py +0 -0
- classiq/interface/model/quantum_if_operation.py +0 -94
- {classiq-0.39.0.dist-info → classiq-0.40.0.dist-info}/WHEEL +0 -0
classiq/__init__.py
CHANGED
@@ -34,6 +34,7 @@ from classiq.applications.chemistry import (
|
|
34
34
|
)
|
35
35
|
from classiq.applications.combinatorial_optimization import (
|
36
36
|
construct_combinatorial_optimization_model,
|
37
|
+
pyo_model_to_hamiltonian,
|
37
38
|
)
|
38
39
|
from classiq.applications.finance import construct_finance_model
|
39
40
|
from classiq.applications.grover import construct_grover_model
|
@@ -446,7 +446,7 @@ def _get_chemistry_quantum_main(
|
|
446
446
|
function="allocate",
|
447
447
|
positional_args=[
|
448
448
|
Expression(
|
449
|
-
expr=f"
|
449
|
+
expr=f"get_field(get_field({_get_problem_to_hamiltonian_name(chemistry_problem)}({_convert_library_problem_to_qmod_problem(chemistry_problem)})[0], 'pauli'), 'len')"
|
450
450
|
),
|
451
451
|
HandleBinding(name="qbv"),
|
452
452
|
],
|
@@ -9,6 +9,7 @@ from classiq.interface.combinatorial_optimization.solver_types import QSolver
|
|
9
9
|
from classiq.interface.executor.vqe_result import VQESolverResult
|
10
10
|
from classiq.interface.generator.functions.qmod_python_interface import QmodPyStruct
|
11
11
|
|
12
|
+
from classiq import Pauli
|
12
13
|
from classiq.applications.combinatorial_helpers.optimization_model import (
|
13
14
|
OptimizationModel,
|
14
15
|
)
|
@@ -16,14 +17,13 @@ from classiq.applications.combinatorial_helpers.pauli_helpers.pauli_sparsing imp
|
|
16
17
|
SparsePauliOp,
|
17
18
|
)
|
18
19
|
from classiq.applications.combinatorial_helpers.pauli_helpers.pauli_utils import (
|
19
|
-
PauliTerm,
|
20
20
|
get_pauli_operator,
|
21
21
|
pauli_operator_to_hamiltonian,
|
22
|
-
pauli_string_to_int,
|
23
22
|
)
|
24
23
|
from classiq.applications.combinatorial_helpers.pyomo_utils import (
|
25
24
|
convert_pyomo_to_global_presentation,
|
26
25
|
)
|
26
|
+
from classiq.qmod.builtins import PauliTerm
|
27
27
|
|
28
28
|
|
29
29
|
def compute_qaoa_initial_point(
|
@@ -58,10 +58,9 @@ def pyo_model_to_hamiltonian(
|
|
58
58
|
pauli_operator = get_pauli_operator(hamiltonian).pauli_list
|
59
59
|
pauli_terms = []
|
60
60
|
for item in pauli_operator:
|
61
|
-
term = PauliTerm(
|
62
|
-
|
63
|
-
|
64
|
-
cast(complex, item[1]).real,
|
61
|
+
term = PauliTerm(
|
62
|
+
[Pauli[p] for p in item[0]], # type:ignore[arg-type]
|
63
|
+
cast(complex, item[1]).real, # type:ignore[arg-type]
|
65
64
|
)
|
66
65
|
pauli_terms.append(term)
|
67
66
|
|
@@ -45,22 +45,23 @@ class OptimizationModel:
|
|
45
45
|
encoding_type: Optional[EncodingType] = None,
|
46
46
|
) -> None:
|
47
47
|
assert model.nobjectives() == 1, "model must have a single objective"
|
48
|
-
|
49
|
-
self.
|
48
|
+
model_copy = copy.deepcopy(model)
|
49
|
+
self._model_original = model
|
50
|
+
self._assigned_model = remove_fixed_variables(model_copy)
|
50
51
|
self.qsolver = qsolver
|
51
52
|
self._encoding_type = encoding_type
|
52
53
|
|
53
|
-
self.is_encoded = encoding_utils.is_model_encodable(
|
54
|
+
self.is_encoded = encoding_utils.is_model_encodable(model_copy)
|
54
55
|
if self.is_encoded:
|
55
56
|
if self._encoding_type is None:
|
56
57
|
self._encoding_type = EncodingType.BINARY
|
57
58
|
self._model_encoder = encoding.ModelEncoder(
|
58
|
-
|
59
|
+
model_copy, qsolver, self._encoding_type
|
59
60
|
)
|
60
61
|
self._model = self._model_encoder.encoded_model
|
61
62
|
self._vars_encoding_mapping = self._model_encoder.vars_encoding_mapping
|
62
63
|
else:
|
63
|
-
self._model =
|
64
|
+
self._model = model_copy
|
64
65
|
# TODO How to handle encoding_type == None
|
65
66
|
self._vars_encoding_mapping = EncodingMapping(self._encoding_type) # type: ignore[arg-type]
|
66
67
|
|
@@ -70,7 +71,7 @@ class OptimizationModel:
|
|
70
71
|
self.vars_not_encoded, self._vars_encoding_mapping
|
71
72
|
)
|
72
73
|
|
73
|
-
self.is_maximization = sense.is_maximization(
|
74
|
+
self.is_maximization = sense.is_maximization(model_copy)
|
74
75
|
self.objective = next(self._model.component_objects(pyo.Objective))
|
75
76
|
|
76
77
|
self.penalty_energy = penalty_energy
|
@@ -12,16 +12,6 @@ from classiq.exceptions import (
|
|
12
12
|
)
|
13
13
|
|
14
14
|
|
15
|
-
class PauliTerm:
|
16
|
-
pauli: List[int]
|
17
|
-
coefficient: float
|
18
|
-
|
19
|
-
|
20
|
-
def pauli_string_to_int(pauli_str: str) -> List[int]:
|
21
|
-
pauli_map = {"I": 0, "X": 1, "Y": 2, "Z": 3}
|
22
|
-
return [pauli_map[char] for char in pauli_str]
|
23
|
-
|
24
|
-
|
25
15
|
def _pauli_str_to_enums(pauli_str: str) -> str:
|
26
16
|
return ", ".join(f"Pauli.{pauli_term}" for pauli_term in pauli_str)
|
27
17
|
|
@@ -6,6 +6,7 @@ from classiq.interface.combinatorial_optimization.solver_types import QSolver
|
|
6
6
|
|
7
7
|
from classiq.applications.combinatorial_helpers.combinatorial_problem_utils import (
|
8
8
|
get_optimization_solution_from_pyo,
|
9
|
+
pyo_model_to_hamiltonian,
|
9
10
|
)
|
10
11
|
|
11
12
|
from .combinatorial_optimization_config import OptimizerConfig, QAOAConfig
|
@@ -21,6 +22,7 @@ __all__ = [
|
|
21
22
|
"construct_combinatorial_optimization_model",
|
22
23
|
"examples",
|
23
24
|
"get_optimization_solution_from_pyo",
|
25
|
+
"pyo_model_to_hamiltonian",
|
24
26
|
]
|
25
27
|
|
26
28
|
|
classiq/applications/combinatorial_optimization/combinatorial_optimization_model_constructor.py
CHANGED
@@ -88,14 +88,14 @@ def construct_combi_opt_py_model(
|
|
88
88
|
QuantumFunctionCall(
|
89
89
|
function="allocate",
|
90
90
|
positional_args=[
|
91
|
-
Expression(expr="len
|
91
|
+
Expression(expr="target.len"),
|
92
92
|
HandleBinding(name="target"),
|
93
93
|
],
|
94
94
|
),
|
95
95
|
QuantumFunctionCall(
|
96
96
|
function="qaoa_penalty",
|
97
97
|
params={
|
98
|
-
"num_qubits": Expression(expr="len
|
98
|
+
"num_qubits": Expression(expr="target.len"),
|
99
99
|
"params_list": Expression(expr="params_list"),
|
100
100
|
"hamiltonian": Expression(expr="hamiltonian"),
|
101
101
|
},
|
classiq/interface/_version.py
CHANGED
@@ -12,8 +12,8 @@ from classiq.interface.backend.quantum_backend_providers import (
|
|
12
12
|
AliceBobBackendNames,
|
13
13
|
AmazonBraketBackendNames,
|
14
14
|
AzureQuantumBackendNames,
|
15
|
-
ClassiqAerBackendNames,
|
16
15
|
ClassiqNvidiaBackendNames,
|
16
|
+
ClassiqSimulatorBackendNames,
|
17
17
|
IonqBackendNames,
|
18
18
|
OQCBackendNames,
|
19
19
|
ProviderTypeVendor,
|
@@ -56,7 +56,7 @@ class BackendPreferences(BaseModel):
|
|
56
56
|
return False
|
57
57
|
|
58
58
|
|
59
|
-
AWS_DEFAULT_JOB_TIMEOUT_SECONDS = int(timedelta(minutes=
|
59
|
+
AWS_DEFAULT_JOB_TIMEOUT_SECONDS = int(timedelta(minutes=240).total_seconds())
|
60
60
|
|
61
61
|
|
62
62
|
class AliceBobBackendPreferences(BackendPreferences):
|
@@ -221,13 +221,13 @@ def is_exact_simulator(backend_preferences: BackendPreferences) -> bool:
|
|
221
221
|
|
222
222
|
|
223
223
|
def default_backend_preferences(
|
224
|
-
backend_name: str =
|
224
|
+
backend_name: str = ClassiqSimulatorBackendNames.SIMULATOR,
|
225
225
|
) -> BackendPreferences:
|
226
226
|
return ClassiqBackendPreferences(backend_name=backend_name)
|
227
227
|
|
228
228
|
|
229
229
|
def backend_preferences_field(
|
230
|
-
backend_name: str =
|
230
|
+
backend_name: str = ClassiqSimulatorBackendNames.SIMULATOR,
|
231
231
|
) -> Any:
|
232
232
|
return pydantic.Field(
|
233
233
|
default_factory=lambda: default_backend_preferences(backend_name),
|
@@ -252,7 +252,7 @@ __all__ = [
|
|
252
252
|
"AzureCredential",
|
253
253
|
"AzureQuantumBackendNames",
|
254
254
|
"ClassiqBackendPreferences",
|
255
|
-
"
|
255
|
+
"ClassiqSimulatorBackendNames",
|
256
256
|
"IBMBackendPreferences",
|
257
257
|
"IBMBackendProvider",
|
258
258
|
"AwsBackendPreferences",
|
@@ -31,11 +31,11 @@ class ProviderTypeVendor:
|
|
31
31
|
OQC = Literal[ProviderVendor.OQC]
|
32
32
|
|
33
33
|
|
34
|
-
class
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
34
|
+
class ClassiqSimulatorBackendNames(StrEnum):
|
35
|
+
SIMULATOR = "simulator"
|
36
|
+
SIMULATOR_STATEVECTOR = "simulator_statevector"
|
37
|
+
SIMULATOR_DENSITY_MATRIX = "simulator_density_matrix"
|
38
|
+
SIMULATOR_MATRIX_PRODUCT_STATE = "simulator_matrix_product_state"
|
39
39
|
|
40
40
|
|
41
41
|
class IonqBackendNames(StrEnum):
|
@@ -141,7 +141,7 @@ class ClassiqNvidiaBackendNames(StrEnum):
|
|
141
141
|
SIMULATOR = "nvidia_state_vector_simulator"
|
142
142
|
|
143
143
|
|
144
|
-
AllClassiqBackendNames = Union[
|
144
|
+
AllClassiqBackendNames = Union[ClassiqSimulatorBackendNames, ClassiqNvidiaBackendNames]
|
145
145
|
|
146
146
|
|
147
147
|
class GoogleNvidiaBackendNames(StrEnum):
|
@@ -166,7 +166,7 @@ EXACT_SIMULATORS = {
|
|
166
166
|
AmazonBraketBackendNames.AMAZON_BRAKET_SV1,
|
167
167
|
AmazonBraketBackendNames.AMAZON_BRAKET_TN1,
|
168
168
|
AmazonBraketBackendNames.AMAZON_BRAKET_DM1,
|
169
|
-
*
|
169
|
+
*ClassiqSimulatorBackendNames,
|
170
170
|
*ClassiqNvidiaBackendNames,
|
171
171
|
}
|
172
172
|
|
@@ -10,8 +10,9 @@ from classiq.interface.backend.backend_preferences import (
|
|
10
10
|
backend_preferences_field,
|
11
11
|
)
|
12
12
|
from classiq.interface.backend.pydantic_backend import MAX_EXECUTION_TIMEOUT_SECONDS
|
13
|
-
from classiq.interface.backend.quantum_backend_providers import
|
14
|
-
|
13
|
+
from classiq.interface.backend.quantum_backend_providers import (
|
14
|
+
ClassiqSimulatorBackendNames,
|
15
|
+
)
|
15
16
|
from classiq.interface.executor.optimizer_preferences import (
|
16
17
|
OptimizerPreferences,
|
17
18
|
OptimizerType,
|
@@ -51,11 +52,6 @@ class ExecutionPreferences(pydantic.BaseModel):
|
|
51
52
|
default_factory=None,
|
52
53
|
description="Settings related to VQE execution.",
|
53
54
|
)
|
54
|
-
error_mitigation_method: Optional[ErrorMitigationMethod] = pydantic.Field(
|
55
|
-
default=None,
|
56
|
-
description="Error mitigation method. Currently supports complete and tensored "
|
57
|
-
"measurement calibration.",
|
58
|
-
)
|
59
55
|
noise_properties: Optional[NoiseProperties] = pydantic.Field(
|
60
56
|
default=None, description="Properties of the noise in the circuit"
|
61
57
|
)
|
@@ -64,7 +60,7 @@ class ExecutionPreferences(pydantic.BaseModel):
|
|
64
60
|
description="The random seed used for the execution",
|
65
61
|
)
|
66
62
|
backend_preferences: BackendPreferencesTypes = backend_preferences_field(
|
67
|
-
backend_name=
|
63
|
+
backend_name=ClassiqSimulatorBackendNames.SIMULATOR
|
68
64
|
)
|
69
65
|
num_shots: Optional[pydantic.PositiveInt] = pydantic.Field(default=None)
|
70
66
|
transpile_to_hardware: TranspilationOption = pydantic.Field(
|
@@ -151,7 +147,6 @@ def _choose_original_or_optimizer_attribute(
|
|
151
147
|
|
152
148
|
__all__ = [
|
153
149
|
"ExecutionPreferences",
|
154
|
-
"ErrorMitigationMethod",
|
155
150
|
"NoiseProperties",
|
156
151
|
"OptimizerPreferences",
|
157
152
|
"OptimizerType",
|
@@ -24,9 +24,7 @@ from classiq.interface.model.quantum_function_declaration import (
|
|
24
24
|
)
|
25
25
|
|
26
26
|
MOLECULE_PROBLEM_PARAM = {"molecule_problem": Struct(name="MoleculeProblem")}
|
27
|
-
MOLECULE_PROBLEM_SIZE = (
|
28
|
-
"len(get_field(molecule_problem_to_hamiltonian(molecule_problem)[0], 'pauli'))"
|
29
|
-
)
|
27
|
+
MOLECULE_PROBLEM_SIZE = "get_field(get_field(molecule_problem_to_hamiltonian(molecule_problem)[0], 'pauli'), 'len')"
|
30
28
|
MOLECULE_PROBLEM_PORT = {
|
31
29
|
"qbv": PortDeclaration(
|
32
30
|
name="qbv",
|
@@ -40,7 +38,7 @@ MOLECULE_PROBLEM_PORT = {
|
|
40
38
|
FOCK_HAMILTONIAN_PROBLEM_PARAM = {
|
41
39
|
"fock_hamiltonian_problem": Struct(name="FockHamiltonianProblem")
|
42
40
|
}
|
43
|
-
FOCK_HAMILTONIAN_SIZE = "
|
41
|
+
FOCK_HAMILTONIAN_SIZE = "get_field(get_field(fock_hamiltonian_problem_to_hamiltonian(fock_hamiltonian_problem)[0], 'pauli'), 'len')"
|
44
42
|
|
45
43
|
FOCK_HAMILTONIAN_PROBLEM_PORT = {
|
46
44
|
"qbv": PortDeclaration(
|
@@ -31,7 +31,7 @@ class FinanceModelType(Enum):
|
|
31
31
|
|
32
32
|
|
33
33
|
FINANCE_FUNCTION_PORT_SIZE_MAPPING: Mapping[FinanceModelType, str] = {
|
34
|
-
FinanceModelType.Gaussian: "get_field(finance_model, 'num_qubits') +
|
34
|
+
FinanceModelType.Gaussian: "get_field(finance_model, 'num_qubits') + get_field(get_field(finance_model, 'rhos'), 'len') + floor(log(sum(get_field(finance_model, 'loss')), 2)) + 1",
|
35
35
|
FinanceModelType.LogNormal: "get_field(finance_model, 'num_qubits')",
|
36
36
|
}
|
37
37
|
|
@@ -10,6 +10,7 @@ from classiq.interface.generator.arith.ast_node_rewrite import AstNodeRewrite
|
|
10
10
|
from classiq.interface.generator.expressions.sympy_supported_expressions import (
|
11
11
|
SYMPY_SUPPORTED_EXPRESSIONS,
|
12
12
|
)
|
13
|
+
from classiq.interface.generator.functions.classical_type import CLASSICAL_ATTRIBUTES
|
13
14
|
|
14
15
|
from classiq.exceptions import ClassiqArithmeticError, ClassiqValueError
|
15
16
|
|
@@ -174,6 +175,7 @@ class ExpressionValidator(ast.NodeVisitor):
|
|
174
175
|
if not (
|
175
176
|
isinstance(node.value, ast.Name)
|
176
177
|
and node.value.id in self._supported_attr_values
|
178
|
+
or node.attr in CLASSICAL_ATTRIBUTES.keys()
|
177
179
|
):
|
178
180
|
raise ClassiqValueError(
|
179
181
|
f"Attribute is not supported for value {node.value}"
|
@@ -0,0 +1,82 @@
|
|
1
|
+
from typing import Optional, Tuple, Union
|
2
|
+
|
3
|
+
from classiq.interface.generator.expressions.expression import Expression
|
4
|
+
from classiq.interface.generator.expressions.qmod_sized_proxy import QmodSizedProxy
|
5
|
+
from classiq.interface.model.handle_binding import (
|
6
|
+
HandleBinding,
|
7
|
+
SlicedHandleBinding,
|
8
|
+
SubscriptHandleBinding,
|
9
|
+
)
|
10
|
+
|
11
|
+
from classiq.exceptions import ClassiqValueError
|
12
|
+
|
13
|
+
ILLEGAL_SLICING_STEP_MSG = "Slicing with a step of a quantum variable is not supported"
|
14
|
+
SLICE_OUT_OF_BOUNDS_MSG = "Slice end index out of bounds"
|
15
|
+
QARRAY_ELEMENT_NOT_SUBSCRIPTABLE = "Subscripting an element in QArray is illegal"
|
16
|
+
|
17
|
+
|
18
|
+
class QmodQArrayProxy(QmodSizedProxy):
|
19
|
+
def __init__(
|
20
|
+
self,
|
21
|
+
name: str,
|
22
|
+
size: int,
|
23
|
+
slice_: Optional[Tuple[int, int]] = None,
|
24
|
+
index_: Optional[int] = None,
|
25
|
+
) -> None:
|
26
|
+
super().__init__(size)
|
27
|
+
self._name = name
|
28
|
+
self._slice = slice_
|
29
|
+
self._index = index_
|
30
|
+
|
31
|
+
def __getitem__(self, key: Union[slice, int]) -> "QmodQArrayProxy":
|
32
|
+
if self._index is not None:
|
33
|
+
raise ClassiqValueError(QARRAY_ELEMENT_NOT_SUBSCRIPTABLE)
|
34
|
+
|
35
|
+
new_index: Optional[int] = None
|
36
|
+
|
37
|
+
if isinstance(key, slice):
|
38
|
+
if key.step is not None:
|
39
|
+
raise ClassiqValueError(ILLEGAL_SLICING_STEP_MSG)
|
40
|
+
new_slice = self._get_new_slice(key.start, key.stop)
|
41
|
+
else:
|
42
|
+
new_slice = self._get_new_slice(key, key + 1)
|
43
|
+
new_index = new_slice[0]
|
44
|
+
|
45
|
+
if (self._slice is not None and new_slice[1] > self._slice[1]) or new_slice[
|
46
|
+
1
|
47
|
+
] > self._size:
|
48
|
+
raise ClassiqValueError(SLICE_OUT_OF_BOUNDS_MSG)
|
49
|
+
|
50
|
+
return QmodQArrayProxy(
|
51
|
+
self._name, self._size, slice_=new_slice, index_=new_index
|
52
|
+
)
|
53
|
+
|
54
|
+
def _get_new_slice(self, start: int, end: int) -> Tuple[int, int]:
|
55
|
+
if self._slice is not None:
|
56
|
+
return self._slice[0] + start, self._slice[0] + end
|
57
|
+
return start, end
|
58
|
+
|
59
|
+
@property
|
60
|
+
def index(self) -> Optional[int]:
|
61
|
+
return self._index
|
62
|
+
|
63
|
+
@property
|
64
|
+
def slice(self) -> Optional[Tuple[int, int]]:
|
65
|
+
return self._slice
|
66
|
+
|
67
|
+
@property
|
68
|
+
def handle(self) -> HandleBinding:
|
69
|
+
if self._index is not None:
|
70
|
+
return SubscriptHandleBinding(
|
71
|
+
name=self._name,
|
72
|
+
index=Expression(expr=str(self._index)),
|
73
|
+
)
|
74
|
+
|
75
|
+
if self._slice is not None:
|
76
|
+
return SlicedHandleBinding(
|
77
|
+
name=self._name,
|
78
|
+
start=Expression(expr=str(self._slice[0])),
|
79
|
+
end=Expression(expr=str(self._slice[1])),
|
80
|
+
)
|
81
|
+
|
82
|
+
return HandleBinding(name=self._name)
|
@@ -1,6 +1,9 @@
|
|
1
|
+
from typing import Any, Mapping
|
2
|
+
|
1
3
|
from sympy import Symbol
|
2
4
|
|
3
5
|
from classiq.interface.generator.expressions.qmod_sized_proxy import QmodSizedProxy
|
6
|
+
from classiq.interface.model.handle_binding import HandleBinding
|
4
7
|
|
5
8
|
|
6
9
|
class QmodQScalarProxy(Symbol, QmodSizedProxy):
|
@@ -9,6 +12,11 @@ class QmodQScalarProxy(Symbol, QmodSizedProxy):
|
|
9
12
|
|
10
13
|
def __init__(self, name: str, size: int) -> None:
|
11
14
|
super().__init__(size)
|
15
|
+
self.name = name
|
16
|
+
|
17
|
+
@property
|
18
|
+
def handle(self) -> HandleBinding:
|
19
|
+
return HandleBinding(name=self.name)
|
12
20
|
|
13
21
|
|
14
22
|
class QmodQBitProxy(QmodQScalarProxy):
|
@@ -24,6 +32,10 @@ class QmodQNumProxy(QmodQScalarProxy):
|
|
24
32
|
self._fraction_digits = fraction_digits
|
25
33
|
self._is_signed = is_signed
|
26
34
|
|
35
|
+
@property
|
36
|
+
def size(self) -> int:
|
37
|
+
return self._size
|
38
|
+
|
27
39
|
@property
|
28
40
|
def fraction_digits(self) -> int:
|
29
41
|
return self._fraction_digits
|
@@ -31,3 +43,12 @@ class QmodQNumProxy(QmodQScalarProxy):
|
|
31
43
|
@property
|
32
44
|
def is_signed(self) -> bool:
|
33
45
|
return self._is_signed
|
46
|
+
|
47
|
+
@property
|
48
|
+
def fields(self) -> Mapping[str, Any]:
|
49
|
+
return {
|
50
|
+
"size": self.size,
|
51
|
+
"is_signed": self.is_signed,
|
52
|
+
"fraction_digits": self.fraction_digits,
|
53
|
+
"len": self.size,
|
54
|
+
}
|
@@ -1,6 +1,28 @@
|
|
1
|
+
from typing import TYPE_CHECKING, Any, Mapping
|
2
|
+
|
3
|
+
from classiq.exceptions import ClassiqNotImplementedError
|
4
|
+
|
5
|
+
if TYPE_CHECKING:
|
6
|
+
from classiq.interface.model.handle_binding import HandleBinding
|
7
|
+
|
8
|
+
|
1
9
|
class QmodSizedProxy:
|
2
10
|
def __init__(self, size: int) -> None:
|
3
11
|
self._size = size
|
4
12
|
|
5
13
|
def __len__(self) -> int:
|
6
14
|
return self._size
|
15
|
+
|
16
|
+
@property
|
17
|
+
def handle(self) -> "HandleBinding":
|
18
|
+
raise ClassiqNotImplementedError("cannot compute handle")
|
19
|
+
|
20
|
+
@property
|
21
|
+
def len(self) -> int:
|
22
|
+
return self._size
|
23
|
+
|
24
|
+
@property
|
25
|
+
def fields(self) -> Mapping[str, Any]:
|
26
|
+
return {
|
27
|
+
"len": self.len,
|
28
|
+
}
|
@@ -423,7 +423,7 @@ UNITARY_FUNCTION = QuantumFunctionDeclaration(
|
|
423
423
|
DEFAULT_TARGET_NAME: PortDeclaration(
|
424
424
|
name=DEFAULT_TARGET_NAME,
|
425
425
|
direction=PortDeclarationDirection.Inout,
|
426
|
-
size=Expression(expr="log(
|
426
|
+
size=Expression(expr="log(get_field(elements[0], 'len'), 2)"),
|
427
427
|
)
|
428
428
|
},
|
429
429
|
)
|
@@ -436,7 +436,7 @@ PREPARE_STATE_FUNCTION = QuantumFunctionDeclaration(
|
|
436
436
|
"out": PortDeclaration(
|
437
437
|
name="out",
|
438
438
|
direction=PortDeclarationDirection.Output,
|
439
|
-
size=Expression(expr="log(
|
439
|
+
size=Expression(expr="log(get_field(probabilities, 'len'), 2)"),
|
440
440
|
)
|
441
441
|
},
|
442
442
|
)
|
@@ -448,7 +448,7 @@ PREPARE_AMPLITUDES_FUNCTION = QuantumFunctionDeclaration(
|
|
448
448
|
"out": PortDeclaration(
|
449
449
|
name="out",
|
450
450
|
direction=PortDeclarationDirection.Output,
|
451
|
-
size=Expression(expr="log(
|
451
|
+
size=Expression(expr="log(get_field(amplitudes, 'len'), 2)"),
|
452
452
|
)
|
453
453
|
},
|
454
454
|
)
|
@@ -467,7 +467,9 @@ ADD_FUNCTION = QuantumFunctionDeclaration(
|
|
467
467
|
"result": PortDeclaration(
|
468
468
|
name="result",
|
469
469
|
direction=PortDeclarationDirection.Output,
|
470
|
-
size=Expression(
|
470
|
+
size=Expression(
|
471
|
+
expr="Max(get_field(left, 'len'), get_field(right, 'len')) + 1"
|
472
|
+
),
|
471
473
|
),
|
472
474
|
},
|
473
475
|
)
|
@@ -578,7 +580,7 @@ INPLACE_PREPARE_STATE = QuantumFunctionDeclaration(
|
|
578
580
|
"target": PortDeclaration(
|
579
581
|
name="target",
|
580
582
|
direction=PortDeclarationDirection.Inout,
|
581
|
-
size=Expression(expr="log(
|
583
|
+
size=Expression(expr="log(get_field(probabilities, 'len'), 2)"),
|
582
584
|
)
|
583
585
|
},
|
584
586
|
)
|
@@ -591,7 +593,7 @@ INPLACE_PREPARE_AMPLITUDES = QuantumFunctionDeclaration(
|
|
591
593
|
"target": PortDeclaration(
|
592
594
|
name="target",
|
593
595
|
direction=PortDeclarationDirection.Inout,
|
594
|
-
size=Expression(expr="log(
|
596
|
+
size=Expression(expr="log(get_field(amplitudes, 'len'), 2)"),
|
595
597
|
)
|
596
598
|
},
|
597
599
|
)
|
@@ -26,7 +26,7 @@ SINGLE_PAULI_EXPONENT_FUNCTION = QuantumFunctionDeclaration(
|
|
26
26
|
"qbv": PortDeclaration(
|
27
27
|
name="qbv",
|
28
28
|
direction=PortDeclarationDirection.Inout,
|
29
|
-
size=Expression(expr="
|
29
|
+
size=Expression(expr="get_field(pauli_string, 'len')"),
|
30
30
|
)
|
31
31
|
},
|
32
32
|
)
|
@@ -44,7 +44,9 @@ SUZUKI_TROTTER_FUNCTION = QuantumFunctionDeclaration(
|
|
44
44
|
"qbv": PortDeclaration(
|
45
45
|
name="qbv",
|
46
46
|
direction=PortDeclarationDirection.Inout,
|
47
|
-
size=Expression(
|
47
|
+
size=Expression(
|
48
|
+
expr="get_field(get_field(pauli_operator[0], 'pauli'), 'len')"
|
49
|
+
),
|
48
50
|
)
|
49
51
|
},
|
50
52
|
)
|
@@ -60,7 +62,9 @@ QDRIFT_FUNCTION = QuantumFunctionDeclaration(
|
|
60
62
|
"qbv": PortDeclaration(
|
61
63
|
name="qbv",
|
62
64
|
direction=PortDeclarationDirection.Inout,
|
63
|
-
size=Expression(
|
65
|
+
size=Expression(
|
66
|
+
expr="get_field(get_field(pauli_operator[0], 'pauli'), 'len')"
|
67
|
+
),
|
64
68
|
)
|
65
69
|
},
|
66
70
|
)
|
@@ -76,7 +80,9 @@ EXPONENTIATION_WITH_DEPTH_CONSTRAINT = QuantumFunctionDeclaration(
|
|
76
80
|
"qbv": PortDeclaration(
|
77
81
|
name="qbv",
|
78
82
|
direction=PortDeclarationDirection.Inout,
|
79
|
-
size=Expression(
|
83
|
+
size=Expression(
|
84
|
+
expr="get_field(get_field(pauli_operator[0], 'pauli'), 'len')"
|
85
|
+
),
|
80
86
|
)
|
81
87
|
},
|
82
88
|
)
|