classiq 0.102.0__py3-none-any.whl → 1.0.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 +2 -0
- classiq/_internals/authentication/auth0.py +29 -0
- classiq/_internals/authentication/auth_flow_factory.py +43 -0
- classiq/_internals/authentication/machine_credentials_flow.py +26 -0
- classiq/_internals/authentication/password_manager.py +84 -0
- classiq/_internals/authentication/token_manager.py +24 -8
- classiq/analyzer/show_interactive_hack.py +0 -8
- classiq/applications/chemistry/op_utils.py +32 -0
- classiq/applications/combinatorial_optimization/combinatorial_problem.py +1 -1
- classiq/evaluators/qmod_annotated_expression.py +1 -1
- classiq/evaluators/qmod_expression_visitors/qmod_expression_evaluator.py +1 -8
- classiq/evaluators/qmod_expression_visitors/qmod_expression_simplifier.py +1 -1
- classiq/evaluators/qmod_node_evaluators/attribute_evaluation.py +2 -2
- classiq/evaluators/qmod_node_evaluators/binary_op_evaluation.py +18 -29
- classiq/evaluators/qmod_node_evaluators/min_max_evaluation.py +1 -6
- classiq/evaluators/qmod_node_evaluators/numeric_attrs_utils.py +1 -7
- classiq/evaluators/qmod_type_inference/quantum_type_comparison.py +52 -0
- classiq/execution/all_hardware_devices.py +59 -1
- classiq/execution/execution_session.py +1 -1
- classiq/execution/functions/__init__.py +13 -0
- classiq/execution/functions/expectation_value.py +106 -0
- classiq/execution/functions/minimize.py +90 -0
- classiq/execution/functions/sample.py +76 -0
- classiq/execution/functions/state_vector.py +113 -0
- classiq/execution/functions/util/__init__.py +0 -0
- classiq/execution/functions/util/_logging.py +19 -0
- classiq/execution/functions/util/backend_preferences.py +188 -0
- classiq/execution/functions/util/constants.py +9 -0
- classiq/execution/functions/util/parse_provider_backend.py +90 -0
- classiq/interface/_version.py +1 -1
- classiq/interface/backend/backend_preferences.py +81 -0
- classiq/interface/backend/provider_config/providers/aqt.py +1 -1
- classiq/interface/backend/provider_config/providers/azure.py +1 -2
- classiq/interface/backend/provider_config/providers/ibm.py +1 -1
- classiq/interface/backend/quantum_backend_providers.py +14 -0
- classiq/interface/exceptions.py +0 -4
- classiq/interface/executor/result.py +9 -5
- classiq/interface/generator/arith/binary_ops.py +62 -2
- classiq/interface/generator/arith/number_utils.py +15 -6
- classiq/interface/generator/compiler_keywords.py +1 -0
- classiq/interface/generator/function_param_list.py +8 -2
- classiq/interface/generator/function_params.py +1 -1
- classiq/interface/generator/functions/builtins/internal_operators.py +5 -9
- classiq/interface/generator/functions/classical_type.py +60 -0
- classiq/interface/generator/functions/type_name.py +36 -0
- classiq/interface/generator/generated_circuit_data.py +0 -2
- classiq/interface/generator/transpiler_basis_gates.py +1 -0
- classiq/interface/generator/types/compilation_metadata.py +18 -0
- classiq/interface/hardware.py +2 -0
- classiq/interface/helpers/model_normalizer.py +42 -6
- classiq/interface/interface_version.py +1 -1
- classiq/interface/model/invert.py +8 -0
- classiq/interface/model/model.py +19 -0
- classiq/interface/model/model_visitor.py +4 -2
- classiq/interface/model/quantum_type.py +36 -0
- classiq/interface/model/statement_block.py +0 -4
- classiq/interface/qubits_mapping/__init__.py +4 -0
- classiq/interface/qubits_mapping/path_expr_range.py +69 -0
- classiq/interface/qubits_mapping/qubits_mapping.py +231 -0
- classiq/interface/qubits_mapping/slices.py +112 -0
- classiq/model_expansions/arithmetic.py +6 -0
- classiq/model_expansions/capturing/captured_vars.py +16 -12
- classiq/model_expansions/function_builder.py +9 -1
- classiq/model_expansions/interpreters/base_interpreter.py +9 -8
- classiq/model_expansions/interpreters/generative_interpreter.py +9 -24
- classiq/model_expansions/quantum_operations/arithmetic/explicit_boolean_expressions.py +1 -0
- classiq/model_expansions/quantum_operations/assignment_result_processor.py +132 -28
- classiq/model_expansions/quantum_operations/bind.py +4 -0
- classiq/model_expansions/quantum_operations/call_emitter.py +5 -35
- classiq/model_expansions/quantum_operations/emitter.py +1 -4
- classiq/model_expansions/quantum_operations/expression_evaluator.py +0 -3
- classiq/model_expansions/visitors/uncomputation_signature_inference.py +0 -9
- classiq/qmod/builtins/functions/__init__.py +21 -9
- classiq/qmod/builtins/functions/allocation.py +0 -36
- classiq/qmod/builtins/functions/arithmetic.py +183 -0
- classiq/qmod/builtins/functions/exponentiation.py +32 -2
- classiq/qmod/builtins/functions/gray_code.py +23 -0
- classiq/qmod/builtins/functions/mcx_func.py +10 -0
- classiq/qmod/builtins/operations.py +2 -38
- classiq/qmod/builtins/structs.py +22 -3
- classiq/qmod/native/pretty_printer.py +1 -12
- classiq/qmod/pretty_print/pretty_printer.py +1 -17
- classiq/qmod/qmod_parameter.py +4 -0
- classiq/qmod/qmod_variable.py +38 -63
- classiq/qmod/quantum_function.py +43 -7
- classiq/qmod/semantics/validation/function_name_collisions_validation.py +7 -4
- classiq/qmod/semantics/validation/model_validation.py +7 -2
- classiq/qmod/symbolic_type.py +4 -2
- classiq/qprog_to_cudaq.py +347 -0
- {classiq-0.102.0.dist-info → classiq-1.0.0.dist-info}/METADATA +4 -1
- {classiq-0.102.0.dist-info → classiq-1.0.0.dist-info}/RECORD +93 -76
- classiq/interface/generator/amplitude_loading.py +0 -103
- classiq/interface/model/quantum_expressions/amplitude_loading_operation.py +0 -77
- {classiq-0.102.0.dist-info → classiq-1.0.0.dist-info}/WHEEL +0 -0
- {classiq-0.102.0.dist-info → classiq-1.0.0.dist-info}/licenses/LICENSE.txt +0 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from typing import Literal
|
|
2
2
|
|
|
3
|
+
from classiq.qmod.cparam import CInt
|
|
3
4
|
from classiq.qmod.qfunc import qfunc, qperm
|
|
4
5
|
from classiq.qmod.qmod_parameter import CArray, CBool, CReal
|
|
5
6
|
from classiq.qmod.qmod_variable import (
|
|
@@ -65,6 +66,58 @@ def add_inplace_right(
|
|
|
65
66
|
pass
|
|
66
67
|
|
|
67
68
|
|
|
69
|
+
@qperm(external=True)
|
|
70
|
+
def canonical_add(
|
|
71
|
+
left: Const[QArray],
|
|
72
|
+
extend_left: CBool,
|
|
73
|
+
right: QArray,
|
|
74
|
+
) -> None:
|
|
75
|
+
"""
|
|
76
|
+
[Qmod core-library function]
|
|
77
|
+
|
|
78
|
+
Adds two quantum variables representing integers (signed or unsigned), storing the
|
|
79
|
+
result in the second variable (in-place):
|
|
80
|
+
|
|
81
|
+
$$
|
|
82
|
+
\\left|\\text{left}\\right\\rangle \\left|\\text{right}\\right\\rangle
|
|
83
|
+
\\mapsto
|
|
84
|
+
\\left|\\text{left}\\right\\rangle \\left|\\left(\\text{right} +
|
|
85
|
+
\\text{left}\\right) \\bmod 2^{\\text{right.size}} \\right\\rangle
|
|
86
|
+
$$
|
|
87
|
+
|
|
88
|
+
Args:
|
|
89
|
+
left: The out-of-place argument for the addition.
|
|
90
|
+
extend_left: Whether to sign-extend the left argument.
|
|
91
|
+
right: The in-place argument for the addition, holds the final result.
|
|
92
|
+
"""
|
|
93
|
+
pass
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
@qperm(external=True)
|
|
97
|
+
def canonical_add_constant(
|
|
98
|
+
left: CInt,
|
|
99
|
+
right: QArray,
|
|
100
|
+
) -> None:
|
|
101
|
+
"""
|
|
102
|
+
[Qmod core-library function]
|
|
103
|
+
|
|
104
|
+
Adds an integer constant to a quantum variable representing an integer (signed or
|
|
105
|
+
unsigned):
|
|
106
|
+
|
|
107
|
+
$$
|
|
108
|
+
\\left|\\text{right}\\right\\rangle
|
|
109
|
+
\\mapsto
|
|
110
|
+
\\left|\\left(\\text{right} +
|
|
111
|
+
\\text{left}\\right) \\bmod 2^{\\text{right.size}} \\right\\rangle
|
|
112
|
+
$$
|
|
113
|
+
|
|
114
|
+
Args:
|
|
115
|
+
left: The constant argument for the addition.
|
|
116
|
+
right: The quantum argument for the addition, holds the final result.
|
|
117
|
+
"""
|
|
118
|
+
pass
|
|
119
|
+
|
|
120
|
+
|
|
68
121
|
@qperm(external=True)
|
|
69
122
|
def modular_add(left: Const[QArray[QBit]], right: QArray[QBit]) -> None:
|
|
70
123
|
pass
|
|
@@ -83,3 +136,133 @@ def integer_xor(left: Const[QArray[QBit]], right: QArray[QBit]) -> None:
|
|
|
83
136
|
@qperm(external=True)
|
|
84
137
|
def real_xor_constant(left: CReal, right: QNum) -> None:
|
|
85
138
|
pass
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
@qperm(external=True)
|
|
142
|
+
def multiply(left: Const[QNum], right: Const[QNum], result: Output[QNum]) -> None:
|
|
143
|
+
"""
|
|
144
|
+
[Qmod core-library function]
|
|
145
|
+
|
|
146
|
+
Multiplies two quantum numeric variables:
|
|
147
|
+
|
|
148
|
+
$$
|
|
149
|
+
\\left|\\text{left}\\right\\rangle \\left|\\text{right}\\right\\rangle
|
|
150
|
+
\\mapsto
|
|
151
|
+
\\left|\\text{left}\\right\\rangle \\left|\\text{right}\\right\\rangle
|
|
152
|
+
\\left|\\text{left} \\cdot \\text{right} \\right\\rangle
|
|
153
|
+
$$
|
|
154
|
+
|
|
155
|
+
Args:
|
|
156
|
+
left: The first argument for the multiplication.
|
|
157
|
+
right: The second argument for the multiplication.
|
|
158
|
+
result: The quantum variable to hold the multiplication result.
|
|
159
|
+
"""
|
|
160
|
+
pass
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
@qperm(external=True)
|
|
164
|
+
def multiply_constant(left: CReal, right: Const[QNum], result: Output[QNum]) -> None:
|
|
165
|
+
"""
|
|
166
|
+
[Qmod core-library function]
|
|
167
|
+
|
|
168
|
+
Multiplies a quantum numeric variable with a constant:
|
|
169
|
+
|
|
170
|
+
$$
|
|
171
|
+
\\left|\\text{right}\\right\\rangle
|
|
172
|
+
\\mapsto
|
|
173
|
+
\\left|\\text{right}\\right\\rangle
|
|
174
|
+
\\left|\\text{left} \\cdot \\text{right} \\right\\rangle
|
|
175
|
+
$$
|
|
176
|
+
|
|
177
|
+
Args:
|
|
178
|
+
left: The constant argument for the multiplication.
|
|
179
|
+
right: The variable argument for the multiplication.
|
|
180
|
+
result: The quantum variable to hold the multiplication result.
|
|
181
|
+
"""
|
|
182
|
+
pass
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
@qperm(external=True)
|
|
186
|
+
def canonical_multiply(
|
|
187
|
+
left: Const[QArray],
|
|
188
|
+
extend_left: CBool,
|
|
189
|
+
right: Const[QArray],
|
|
190
|
+
extend_right: CBool,
|
|
191
|
+
result: QArray,
|
|
192
|
+
trim_result_lsb: CBool,
|
|
193
|
+
) -> None:
|
|
194
|
+
"""
|
|
195
|
+
[Qmod core-library function]
|
|
196
|
+
|
|
197
|
+
Multiplies two quantum variables representing integers (signed or unsigned) into the
|
|
198
|
+
result variable which is assumed to start in the $|0\\rangle$ state.
|
|
199
|
+
|
|
200
|
+
If `trim_result_lsb` is `False`, applies the transformation:
|
|
201
|
+
|
|
202
|
+
$$
|
|
203
|
+
\\left|\\text{left}\\right\\rangle \\left|\\text{right}\\right\\rangle
|
|
204
|
+
\\left|0\\right\\rangle \\mapsto \\left|\\text{left}\\right\\rangle
|
|
205
|
+
\\left|\\text{right}\\right\\rangle \\left|\\left( \\text{left} \\cdot
|
|
206
|
+
\\text{right} \\right) \\bmod 2^{\\text{result.size}} \\right\\rangle
|
|
207
|
+
$$
|
|
208
|
+
|
|
209
|
+
If `trim_result_lsb` is `True`, the function avoids computing the result's LSB and
|
|
210
|
+
applies the transformation:
|
|
211
|
+
|
|
212
|
+
$$
|
|
213
|
+
\\left|\\text{left}\\right\\rangle \\left|\\text{right}\\right\\rangle
|
|
214
|
+
\\left|0\\right\\rangle \\mapsto \\left|\\text{left}\\right\\rangle
|
|
215
|
+
\\left|\\text{right}\\right\\rangle \\left|\\left( \\text{left} \\cdot
|
|
216
|
+
\\text{right} \\right) \\gg 1 \\bmod 2^{\\text{result.size}} \\right\\rangle
|
|
217
|
+
$$
|
|
218
|
+
|
|
219
|
+
Args:
|
|
220
|
+
left: The first argument for the multiplication.
|
|
221
|
+
extend_left: Whether to sign-extend the left argument.
|
|
222
|
+
right: The second argument for the multiplication.
|
|
223
|
+
extend_right: Whether to sign-extend the right argument.
|
|
224
|
+
result: The quantum variable to hold the multiplication result.
|
|
225
|
+
trim_result_lsb: Whether to avoid computing the result's LSB.
|
|
226
|
+
"""
|
|
227
|
+
pass
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
@qperm(external=True)
|
|
231
|
+
def canonical_multiply_constant(
|
|
232
|
+
left: CInt,
|
|
233
|
+
right: Const[QArray],
|
|
234
|
+
extend_right: CBool,
|
|
235
|
+
result: QArray,
|
|
236
|
+
trim_result_lsb: CBool,
|
|
237
|
+
) -> None:
|
|
238
|
+
"""
|
|
239
|
+
[Qmod core-library function]
|
|
240
|
+
|
|
241
|
+
Multiplies a quantum variable representing an integer (signed or unsigned) with a
|
|
242
|
+
constant, into the result variable which is assumed to start in the $|0\\rangle$ state.
|
|
243
|
+
|
|
244
|
+
If `trim_result_lsb` is `False`, applies the transformation:
|
|
245
|
+
|
|
246
|
+
$$
|
|
247
|
+
\\left|\\text{right}\\right\\rangle \\left|0\\right\\rangle \\mapsto
|
|
248
|
+
\\left|\\text{right}\\right\\rangle \\left|\\left( \\text{left} \\cdot
|
|
249
|
+
\\text{right} \\right) \\bmod 2^{\\text{result.size}} \\right\\rangle
|
|
250
|
+
$$
|
|
251
|
+
|
|
252
|
+
If `trim_result_lsb` is `True`, the function avoids computing the result's LSB and
|
|
253
|
+
applies the transformation:
|
|
254
|
+
|
|
255
|
+
$$
|
|
256
|
+
\\left|\\text{right}\\right\\rangle \\left|0\\right\\rangle \\mapsto
|
|
257
|
+
\\left|\\text{right}\\right\\rangle \\left|\\left( \\text{left} \\cdot
|
|
258
|
+
\\text{right} \\right) \\gg 1 \\bmod 2^{\\text{result.size}} \\right\\rangle
|
|
259
|
+
$$
|
|
260
|
+
|
|
261
|
+
Args:
|
|
262
|
+
left: The constant argument for the multiplication.
|
|
263
|
+
right: The variable argument for the multiplication.
|
|
264
|
+
extend_right: Whether to sign-extend the right argument.
|
|
265
|
+
result: The quantum variable to hold the multiplication result.
|
|
266
|
+
trim_result_lsb: Whether to avoid computing the result's LSB.
|
|
267
|
+
"""
|
|
268
|
+
pass
|
|
@@ -99,7 +99,7 @@ def multi_suzuki_trotter(
|
|
|
99
99
|
The error of a Suzuki-Trotter decomposition decreases as the order and number of repetitions increase.
|
|
100
100
|
|
|
101
101
|
Args:
|
|
102
|
-
hamiltonians: The
|
|
102
|
+
hamiltonians: The hamiltonians to be exponentiated, in sparse representation.
|
|
103
103
|
evolution_coefficients: The hamiltonian coefficients (can be link-time).
|
|
104
104
|
order: The order of the Suzuki-Trotter decomposition.
|
|
105
105
|
repetitions: The number of repetitions of the Suzuki-Trotter decomposition.
|
|
@@ -129,7 +129,37 @@ def unscheduled_suzuki_trotter(
|
|
|
129
129
|
The error of a Suzuki-Trotter decomposition decreases as the order and number of repetitions increase.
|
|
130
130
|
|
|
131
131
|
Args:
|
|
132
|
-
hamiltonians: The
|
|
132
|
+
hamiltonians: The hamiltonians to be exponentiated, in sparse representation.
|
|
133
|
+
evolution_coefficients: The hamiltonian coefficients (can be link-time).
|
|
134
|
+
order: The order of the Suzuki-Trotter decomposition.
|
|
135
|
+
repetitions: The number of repetitions of the Suzuki-Trotter decomposition.
|
|
136
|
+
qbv: The target quantum variable of the exponentiation.
|
|
137
|
+
"""
|
|
138
|
+
pass
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
@qfunc(external=True)
|
|
142
|
+
def sequential_suzuki_trotter(
|
|
143
|
+
hamiltonians: CArray[SparsePauliOp],
|
|
144
|
+
evolution_coefficients: CArray[CReal],
|
|
145
|
+
order: CInt,
|
|
146
|
+
repetitions: CInt,
|
|
147
|
+
qbv: QArray,
|
|
148
|
+
) -> None:
|
|
149
|
+
"""
|
|
150
|
+
[Qmod core-library function]
|
|
151
|
+
|
|
152
|
+
Applies the Suzuki-Trotter decomposition jointly to a sum of Hamiltonians
|
|
153
|
+
(represented as Pauli operators), each with its separate evolution coefficient,
|
|
154
|
+
approximating $\\exp{-iH_1t_1+H_2t_2+\\dots}$ with a specified order and number of
|
|
155
|
+
repetitions. Does not reorder the Pauli terms.
|
|
156
|
+
|
|
157
|
+
The Suzuki-Trotter decomposition is a method for approximating the exponential of a sum of operators by a product of exponentials of each operator.
|
|
158
|
+
The Suzuki-Trotter decomposition of a given order nullifies the error of the Taylor series expansion of the product of exponentials up to that order.
|
|
159
|
+
The error of a Suzuki-Trotter decomposition decreases as the order and number of repetitions increase.
|
|
160
|
+
|
|
161
|
+
Args:
|
|
162
|
+
hamiltonians: The hamiltonians to be exponentiated, in sparse representation.
|
|
133
163
|
evolution_coefficients: The hamiltonian coefficients (can be link-time).
|
|
134
164
|
order: The order of the Suzuki-Trotter decomposition.
|
|
135
165
|
repetitions: The number of repetitions of the Suzuki-Trotter decomposition.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from classiq.qmod.builtins.enums import Pauli
|
|
2
|
+
from classiq.qmod.qfunc import qfunc
|
|
3
|
+
from classiq.qmod.qmod_parameter import CArray, CReal
|
|
4
|
+
from classiq.qmod.qmod_variable import QBit, QNum
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@qfunc(external=True)
|
|
8
|
+
def select_rotation(
|
|
9
|
+
basis: Pauli, angles: CArray[CReal], selector: QNum, target: QBit
|
|
10
|
+
) -> None:
|
|
11
|
+
"""
|
|
12
|
+
[Qmod core-library function]
|
|
13
|
+
|
|
14
|
+
Applies a set of controlled single-qubit rotations to a target qubit, using
|
|
15
|
+
a specified rotation axis and a list of rotation angles.
|
|
16
|
+
|
|
17
|
+
Args:
|
|
18
|
+
basis: The Pauli operator defining the rotation axis.
|
|
19
|
+
angles: The list of rotation angles in radians. The list must have length 2**selector.size.
|
|
20
|
+
selector: The qubits that act as the selection register.
|
|
21
|
+
target: The qubit on which the selected rotation is applied.
|
|
22
|
+
"""
|
|
23
|
+
pass
|
|
@@ -5,3 +5,13 @@ from classiq.qmod.qmod_variable import Const, QArray, QBit
|
|
|
5
5
|
@qperm(external=True)
|
|
6
6
|
def mcx(ctrl: Const[QArray[QBit]], target: QBit) -> None:
|
|
7
7
|
pass
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@qperm(external=True)
|
|
11
|
+
def mcx_gray_code(ctrl: Const[QArray[QBit]], target: QBit) -> None:
|
|
12
|
+
pass
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@qperm(external=True)
|
|
16
|
+
def mcx_hybrid_rec(ctrl: Const[QArray[QBit]], target: QBit, aux: QArray[QBit]) -> None:
|
|
17
|
+
pass
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import inspect
|
|
2
2
|
import sys
|
|
3
|
-
import warnings
|
|
4
3
|
from collections.abc import Callable, Mapping
|
|
5
4
|
from functools import wraps
|
|
6
5
|
from itertools import product
|
|
@@ -14,7 +13,7 @@ from typing import (
|
|
|
14
13
|
overload,
|
|
15
14
|
)
|
|
16
15
|
|
|
17
|
-
from classiq.interface.exceptions import
|
|
16
|
+
from classiq.interface.exceptions import ClassiqValueError
|
|
18
17
|
from classiq.interface.generator.expressions.expression import Expression
|
|
19
18
|
from classiq.interface.generator.functions.builtins.internal_operators import (
|
|
20
19
|
REPEAT_OPERATOR_NAME,
|
|
@@ -33,9 +32,6 @@ from classiq.interface.model.control import Control
|
|
|
33
32
|
from classiq.interface.model.invert import BlockKind, Invert
|
|
34
33
|
from classiq.interface.model.phase_operation import PhaseOperation
|
|
35
34
|
from classiq.interface.model.power import Power
|
|
36
|
-
from classiq.interface.model.quantum_expressions.amplitude_loading_operation import (
|
|
37
|
-
AmplitudeLoadingOperation,
|
|
38
|
-
)
|
|
39
35
|
from classiq.interface.model.quantum_expressions.arithmetic_operation import (
|
|
40
36
|
ArithmeticOperation,
|
|
41
37
|
ArithmeticOperationKind,
|
|
@@ -336,37 +332,6 @@ def assign(expression: SymbolicExpr, target_var: QScalar) -> None:
|
|
|
336
332
|
)
|
|
337
333
|
|
|
338
334
|
|
|
339
|
-
@suppress_return_value
|
|
340
|
-
@qmod_statement
|
|
341
|
-
def assign_amplitude(expression: SymbolicExpr, target_var: QScalar) -> None:
|
|
342
|
-
"""
|
|
343
|
-
Perform an amplitude-encoding assignment operation on a quantum variable and a
|
|
344
|
-
quantum expression.
|
|
345
|
-
|
|
346
|
-
Equivalent to `<target_var> *= <expression>`.
|
|
347
|
-
|
|
348
|
-
Args:
|
|
349
|
-
expression: A quantum arithmetic expression
|
|
350
|
-
target_var: A scalar quantum variable
|
|
351
|
-
"""
|
|
352
|
-
warnings.warn(
|
|
353
|
-
"The 'assign_amplitude' function is deprecated and will no longer be "
|
|
354
|
-
"supported starting on 2025-12-03 at the earliest. Use 'assign_amplitude_table' "
|
|
355
|
-
"instead",
|
|
356
|
-
ClassiqDeprecationWarning,
|
|
357
|
-
stacklevel=3,
|
|
358
|
-
)
|
|
359
|
-
assert QCallable.CURRENT_EXPANDABLE is not None
|
|
360
|
-
source_ref = get_source_ref(sys._getframe(2))
|
|
361
|
-
QCallable.CURRENT_EXPANDABLE.append_statement_to_body(
|
|
362
|
-
AmplitudeLoadingOperation(
|
|
363
|
-
expression=Expression(expr=str(expression)),
|
|
364
|
-
result_var=target_var.get_handle_binding(),
|
|
365
|
-
source_ref=source_ref,
|
|
366
|
-
)
|
|
367
|
-
)
|
|
368
|
-
|
|
369
|
-
|
|
370
335
|
@suppress_return_value
|
|
371
336
|
@qmod_statement
|
|
372
337
|
def inplace_add(expression: SymbolicExpr, target_var: QScalar) -> None:
|
|
@@ -553,7 +518,7 @@ def power(
|
|
|
553
518
|
|
|
554
519
|
@suppress_return_value
|
|
555
520
|
@qmod_statement
|
|
556
|
-
def invert(stmt_block: QCallable | Callable[[], Statements]) ->
|
|
521
|
+
def invert(stmt_block: QCallable | Callable[[], Statements]) -> Any:
|
|
557
522
|
"""
|
|
558
523
|
Apply the inverse of a quantum gate.
|
|
559
524
|
|
|
@@ -868,7 +833,6 @@ def lookup_table(func: RealFunction, targets: QNum | list[QNum]) -> list[float]:
|
|
|
868
833
|
__all__ = [
|
|
869
834
|
"allocate",
|
|
870
835
|
"assign",
|
|
871
|
-
"assign_amplitude",
|
|
872
836
|
"assign_amplitude_poly_sin",
|
|
873
837
|
"bind",
|
|
874
838
|
"block",
|
classiq/qmod/builtins/structs.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from dataclasses import dataclass, fields, is_dataclass
|
|
2
|
-
from typing import Union
|
|
2
|
+
from typing import Any, Union
|
|
3
3
|
|
|
4
4
|
from classiq.interface.exceptions import ClassiqValueError
|
|
5
5
|
from classiq.interface.generator.types.struct_declaration import StructDeclaration
|
|
@@ -117,13 +117,21 @@ class SparsePauliOp:
|
|
|
117
117
|
def __rmul__(self, obj: Union[float, "SparsePauliOp"]) -> "SparsePauliOp":
|
|
118
118
|
return self.__mul__(obj)
|
|
119
119
|
|
|
120
|
-
def __add__(self, other:
|
|
120
|
+
def __add__(self, other: Any) -> "SparsePauliOp":
|
|
121
|
+
if not isinstance(other, SparsePauliOp):
|
|
122
|
+
raise ClassiqValueError(
|
|
123
|
+
f"Cannot add an object of type {type(other).__name__} to SparsePauliOp"
|
|
124
|
+
)
|
|
121
125
|
return SparsePauliOp(
|
|
122
126
|
terms=LenList(self.terms + other.terms),
|
|
123
127
|
num_qubits=max(self.num_qubits, other.num_qubits),
|
|
124
128
|
)
|
|
125
129
|
|
|
126
|
-
def __sub__(self, other:
|
|
130
|
+
def __sub__(self, other: Any) -> "SparsePauliOp":
|
|
131
|
+
if not isinstance(other, SparsePauliOp):
|
|
132
|
+
raise ClassiqValueError(
|
|
133
|
+
f"Cannot substruct an object of type {type(other).__name__} to SparsePauliOp"
|
|
134
|
+
)
|
|
127
135
|
return self + -1.0 * other
|
|
128
136
|
|
|
129
137
|
def __str__(self) -> str:
|
|
@@ -136,6 +144,17 @@ class SparsePauliOp:
|
|
|
136
144
|
for term in self.terms
|
|
137
145
|
)
|
|
138
146
|
|
|
147
|
+
def __truediv__(self, other: Any) -> "SparsePauliOp":
|
|
148
|
+
if not isinstance(other, (int, float)):
|
|
149
|
+
raise ClassiqValueError(
|
|
150
|
+
f"Cannot divide SparsePauliOp by object of type {type(other).__name__}"
|
|
151
|
+
)
|
|
152
|
+
if other == 0:
|
|
153
|
+
raise ClassiqValueError("Cannot divide by zero")
|
|
154
|
+
return SparsePauliOp(terms=self.terms, num_qubits=self.num_qubits) * float(
|
|
155
|
+
1 / other
|
|
156
|
+
)
|
|
157
|
+
|
|
139
158
|
|
|
140
159
|
@dataclass
|
|
141
160
|
class CombinatorialOptimizationSolution:
|
|
@@ -51,9 +51,6 @@ from classiq.interface.model.port_declaration import (
|
|
|
51
51
|
AnonPortDeclaration,
|
|
52
52
|
)
|
|
53
53
|
from classiq.interface.model.power import Power
|
|
54
|
-
from classiq.interface.model.quantum_expressions.amplitude_loading_operation import (
|
|
55
|
-
AmplitudeLoadingOperation,
|
|
56
|
-
)
|
|
57
54
|
from classiq.interface.model.quantum_expressions.arithmetic_operation import (
|
|
58
55
|
ArithmeticOperation,
|
|
59
56
|
ArithmeticOperationKind,
|
|
@@ -367,12 +364,9 @@ class DSLPrettyPrinter(ModelVisitor):
|
|
|
367
364
|
return power_code
|
|
368
365
|
|
|
369
366
|
def visit_Invert(self, invert: Invert) -> str:
|
|
367
|
+
invert.validate_node()
|
|
370
368
|
match invert.block_kind:
|
|
371
369
|
case BlockKind.SingleCall:
|
|
372
|
-
if len(invert.body) != 1 or not isinstance(
|
|
373
|
-
invert.body[0], QuantumFunctionCall
|
|
374
|
-
):
|
|
375
|
-
raise ClassiqInternalError("Malformed single-call invert")
|
|
376
370
|
invert_code = f"{self._indent}invert "
|
|
377
371
|
invert_code += self.visit(invert.body[0]).lstrip()
|
|
378
372
|
case BlockKind.Compound:
|
|
@@ -446,11 +440,6 @@ class DSLPrettyPrinter(ModelVisitor):
|
|
|
446
440
|
op = "+="
|
|
447
441
|
return f"{self._indent}{self.visit(arith_op.result_var)} {op} {self.visit(arith_op.expression)};\n"
|
|
448
442
|
|
|
449
|
-
def visit_AmplitudeLoadingOperation(
|
|
450
|
-
self, amplitude_loading_op: AmplitudeLoadingOperation
|
|
451
|
-
) -> str:
|
|
452
|
-
return f"{self._indent}{self.visit(amplitude_loading_op.result_var)} *= {self.visit(amplitude_loading_op.expression)};\n"
|
|
453
|
-
|
|
454
443
|
def _print_bind_handles(self, handles: list[HandleBinding]) -> str:
|
|
455
444
|
if len(handles) == 1:
|
|
456
445
|
return self.visit(handles[0])
|
|
@@ -52,9 +52,6 @@ from classiq.interface.model.native_function_definition import NativeFunctionDef
|
|
|
52
52
|
from classiq.interface.model.phase_operation import PhaseOperation
|
|
53
53
|
from classiq.interface.model.port_declaration import AnonPortDeclaration
|
|
54
54
|
from classiq.interface.model.power import Power
|
|
55
|
-
from classiq.interface.model.quantum_expressions.amplitude_loading_operation import (
|
|
56
|
-
AmplitudeLoadingOperation,
|
|
57
|
-
)
|
|
58
55
|
from classiq.interface.model.quantum_expressions.arithmetic_operation import (
|
|
59
56
|
ArithmeticOperation,
|
|
60
57
|
ArithmeticOperationKind,
|
|
@@ -508,13 +505,10 @@ class PythonPrettyPrinter(ModelVisitor):
|
|
|
508
505
|
return f"{self._indent}power({self.visit(power.power)}, {self._visit_body(power.body)})\n"
|
|
509
506
|
|
|
510
507
|
def visit_Invert(self, invert: Invert) -> str:
|
|
508
|
+
invert.validate_node()
|
|
511
509
|
self._imports["invert"] = 1
|
|
512
510
|
match invert.block_kind:
|
|
513
511
|
case BlockKind.SingleCall:
|
|
514
|
-
if len(invert.body) != 1 or not isinstance(
|
|
515
|
-
invert.body[0], QuantumFunctionCall
|
|
516
|
-
):
|
|
517
|
-
raise ClassiqInternalError("Malformed single-call invert")
|
|
518
512
|
call_str = self.visit(invert.body[0])
|
|
519
513
|
call_str = call_str.replace("(", ")(", 1)
|
|
520
514
|
return f"{self._indent}invert({call_str}\n"
|
|
@@ -540,8 +534,6 @@ class PythonPrettyPrinter(ModelVisitor):
|
|
|
540
534
|
for i, statement in enumerate(body):
|
|
541
535
|
if isinstance(statement, VariableDeclarationStatement):
|
|
542
536
|
code += self.visit_VariableDeclarationStatement(statement, walrus=True)
|
|
543
|
-
elif isinstance(statement, AmplitudeLoadingOperation):
|
|
544
|
-
code += self.visit_AmplitudeLoadingOperation(statement, in_lambda=True)
|
|
545
537
|
elif isinstance(statement, ArithmeticOperation):
|
|
546
538
|
code += self.visit_ArithmeticOperation(statement, in_lambda=True)
|
|
547
539
|
else:
|
|
@@ -599,14 +591,6 @@ class PythonPrettyPrinter(ModelVisitor):
|
|
|
599
591
|
return f"{func}({self.visit(arith_op.expression)}, {self._indent}{self.visit(arith_op.result_var)})\n"
|
|
600
592
|
return f"{self._indent}{self.visit(arith_op.result_var)} {op} {self.visit(arith_op.expression)}\n"
|
|
601
593
|
|
|
602
|
-
def visit_AmplitudeLoadingOperation(
|
|
603
|
-
self, amplitude_loading_op: AmplitudeLoadingOperation, in_lambda: bool = False
|
|
604
|
-
) -> str:
|
|
605
|
-
if in_lambda:
|
|
606
|
-
self._imports["assign_amplitude"] = 1
|
|
607
|
-
return f"assign_amplitude({self.visit(amplitude_loading_op.expression)}, {self._indent}{self.visit(amplitude_loading_op.result_var)})\n"
|
|
608
|
-
return f"{self._indent}{self.visit(amplitude_loading_op.result_var)} *= {self.visit(amplitude_loading_op.expression)}\n"
|
|
609
|
-
|
|
610
594
|
def _print_bind_handles(self, handles: list[HandleBinding]) -> str:
|
|
611
595
|
if len(handles) == 1:
|
|
612
596
|
return self.visit(handles[0])
|
classiq/qmod/qmod_parameter.py
CHANGED
|
@@ -63,6 +63,10 @@ class CParamList(CParam):
|
|
|
63
63
|
else:
|
|
64
64
|
param_type = self._list_type.element_type
|
|
65
65
|
else:
|
|
66
|
+
if key.start is None:
|
|
67
|
+
key = slice(0, key.stop, None)
|
|
68
|
+
if key.stop is None:
|
|
69
|
+
key = slice(key.start, self.len, None)
|
|
66
70
|
if not isinstance(self._list_type, ClassicalTuple):
|
|
67
71
|
param_type = self._list_type
|
|
68
72
|
else:
|
classiq/qmod/qmod_variable.py
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import abc
|
|
2
2
|
import sys
|
|
3
|
-
import warnings
|
|
4
3
|
from collections.abc import Iterator, Mapping
|
|
5
4
|
from contextlib import contextmanager
|
|
6
5
|
from typing import ( # type: ignore[attr-defined]
|
|
@@ -23,7 +22,6 @@ from typing import ( # type: ignore[attr-defined]
|
|
|
23
22
|
from typing_extensions import ParamSpec, Self, _AnnotatedAlias
|
|
24
23
|
|
|
25
24
|
from classiq.interface.exceptions import (
|
|
26
|
-
ClassiqDeprecationWarning,
|
|
27
25
|
ClassiqInternalError,
|
|
28
26
|
ClassiqNotImplementedError,
|
|
29
27
|
ClassiqValueError,
|
|
@@ -45,9 +43,6 @@ from classiq.interface.model.handle_binding import (
|
|
|
45
43
|
SlicedHandleBinding,
|
|
46
44
|
SubscriptHandleBinding,
|
|
47
45
|
)
|
|
48
|
-
from classiq.interface.model.quantum_expressions.amplitude_loading_operation import (
|
|
49
|
-
AmplitudeLoadingOperation,
|
|
50
|
-
)
|
|
51
46
|
from classiq.interface.model.quantum_expressions.arithmetic_operation import (
|
|
52
47
|
ArithmeticOperation,
|
|
53
48
|
ArithmeticOperationKind,
|
|
@@ -161,37 +156,6 @@ class QVar(Symbolic):
|
|
|
161
156
|
def type_name(self) -> str:
|
|
162
157
|
return self.get_qmod_type().type_name
|
|
163
158
|
|
|
164
|
-
|
|
165
|
-
class QmodExpressionCreator(Protocol):
|
|
166
|
-
"""
|
|
167
|
-
A callable that creates a Qmod expression from the provided QVars.
|
|
168
|
-
"""
|
|
169
|
-
|
|
170
|
-
def __call__(self, **kwargs: QVar) -> SymbolicExpr: ...
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
_Q = TypeVar("_Q", bound=QVar)
|
|
174
|
-
Output = Annotated[_Q, PortDeclarationDirection.Output]
|
|
175
|
-
Input = Annotated[_Q, PortDeclarationDirection.Input]
|
|
176
|
-
Const = Annotated[
|
|
177
|
-
_Q, TypeModifier.Const
|
|
178
|
-
] # A constant variable, up to a phase dependent on the computational basis state
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
class QScalar(QVar, SymbolicExpr):
|
|
182
|
-
CONSTRUCTOR_DEPTH: int = 2
|
|
183
|
-
|
|
184
|
-
def __init__(
|
|
185
|
-
self,
|
|
186
|
-
origin: None | str | HandleBinding = None,
|
|
187
|
-
*,
|
|
188
|
-
_expr_str: str | None = None,
|
|
189
|
-
depth: int = 2,
|
|
190
|
-
) -> None:
|
|
191
|
-
origin = _infer_variable_name(origin, self.CONSTRUCTOR_DEPTH)
|
|
192
|
-
QVar.__init__(self, origin, expr_str=_expr_str, depth=depth)
|
|
193
|
-
SymbolicExpr.__init__(self, str(origin), True)
|
|
194
|
-
|
|
195
159
|
def _insert_arith_operation(
|
|
196
160
|
self,
|
|
197
161
|
expr: SymbolicTypes,
|
|
@@ -210,19 +174,6 @@ class QScalar(QVar, SymbolicExpr):
|
|
|
210
174
|
)
|
|
211
175
|
)
|
|
212
176
|
|
|
213
|
-
def _insert_amplitude_loading(
|
|
214
|
-
self, expr: SymbolicTypes, source_ref: SourceReference
|
|
215
|
-
) -> None:
|
|
216
|
-
if TYPE_CHECKING:
|
|
217
|
-
assert QCallable.CURRENT_EXPANDABLE is not None
|
|
218
|
-
QCallable.CURRENT_EXPANDABLE.append_statement_to_body(
|
|
219
|
-
AmplitudeLoadingOperation(
|
|
220
|
-
expression=Expression(expr=str(expr)),
|
|
221
|
-
result_var=self.get_handle_binding(),
|
|
222
|
-
source_ref=source_ref,
|
|
223
|
-
)
|
|
224
|
-
)
|
|
225
|
-
|
|
226
177
|
def __ior__(self, other: Any) -> Self:
|
|
227
178
|
if not isinstance(other, SYMBOLIC_TYPES):
|
|
228
179
|
raise ClassiqValueError(
|
|
@@ -245,6 +196,37 @@ class QScalar(QVar, SymbolicExpr):
|
|
|
245
196
|
)
|
|
246
197
|
return self
|
|
247
198
|
|
|
199
|
+
|
|
200
|
+
class QmodExpressionCreator(Protocol):
|
|
201
|
+
"""
|
|
202
|
+
A callable that creates a Qmod expression from the provided QVars.
|
|
203
|
+
"""
|
|
204
|
+
|
|
205
|
+
def __call__(self, **kwargs: QVar) -> SymbolicExpr: ...
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
_Q = TypeVar("_Q", bound=QVar)
|
|
209
|
+
Output = Annotated[_Q, PortDeclarationDirection.Output]
|
|
210
|
+
Input = Annotated[_Q, PortDeclarationDirection.Input]
|
|
211
|
+
Const = Annotated[
|
|
212
|
+
_Q, TypeModifier.Const
|
|
213
|
+
] # A constant variable, up to a phase dependent on the computational basis state
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
class QScalar(QVar, SymbolicExpr):
|
|
217
|
+
CONSTRUCTOR_DEPTH: int = 2
|
|
218
|
+
|
|
219
|
+
def __init__(
|
|
220
|
+
self,
|
|
221
|
+
origin: None | str | HandleBinding = None,
|
|
222
|
+
*,
|
|
223
|
+
_expr_str: str | None = None,
|
|
224
|
+
depth: int = 2,
|
|
225
|
+
) -> None:
|
|
226
|
+
origin = _infer_variable_name(origin, self.CONSTRUCTOR_DEPTH)
|
|
227
|
+
QVar.__init__(self, origin, expr_str=_expr_str, depth=depth)
|
|
228
|
+
SymbolicExpr.__init__(self, str(origin), True)
|
|
229
|
+
|
|
248
230
|
def __iadd__(self, other: Any) -> Self:
|
|
249
231
|
if not isinstance(other, SYMBOLIC_TYPES):
|
|
250
232
|
raise ClassiqValueError(
|
|
@@ -256,21 +238,10 @@ class QScalar(QVar, SymbolicExpr):
|
|
|
256
238
|
)
|
|
257
239
|
return self
|
|
258
240
|
|
|
259
|
-
def __imul__(self, other: Any) ->
|
|
260
|
-
|
|
261
|
-
"
|
|
262
|
-
"starting on 2025-12-03 at the earliest. Use the 'assign_amplitude_table' "
|
|
263
|
-
"function instead",
|
|
264
|
-
ClassiqDeprecationWarning,
|
|
265
|
-
stacklevel=2,
|
|
241
|
+
def __imul__(self, other: Any) -> NoReturn:
|
|
242
|
+
raise ClassiqNotImplementedError(
|
|
243
|
+
f"{self.get_qmod_type().raw_qmod_type_name} does not support '*='"
|
|
266
244
|
)
|
|
267
|
-
if not isinstance(other, SYMBOLIC_TYPES):
|
|
268
|
-
raise ClassiqValueError(
|
|
269
|
-
f"Invalid argument {str(other)!r} for out of ampltiude encoding operation"
|
|
270
|
-
)
|
|
271
|
-
|
|
272
|
-
self._insert_amplitude_loading(other, get_source_ref(sys._getframe(1)))
|
|
273
|
-
return self
|
|
274
245
|
|
|
275
246
|
def __iand__(self, other: Any) -> NoReturn:
|
|
276
247
|
raise ClassiqNotImplementedError(
|
|
@@ -558,6 +529,10 @@ class QArray(ArrayBase[_P], QVar, NonSymbolicExpr):
|
|
|
558
529
|
def _get_slice(self, slice_: slice) -> Any:
|
|
559
530
|
if slice_.step is not None:
|
|
560
531
|
raise ClassiqValueError(ILLEGAL_SLICING_STEP_MSG)
|
|
532
|
+
if slice_.start is None:
|
|
533
|
+
slice_ = slice(0, slice_.stop, None)
|
|
534
|
+
if slice_.stop is None:
|
|
535
|
+
slice_ = slice(slice_.start, self.len, None)
|
|
561
536
|
if not isinstance(slice_.start, (int, SymbolicExpr)) or not isinstance(
|
|
562
537
|
slice_.stop, (int, SymbolicExpr)
|
|
563
538
|
):
|