classiq 0.60.1__py3-none-any.whl → 0.61.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/client.py +6 -1
- classiq/applications/__init__.py +1 -1
- classiq/applications/chemistry/__init__.py +7 -7
- classiq/applications/chemistry/chemistry_model_constructor.py +17 -6
- classiq/applications/combinatorial_optimization/__init__.py +7 -1
- classiq/applications/combinatorial_optimization/combinatorial_optimization_model_constructor.py +2 -0
- classiq/applications/combinatorial_optimization/combinatorial_problem.py +197 -0
- classiq/applications/finance/finance_model_constructor.py +6 -6
- classiq/applications/grover/grover_model_constructor.py +3 -0
- classiq/applications/libraries/qmci_library.py +1 -10
- classiq/applications/qnn/__init__.py +1 -1
- classiq/applications/qnn/datasets/__init__.py +8 -8
- classiq/applications/qsvm/qsvm.py +1 -1
- classiq/execution/__init__.py +0 -2
- classiq/execution/execution_session.py +6 -0
- classiq/executor.py +1 -1
- classiq/interface/_version.py +1 -1
- classiq/interface/backend/backend_preferences.py +12 -12
- classiq/interface/executor/execution_preferences.py +1 -1
- classiq/interface/generator/application_apis/chemistry_declarations.py +1 -1
- classiq/interface/generator/application_apis/finance_declarations.py +2 -2
- classiq/interface/generator/arith/arithmetic.py +16 -1
- classiq/interface/generator/arith/arithmetic_expression_validator.py +4 -3
- classiq/interface/generator/expressions/expression_constants.py +3 -0
- classiq/interface/generator/generated_circuit_data.py +58 -20
- classiq/interface/generator/model/__init__.py +1 -1
- classiq/interface/generator/model/quantum_register.py +3 -3
- classiq/interface/generator/standard_gates/controlled_standard_gates.py +20 -32
- classiq/interface/ide/visual_model.py +1 -0
- classiq/interface/interface_version.py +1 -1
- classiq/interface/model/model.py +2 -3
- classiq/interface/model/quantum_function_call.py +4 -7
- classiq/interface/model/quantum_function_declaration.py +7 -0
- classiq/interface/model/quantum_lambda_function.py +10 -1
- classiq/interface/model/quantum_type.py +3 -1
- classiq/model_expansions/atomic_expression_functions_defs.py +3 -1
- classiq/model_expansions/capturing/captured_vars.py +24 -8
- classiq/model_expansions/capturing/mangling_utils.py +23 -15
- classiq/model_expansions/evaluators/arg_type_match.py +7 -7
- classiq/model_expansions/expression_evaluator.py +5 -2
- classiq/model_expansions/function_builder.py +21 -4
- classiq/model_expansions/generative_functions.py +12 -90
- classiq/model_expansions/interpreter.py +58 -11
- classiq/model_expansions/quantum_operations/call_emitter.py +19 -10
- classiq/model_expansions/quantum_operations/classicalif.py +1 -1
- classiq/model_expansions/quantum_operations/control.py +5 -31
- classiq/model_expansions/quantum_operations/emitter.py +27 -14
- classiq/model_expansions/quantum_operations/expression_operation.py +3 -5
- classiq/model_expansions/quantum_operations/inplace_binary_operation.py +57 -15
- classiq/model_expansions/quantum_operations/invert.py +1 -6
- classiq/model_expansions/quantum_operations/phase.py +2 -5
- classiq/model_expansions/quantum_operations/power.py +0 -4
- classiq/model_expansions/quantum_operations/quantum_assignment_operation.py +19 -30
- classiq/model_expansions/quantum_operations/quantum_function_call.py +3 -1
- classiq/model_expansions/quantum_operations/shallow_emitter.py +155 -0
- classiq/model_expansions/quantum_operations/within_apply.py +0 -14
- classiq/model_expansions/scope.py +10 -4
- classiq/model_expansions/scope_initialization.py +0 -11
- classiq/model_expansions/sympy_conversion/expression_to_sympy.py +7 -0
- classiq/model_expansions/sympy_conversion/sympy_to_python.py +12 -2
- classiq/model_expansions/transformers/ast_renamer.py +26 -0
- classiq/model_expansions/transformers/var_splitter.py +11 -12
- classiq/model_expansions/visitors/variable_references.py +20 -12
- classiq/qmod/builtins/classical_execution_primitives.py +6 -6
- classiq/qmod/builtins/classical_functions.py +10 -10
- classiq/qmod/builtins/functions/__init__.py +89 -103
- classiq/qmod/builtins/functions/amplitude_estimation.py +1 -1
- classiq/qmod/builtins/functions/arithmetic.py +1 -1
- classiq/qmod/builtins/functions/discrete_sine_cosine_transform.py +6 -6
- classiq/qmod/builtins/functions/grover.py +5 -5
- classiq/qmod/builtins/functions/hea.py +1 -1
- classiq/qmod/builtins/functions/linear_pauli_rotation.py +2 -2
- classiq/qmod/builtins/functions/modular_exponentiation.py +8 -8
- classiq/qmod/builtins/functions/operators.py +1 -1
- classiq/qmod/builtins/functions/qaoa_penalty.py +5 -5
- classiq/qmod/builtins/functions/qft_functions.py +2 -2
- classiq/qmod/builtins/functions/qpe.py +9 -12
- classiq/qmod/builtins/functions/qsvt.py +177 -15
- classiq/qmod/builtins/functions/state_preparation.py +9 -9
- classiq/qmod/builtins/functions/swap_test.py +1 -1
- classiq/qmod/builtins/functions/utility_functions.py +2 -2
- classiq/qmod/builtins/functions/variational.py +2 -2
- classiq/qmod/builtins/operations.py +3 -3
- classiq/qmod/builtins/structs.py +9 -9
- classiq/qmod/native/pretty_printer.py +17 -19
- classiq/qmod/pretty_print/pretty_printer.py +9 -6
- classiq/qmod/qmod_variable.py +2 -5
- classiq/qmod/quantum_expandable.py +18 -4
- classiq/qmod/quantum_function.py +19 -6
- classiq/qmod/semantics/static_semantics_visitor.py +34 -16
- classiq/qmod/semantics/validation/func_call_validation.py +9 -5
- classiq/qmod/semantics/validation/function_name_collisions_validation.py +23 -0
- classiq/qmod/symbolic.py +47 -47
- {classiq-0.60.1.dist-info → classiq-0.61.0.dist-info}/METADATA +1 -1
- {classiq-0.60.1.dist-info → classiq-0.61.0.dist-info}/RECORD +97 -94
- classiq/execution/qaoa.py +0 -86
- {classiq-0.60.1.dist-info → classiq-0.61.0.dist-info}/WHEEL +0 -0
@@ -8,7 +8,7 @@ from classiq.qmod.qmod_parameter import CArray, CInt, CReal
|
|
8
8
|
from classiq.qmod.qmod_variable import QArray, QBit
|
9
9
|
|
10
10
|
|
11
|
-
@qfunc
|
11
|
+
@qfunc
|
12
12
|
def qaoa_mixer_layer(b: CReal, target: QArray[QBit]) -> None:
|
13
13
|
"""
|
14
14
|
[Qmod Classiq-library function]
|
@@ -24,7 +24,7 @@ def qaoa_mixer_layer(b: CReal, target: QArray[QBit]) -> None:
|
|
24
24
|
repeat(target.len, lambda index: RX(b, target[index]))
|
25
25
|
|
26
26
|
|
27
|
-
@qfunc
|
27
|
+
@qfunc
|
28
28
|
def qaoa_cost_layer(
|
29
29
|
g: CReal, hamiltonian: CArray[PauliTerm], target: QArray[QBit]
|
30
30
|
) -> None:
|
@@ -45,7 +45,7 @@ def qaoa_cost_layer(
|
|
45
45
|
suzuki_trotter(hamiltonian, g, 1, 1, target)
|
46
46
|
|
47
47
|
|
48
|
-
@qfunc
|
48
|
+
@qfunc
|
49
49
|
def qaoa_layer(
|
50
50
|
g: CReal, b: CReal, hamiltonian: CArray[PauliTerm], target: QArray[QBit]
|
51
51
|
) -> None:
|
@@ -69,7 +69,7 @@ def qaoa_layer(
|
|
69
69
|
qaoa_mixer_layer(b, target)
|
70
70
|
|
71
71
|
|
72
|
-
@qfunc
|
72
|
+
@qfunc
|
73
73
|
def qaoa_init(target: QArray[QBit]) -> None:
|
74
74
|
"""
|
75
75
|
[Qmod Classiq-library function]
|
@@ -86,7 +86,7 @@ def qaoa_init(target: QArray[QBit]) -> None:
|
|
86
86
|
repeat(target.len, lambda index: H(target[index]))
|
87
87
|
|
88
88
|
|
89
|
-
@qfunc
|
89
|
+
@qfunc
|
90
90
|
def qaoa_penalty(
|
91
91
|
num_qubits: CInt,
|
92
92
|
params_list: CArray[CReal],
|
@@ -5,7 +5,7 @@ from classiq.qmod.qmod_variable import QArray, QBit
|
|
5
5
|
from classiq.qmod.symbolic import pi
|
6
6
|
|
7
7
|
|
8
|
-
@qfunc
|
8
|
+
@qfunc
|
9
9
|
def qft_no_swap(qbv: QArray[QBit]) -> None:
|
10
10
|
"""
|
11
11
|
[Qmod Classiq-library function]
|
@@ -32,7 +32,7 @@ def qft_no_swap(qbv: QArray[QBit]) -> None:
|
|
32
32
|
)
|
33
33
|
|
34
34
|
|
35
|
-
@qfunc
|
35
|
+
@qfunc
|
36
36
|
def qft(target: QArray[QBit]) -> None:
|
37
37
|
"""
|
38
38
|
[Qmod Classiq-library function]
|
@@ -1,15 +1,15 @@
|
|
1
1
|
from classiq.qmod.builtins.functions.qft_functions import qft
|
2
2
|
from classiq.qmod.builtins.functions.standard_gates import H
|
3
3
|
from classiq.qmod.builtins.functions.utility_functions import apply_to_all
|
4
|
-
from classiq.qmod.builtins.operations import
|
4
|
+
from classiq.qmod.builtins.operations import control, invert, power, repeat
|
5
5
|
from classiq.qmod.cparam import CInt
|
6
6
|
from classiq.qmod.qfunc import qfunc
|
7
|
-
from classiq.qmod.qmod_variable import QArray, QNum
|
7
|
+
from classiq.qmod.qmod_variable import QArray, QBit, QNum
|
8
8
|
from classiq.qmod.quantum_callable import QCallable
|
9
9
|
|
10
10
|
|
11
|
-
@qfunc
|
12
|
-
def qpe_flexible(unitary_with_power: QCallable[CInt], phase:
|
11
|
+
@qfunc
|
12
|
+
def qpe_flexible(unitary_with_power: QCallable[CInt], phase: QArray[QBit]) -> None:
|
13
13
|
"""
|
14
14
|
[Qmod Classiq-library function]
|
15
15
|
|
@@ -20,22 +20,19 @@ def qpe_flexible(unitary_with_power: QCallable[CInt], phase: QNum) -> None:
|
|
20
20
|
unitary_with_power: A callable that returns the unitary operator $U^k$ given an integer $k$. This callable is used to control the application of powers of the unitary operator.
|
21
21
|
phase: The quantum variable that represents the estimated phase (eigenvalue), assuming initialized to zero.
|
22
22
|
"""
|
23
|
-
|
24
|
-
bind(phase, phase_array)
|
25
|
-
apply_to_all(H, phase_array)
|
23
|
+
apply_to_all(H, phase)
|
26
24
|
|
27
25
|
repeat(
|
28
|
-
count=
|
26
|
+
count=phase.len,
|
29
27
|
iteration=lambda index: control(
|
30
|
-
ctrl=
|
28
|
+
ctrl=phase[index], stmt_block=lambda: unitary_with_power(2**index)
|
31
29
|
),
|
32
30
|
)
|
33
31
|
|
34
|
-
invert(lambda: qft(
|
35
|
-
bind(phase_array, phase)
|
32
|
+
invert(lambda: qft(phase))
|
36
33
|
|
37
34
|
|
38
|
-
@qfunc
|
35
|
+
@qfunc
|
39
36
|
def qpe(unitary: QCallable, phase: QNum) -> None:
|
40
37
|
"""
|
41
38
|
[Qmod Classiq-library function]
|
@@ -1,13 +1,13 @@
|
|
1
1
|
from classiq.qmod.builtins.functions.standard_gates import IDENTITY, RZ, H
|
2
|
-
from classiq.qmod.builtins.operations import if_, invert, repeat
|
2
|
+
from classiq.qmod.builtins.operations import control, if_, invert, repeat, within_apply
|
3
3
|
from classiq.qmod.qfunc import qfunc
|
4
4
|
from classiq.qmod.qmod_parameter import CArray, CReal
|
5
5
|
from classiq.qmod.qmod_variable import QArray, QBit
|
6
6
|
from classiq.qmod.quantum_callable import QCallable
|
7
|
-
from classiq.qmod.symbolic import floor
|
7
|
+
from classiq.qmod.symbolic import floor, min as qmin
|
8
8
|
|
9
9
|
|
10
|
-
@qfunc
|
10
|
+
@qfunc
|
11
11
|
def qsvt_step(
|
12
12
|
phase1: CReal,
|
13
13
|
phase2: CReal,
|
@@ -23,7 +23,7 @@ def qsvt_step(
|
|
23
23
|
Applies a single QSVT step, composed of 2 projector-controlled-phase rotations, and applications of the block encoding unitary `u` and its inverse:
|
24
24
|
|
25
25
|
$$
|
26
|
-
\\Pi_{\\phi_2}U^{\\dagger}
|
26
|
+
\\Pi_{\\phi_2}U^{\\dagger}\\tilde{\\Pi}_{\\phi_{1}}U
|
27
27
|
$$
|
28
28
|
|
29
29
|
Args:
|
@@ -41,7 +41,7 @@ def qsvt_step(
|
|
41
41
|
projector_controlled_phase(phase2, proj_cnot_1, qvar, aux)
|
42
42
|
|
43
43
|
|
44
|
-
@qfunc
|
44
|
+
@qfunc
|
45
45
|
def qsvt(
|
46
46
|
phase_seq: CArray[CReal],
|
47
47
|
proj_cnot_1: QCallable[QArray[QBit], QBit],
|
@@ -53,17 +53,17 @@ def qsvt(
|
|
53
53
|
"""
|
54
54
|
[Qmod Classiq-library function]
|
55
55
|
|
56
|
-
Implements the Quantum Singular Value Transformation (QSVT) - an algorithmic framework, used to apply polynomial transformations of degree `d` on the singular values of a block encoded matrix, given as the unitary `u`. Given a unitary $U$, a list of phase angles $\\phi_1, \\phi_2, ..., \\phi_{d+1}$ and 2 projector-controlled-not operands $C_{\\Pi}NOT,C_{
|
57
|
-
Given a unitary $U$, a list of phase angles $\\phi_1, \\phi_2, ..., \\phi_{d+1}$ and 2 projector-controlled-not operands $C_{\\Pi}NOT,C_{
|
56
|
+
Implements the Quantum Singular Value Transformation (QSVT) - an algorithmic framework, used to apply polynomial transformations of degree `d` on the singular values of a block encoded matrix, given as the unitary `u`. Given a unitary $U$, a list of phase angles $\\phi_1, \\phi_2, ..., \\phi_{d+1}$ and 2 projector-controlled-not operands $C_{\\Pi}NOT,C_{\\tilde{\\Pi}}NOT$, the QSVT sequence is as follows:
|
57
|
+
Given a unitary $U$, a list of phase angles $\\phi_1, \\phi_2, ..., \\phi_{d+1}$ and 2 projector-controlled-not operands $C_{\\Pi}NOT,C_{\\tilde{\\Pi}}NOT$, the QSVT sequence is as follows:
|
58
58
|
|
59
59
|
$$
|
60
|
-
|
60
|
+
\\tilde{\\Pi}_{\\phi_{d+1}}U \\prod_{k=1}^{(d-1)/2} (\\Pi_{\\phi_{d-2k}} U^{\\dagger}\\tilde{\\Pi}_{\\phi_{d - (2k+1)}}U)\\Pi_{\\phi_{1}}
|
61
61
|
$$
|
62
62
|
|
63
63
|
for odd $d$, and:
|
64
64
|
|
65
65
|
$$
|
66
|
-
\\prod_{k=1}^{d/2} (\\Pi_{\\phi_{d-(2k-1)}} U^{\\dagger}
|
66
|
+
\\prod_{k=1}^{d/2} (\\Pi_{\\phi_{d-(2k-1)}} U^{\\dagger}\\tilde{\\Pi}_{\\phi_{d-2k}}U)\\Pi_{\\phi_{1}}
|
67
67
|
$$
|
68
68
|
|
69
69
|
for even $d$.
|
@@ -111,7 +111,7 @@ def qsvt(
|
|
111
111
|
H(aux)
|
112
112
|
|
113
113
|
|
114
|
-
@qfunc
|
114
|
+
@qfunc
|
115
115
|
def projector_controlled_phase(
|
116
116
|
phase: CReal,
|
117
117
|
proj_cnot: QCallable[QArray[QBit], QBit],
|
@@ -128,17 +128,15 @@ def projector_controlled_phase(
|
|
128
128
|
$$
|
129
129
|
|
130
130
|
Args:
|
131
|
-
|
131
|
+
phase: A rotation phase.
|
132
132
|
proj_cnot: Projector-controlled-not unitary that sets an auxilliary qubit to |1> when the state is in the projection.
|
133
133
|
qvar: The quantum variable to which the rotation applies, which resides in the entire block encoding space.
|
134
134
|
aux: A zero auxilliary qubit, used for the projector-controlled-phase rotation. Given as an inout so that qsvt can be used as a building-block in a larger algorithm.
|
135
135
|
"""
|
136
|
-
proj_cnot(qvar, aux)
|
137
|
-
RZ(phase, aux)
|
138
|
-
proj_cnot(qvar, aux)
|
136
|
+
within_apply(lambda: proj_cnot(qvar, aux), lambda: RZ(phase, aux))
|
139
137
|
|
140
138
|
|
141
|
-
@qfunc
|
139
|
+
@qfunc
|
142
140
|
def qsvt_inversion(
|
143
141
|
phase_seq: CArray[CReal],
|
144
142
|
block_encoding_cnot: QCallable[QArray[QBit], QBit],
|
@@ -167,3 +165,167 @@ def qsvt_inversion(
|
|
167
165
|
qvar,
|
168
166
|
aux,
|
169
167
|
)
|
168
|
+
|
169
|
+
|
170
|
+
@qfunc
|
171
|
+
def projector_controlled_double_phase(
|
172
|
+
phase_even: CReal,
|
173
|
+
phase_odd: CReal,
|
174
|
+
proj_cnot: QCallable[QArray[QBit], QBit],
|
175
|
+
qvar: QArray[QBit],
|
176
|
+
aux: QBit,
|
177
|
+
lcu: QBit,
|
178
|
+
) -> None:
|
179
|
+
"""
|
180
|
+
[Qmod Classiq-library function]
|
181
|
+
|
182
|
+
Assigns 2 phases to the entire subspace determined by the given projector, each one is controlled differentely on a given `lcu` qvar.
|
183
|
+
Used in the context of the `qsvt_lcu` function. Corresponds to the operation:
|
184
|
+
|
185
|
+
$$
|
186
|
+
\\Pi_{\\phi_{odd}, \\phi_{even}} = (C_{\\Pi}NOT) (C_{lcu=1}e^{-i\\frac{\\phi_{even}}{2}Z}) (C_{lcu=0}e^{-i\\frac{\\phi_{odd}}{2}Z}) (C_{\\Pi}NOT)
|
187
|
+
$$
|
188
|
+
|
189
|
+
Args:
|
190
|
+
phase_even: Rotation phase, corresponds to 'lcu'=1.
|
191
|
+
phase_odd: Rotation phase, corresponds to 'lcu'=0.
|
192
|
+
proj_cnot: Projector-controlled-not unitary that sets an auxilliary qubit to |1> when the state is in the projection.
|
193
|
+
qvar: The quantum variable to which the rotation applies, which resides in the entire block encoding space.
|
194
|
+
aux: A zero auxilliary qubit, used for the projector-controlled-phase rotation. Given as an inout so that qsvt can be used as a building-block in a larger algorithm.
|
195
|
+
"""
|
196
|
+
within_apply(
|
197
|
+
lambda: proj_cnot(qvar, aux),
|
198
|
+
lambda: control(lcu, lambda: RZ(phase_even, aux), lambda: RZ(phase_odd, aux)),
|
199
|
+
)
|
200
|
+
|
201
|
+
|
202
|
+
@qfunc
|
203
|
+
def qsvt_lcu_step(
|
204
|
+
phases_even: CArray[CReal],
|
205
|
+
phases_odd: CArray[CReal],
|
206
|
+
proj_cnot_1: QCallable[QArray[QBit], QBit],
|
207
|
+
proj_cnot_2: QCallable[QArray[QBit], QBit],
|
208
|
+
u: QCallable[QArray[QBit]],
|
209
|
+
qvar: QArray[QBit],
|
210
|
+
aux: QBit,
|
211
|
+
lcu: QBit,
|
212
|
+
) -> None:
|
213
|
+
"""
|
214
|
+
[Qmod Classiq-library function]
|
215
|
+
|
216
|
+
Applies a single QSVT-lcu step, composed of 2 double phase projector-controlled-phase rotations, and applications of the block encoding unitary `u` and its inverse:
|
217
|
+
|
218
|
+
$$
|
219
|
+
(C_{lcu=1}\\Pi^{even}_{\\phi_2})(C_{lcu=0}\\Pi^{odd}_{\\phi_2})U^{\\dagger}(C_{lcu=1}\\tilde{\\Pi}^{even}_{\\phi_1})(C_{lcu=0}\\tilde{\\Pi}^{odd}_{\\phi_1})U
|
220
|
+
$$
|
221
|
+
|
222
|
+
Args:
|
223
|
+
phases_even: 2 rotation phases for the even polynomial
|
224
|
+
phases_odd: 2 rotation phases for the odd polynomial
|
225
|
+
proj_cnot_1: Projector-controlled-not unitary that locates the encoded matrix columns within U. Accepts a quantum variable of the same size as qvar, and a qubit that is set to |1> when the state is in the block.
|
226
|
+
proj_cnot_2: Projector-controlled-not unitary that locates the encoded matrix rows within U. Accepts a quantum variable of the same size as qvar, and a qubit that is set to |1> when the state is in the block.
|
227
|
+
u: A block encoded unitary matrix.
|
228
|
+
qvar: The quantum variable to which U is applied, which resides in the entire block encoding space.
|
229
|
+
aux: A zero auxilliary qubit, used for the projector-controlled-phase rotations. Given as an inout so that qsvt can be used as a building-block in a larger algorithm.
|
230
|
+
lcu: A qubit used for the combination of 2 polynomials within a single qsvt application
|
231
|
+
"""
|
232
|
+
u(qvar)
|
233
|
+
projector_controlled_double_phase(
|
234
|
+
phases_even[0], phases_odd[0], proj_cnot_2, qvar, aux, lcu
|
235
|
+
)
|
236
|
+
invert(lambda: u(qvar))
|
237
|
+
projector_controlled_double_phase(
|
238
|
+
phases_even[1], phases_odd[1], proj_cnot_1, qvar, aux, lcu
|
239
|
+
)
|
240
|
+
|
241
|
+
|
242
|
+
@qfunc
|
243
|
+
def qsvt_lcu(
|
244
|
+
phase_seq_even: CArray[CReal],
|
245
|
+
phase_seq_odd: CArray[CReal],
|
246
|
+
proj_cnot_1: QCallable[QArray[QBit], QBit],
|
247
|
+
proj_cnot_2: QCallable[QArray[QBit], QBit],
|
248
|
+
u: QCallable[QArray[QBit]],
|
249
|
+
qvar: QArray[QBit],
|
250
|
+
aux: QBit,
|
251
|
+
lcu: QBit,
|
252
|
+
) -> None:
|
253
|
+
"""
|
254
|
+
[Qmod Classiq-library function]
|
255
|
+
|
256
|
+
Implements the Quantum Singular Value Transformation (QSVT) for a linear combination of odd and even polynomials, so that
|
257
|
+
it is possible to encode a polynomial of indefinite parity, such as approximation to exp(i*A) or exp(A). Should work
|
258
|
+
for Hermitian block encodings.
|
259
|
+
|
260
|
+
The function is equivalent to applying the `qsvt` function for odd and even polynomials with a LCU function, but
|
261
|
+
is more efficient as the two polynomials share the same applications of the given unitary.
|
262
|
+
|
263
|
+
The function is intended to be called within a context of LCU, where it is called as the SELECT operator, and wrapped
|
264
|
+
with initialization of the `lcu` qubit to get the desired combination coefficients.
|
265
|
+
The even polynomial corresponds to the case where the $lcu=|0\\rangle$, while the odd to #lcu=|1\\rangle$.
|
266
|
+
|
267
|
+
Note: the two polynomials should have the same degree up to a difference of 1.
|
268
|
+
|
269
|
+
Args:
|
270
|
+
phase_seq_odd: A sequence of phase angles of length d+1 for the odd polynomial.
|
271
|
+
phase_seq_even: A sequence of phase angles of length d+1 for the even polynomial.
|
272
|
+
proj_cnot_1: Projector-controlled-not unitary that locates the encoded matrix columns within U. Accepts a quantum variable of the same size as qvar, and a qubit that is set to |1> when the state is in the block.
|
273
|
+
proj_cnot_2: Projector-controlled-not unitary that locates the encoded matrix rows within U. Accepts a quantum variable of the same size as qvar, and a qubit that is set to |1> when the state is in the block.
|
274
|
+
u: A block encoded unitary matrix.
|
275
|
+
qvar: The quantum variable to which U is applied, which resides in the entire block encoding space.
|
276
|
+
aux: A zero auxilliary qubit, used for the projector-controlled-phase rotations. Given as an inout so that qsvt can be used as a building-block in a larger algorithm.
|
277
|
+
lcu: A qubit used for the combination of 2 polynomials within a single qsvt application
|
278
|
+
"""
|
279
|
+
H(aux)
|
280
|
+
projector_controlled_double_phase(
|
281
|
+
phase_seq_even[0], phase_seq_odd[0], proj_cnot_1, qvar, aux, lcu
|
282
|
+
)
|
283
|
+
repeat(
|
284
|
+
count=floor((qmin(phase_seq_odd.len, phase_seq_even.len)) / 2),
|
285
|
+
iteration=lambda index: qsvt_lcu_step(
|
286
|
+
phase_seq_even[2 * index + 1 : 2 * index + 3],
|
287
|
+
phase_seq_odd[2 * index + 1 : 2 * index + 3],
|
288
|
+
proj_cnot_1,
|
289
|
+
proj_cnot_2,
|
290
|
+
u,
|
291
|
+
qvar,
|
292
|
+
aux,
|
293
|
+
lcu,
|
294
|
+
),
|
295
|
+
)
|
296
|
+
if_(
|
297
|
+
condition=phase_seq_odd.len > phase_seq_even.len,
|
298
|
+
then=lambda: control(
|
299
|
+
lcu == 0,
|
300
|
+
lambda: [ # type:ignore[arg-type]
|
301
|
+
u(qvar), # type:ignore[func-returns-value]
|
302
|
+
projector_controlled_phase(
|
303
|
+
phase_seq_odd[phase_seq_odd.len - 1], proj_cnot_2, qvar, aux
|
304
|
+
),
|
305
|
+
],
|
306
|
+
),
|
307
|
+
)
|
308
|
+
if_(
|
309
|
+
condition=phase_seq_odd.len < phase_seq_even.len,
|
310
|
+
then=lambda: ( # type:ignore[arg-type]
|
311
|
+
u(qvar), # type:ignore[func-returns-value]
|
312
|
+
projector_controlled_double_phase(
|
313
|
+
phase_seq_even[phase_seq_even.len - 1],
|
314
|
+
phase_seq_odd[phase_seq_odd.len - 1],
|
315
|
+
proj_cnot_2,
|
316
|
+
qvar,
|
317
|
+
aux,
|
318
|
+
lcu,
|
319
|
+
),
|
320
|
+
control(
|
321
|
+
lcu,
|
322
|
+
lambda: [ # type:ignore[arg-type]
|
323
|
+
invert(lambda: u(qvar)), # type:ignore[func-returns-value]
|
324
|
+
projector_controlled_phase(
|
325
|
+
phase_seq_even[phase_seq_even.len - 1], proj_cnot_1, qvar, aux
|
326
|
+
),
|
327
|
+
],
|
328
|
+
),
|
329
|
+
),
|
330
|
+
)
|
331
|
+
H(aux)
|
@@ -46,7 +46,7 @@ def allocate(
|
|
46
46
|
pass
|
47
47
|
|
48
48
|
|
49
|
-
@qfunc
|
49
|
+
@qfunc
|
50
50
|
def allocate_num(
|
51
51
|
num_qubits: CInt,
|
52
52
|
is_signed: CBool,
|
@@ -200,7 +200,7 @@ def prepare_uniform_trimmed_state_apply_rotation(
|
|
200
200
|
)
|
201
201
|
|
202
202
|
|
203
|
-
@qfunc
|
203
|
+
@qfunc
|
204
204
|
def _prepare_uniform_trimmed_state_step(
|
205
205
|
size_lsb: CInt, ctrl_val: CInt, lsbs_val: CInt, ctrl_var: QNum, rotation_var: QBit
|
206
206
|
) -> None:
|
@@ -215,7 +215,7 @@ def _prepare_uniform_trimmed_state_step(
|
|
215
215
|
)
|
216
216
|
|
217
217
|
|
218
|
-
@qfunc
|
218
|
+
@qfunc
|
219
219
|
def prepare_uniform_trimmed_state(m: CInt, q: QArray[QBit]) -> None:
|
220
220
|
"""
|
221
221
|
[Qmod Classiq-library function]
|
@@ -261,7 +261,7 @@ def prepare_uniform_trimmed_state(m: CInt, q: QArray[QBit]) -> None:
|
|
261
261
|
)
|
262
262
|
|
263
263
|
|
264
|
-
@qfunc
|
264
|
+
@qfunc
|
265
265
|
def prepare_uniform_interval_state(start: CInt, end: CInt, q: QArray[QBit]) -> None:
|
266
266
|
"""
|
267
267
|
[Qmod Classiq-library function]
|
@@ -287,7 +287,7 @@ def prepare_uniform_interval_state(start: CInt, end: CInt, q: QArray[QBit]) -> N
|
|
287
287
|
modular_increment(start, q)
|
288
288
|
|
289
289
|
|
290
|
-
@qfunc
|
290
|
+
@qfunc
|
291
291
|
def prepare_ghz_state(size: CInt, q: Output[QArray[QBit]]) -> None:
|
292
292
|
"""
|
293
293
|
[Qmod Classiq-library function]
|
@@ -319,7 +319,7 @@ def prepare_ghz_state(size: CInt, q: Output[QArray[QBit]]) -> None:
|
|
319
319
|
repeat(floor(log(size - 1, 2)) + 1, inner_lop) # type:ignore[arg-type]
|
320
320
|
|
321
321
|
|
322
|
-
@qfunc
|
322
|
+
@qfunc
|
323
323
|
def prepare_exponential_state(rate: CInt, q: QArray[QBit]) -> None:
|
324
324
|
"""
|
325
325
|
|
@@ -338,7 +338,7 @@ def prepare_exponential_state(rate: CInt, q: QArray[QBit]) -> None:
|
|
338
338
|
repeat(q.len, lambda i: RY(2.0 * atan(exp((-rate * 2.0**i) / 2.0)), q[i]))
|
339
339
|
|
340
340
|
|
341
|
-
@qfunc
|
341
|
+
@qfunc
|
342
342
|
def prepare_bell_state(state_num: CInt, q: Output[QArray[QBit, Literal[2]]]) -> None:
|
343
343
|
"""
|
344
344
|
[Qmod Classiq-library function]
|
@@ -387,7 +387,7 @@ def prepare_bell_state(state_num: CInt, q: Output[QArray[QBit, Literal[2]]]) ->
|
|
387
387
|
CX(q[0], q[1])
|
388
388
|
|
389
389
|
|
390
|
-
@qfunc
|
390
|
+
@qfunc
|
391
391
|
def inplace_prepare_int(value: CInt, target: QArray[QBit]) -> None:
|
392
392
|
"""
|
393
393
|
[Qmod Classiq-library function]
|
@@ -412,7 +412,7 @@ def inplace_prepare_int(value: CInt, target: QArray[QBit]) -> None:
|
|
412
412
|
)
|
413
413
|
|
414
414
|
|
415
|
-
@qfunc
|
415
|
+
@qfunc
|
416
416
|
def prepare_int(
|
417
417
|
value: CInt,
|
418
418
|
out: Output[QNum[Literal["floor(log(value, 2)) + 1"]]],
|
@@ -5,7 +5,7 @@ from classiq.qmod.qfunc import qfunc
|
|
5
5
|
from classiq.qmod.qmod_variable import Output, QArray, QBit
|
6
6
|
|
7
7
|
|
8
|
-
@qfunc
|
8
|
+
@qfunc
|
9
9
|
def swap_test(state1: QArray[QBit], state2: QArray[QBit], test: Output[QBit]) -> None:
|
10
10
|
"""
|
11
11
|
[Qmod Classiq-library function]
|
@@ -6,7 +6,7 @@ from classiq.qmod.qfunc import qfunc
|
|
6
6
|
from classiq.qmod.qmod_variable import QArray, QBit, QCallable
|
7
7
|
|
8
8
|
|
9
|
-
@qfunc
|
9
|
+
@qfunc
|
10
10
|
def apply_to_all(
|
11
11
|
gate_operand: QCallable[Annotated[QBit, "target"]], target: QArray[QBit]
|
12
12
|
) -> None:
|
@@ -23,7 +23,7 @@ def apply_to_all(
|
|
23
23
|
repeat(target.len, lambda index: gate_operand(target[index]))
|
24
24
|
|
25
25
|
|
26
|
-
@qfunc
|
26
|
+
@qfunc
|
27
27
|
def hadamard_transform(target: QArray[QBit]) -> None:
|
28
28
|
"""
|
29
29
|
[Qmod Classiq-library function]
|
@@ -8,7 +8,7 @@ from classiq.qmod.qmod_variable import Output, QArray, QBit
|
|
8
8
|
from classiq.qmod.symbolic import ceiling, floor, pi
|
9
9
|
|
10
10
|
|
11
|
-
@qfunc
|
11
|
+
@qfunc
|
12
12
|
def encode_in_angle(data: CArray[CReal], qba: Output[QArray[QBit]]) -> None:
|
13
13
|
"""
|
14
14
|
[Qmod Classiq-library function]
|
@@ -28,7 +28,7 @@ def encode_in_angle(data: CArray[CReal], qba: Output[QArray[QBit]]) -> None:
|
|
28
28
|
)
|
29
29
|
|
30
30
|
|
31
|
-
@qfunc
|
31
|
+
@qfunc
|
32
32
|
def encode_on_bloch(data: CArray[CReal], qba: Output[QArray]) -> None:
|
33
33
|
"""
|
34
34
|
[Qmod Classiq-library function]
|
@@ -434,14 +434,14 @@ __all__ = [
|
|
434
434
|
"assign_amplitude",
|
435
435
|
"bind",
|
436
436
|
"control",
|
437
|
-
"invert",
|
438
437
|
"if_",
|
439
438
|
"inplace_add",
|
440
439
|
"inplace_xor",
|
440
|
+
"invert",
|
441
|
+
"phase",
|
441
442
|
"power",
|
442
|
-
"within_apply",
|
443
443
|
"repeat",
|
444
|
-
"
|
444
|
+
"within_apply",
|
445
445
|
]
|
446
446
|
|
447
447
|
|
classiq/qmod/builtins/structs.py
CHANGED
@@ -134,18 +134,18 @@ BUILTIN_STRUCT_DECLARATIONS = {
|
|
134
134
|
|
135
135
|
|
136
136
|
__all__ = [
|
137
|
-
"PauliTerm",
|
138
|
-
"MoleculeProblem",
|
139
|
-
"Molecule",
|
140
137
|
"ChemistryAtom",
|
141
|
-
"Position",
|
142
|
-
"FockHamiltonianProblem",
|
143
|
-
"LadderTerm",
|
144
|
-
"LadderOp",
|
145
138
|
"CombinatorialOptimizationSolution",
|
139
|
+
"FinanceFunction",
|
140
|
+
"FockHamiltonianProblem",
|
146
141
|
"GaussianModel",
|
142
|
+
"LadderOp",
|
143
|
+
"LadderTerm",
|
147
144
|
"LogNormalModel",
|
148
|
-
"
|
149
|
-
"
|
145
|
+
"Molecule",
|
146
|
+
"MoleculeProblem",
|
147
|
+
"PauliTerm",
|
148
|
+
"Position",
|
150
149
|
"QSVMFeatureMapPauli",
|
150
|
+
"QsvmResult",
|
151
151
|
]
|
@@ -51,7 +51,6 @@ from classiq.interface.model.quantum_expressions.arithmetic_operation import (
|
|
51
51
|
ArithmeticOperationKind,
|
52
52
|
)
|
53
53
|
from classiq.interface.model.quantum_function_call import (
|
54
|
-
OperandIdentifier,
|
55
54
|
QuantumFunctionCall,
|
56
55
|
)
|
57
56
|
from classiq.interface.model.quantum_function_declaration import (
|
@@ -60,7 +59,10 @@ from classiq.interface.model.quantum_function_declaration import (
|
|
60
59
|
QuantumFunctionDeclaration,
|
61
60
|
QuantumOperandDeclaration,
|
62
61
|
)
|
63
|
-
from classiq.interface.model.quantum_lambda_function import
|
62
|
+
from classiq.interface.model.quantum_lambda_function import (
|
63
|
+
OperandIdentifier,
|
64
|
+
QuantumLambdaFunction,
|
65
|
+
)
|
64
66
|
from classiq.interface.model.quantum_type import (
|
65
67
|
QuantumBit,
|
66
68
|
QuantumBitvector,
|
@@ -76,6 +78,7 @@ from classiq.interface.model.variable_declaration_statement import (
|
|
76
78
|
)
|
77
79
|
from classiq.interface.model.within_apply_operation import WithinApply
|
78
80
|
|
81
|
+
from classiq.qmod.builtins.functions import OPEN_LIBRARY_FUNCTIONS
|
79
82
|
from classiq.qmod.native.expression_to_qmod import transform_expression
|
80
83
|
from classiq.qmod.semantics.static_semantics_visitor import resolve_function_calls
|
81
84
|
from classiq.qmod.utilities import DEFAULT_DECIMAL_PRECISION
|
@@ -85,11 +88,11 @@ class DSLPrettyPrinter(Visitor):
|
|
85
88
|
def __init__(
|
86
89
|
self,
|
87
90
|
decimal_precision: Optional[int] = DEFAULT_DECIMAL_PRECISION,
|
88
|
-
|
91
|
+
emit_open_lib_functions: bool = False,
|
89
92
|
) -> None:
|
90
93
|
self._level = 0
|
91
94
|
self._decimal_precision = decimal_precision
|
92
|
-
self.
|
95
|
+
self._emit_open_lib_functions = emit_open_lib_functions
|
93
96
|
|
94
97
|
def visit(self, node: NodeType) -> str:
|
95
98
|
res = super().visit(node)
|
@@ -168,10 +171,7 @@ class DSLPrettyPrinter(Visitor):
|
|
168
171
|
def visit_QuantumVariableDeclaration(
|
169
172
|
self, var_decl: QuantumVariableDeclaration
|
170
173
|
) -> str:
|
171
|
-
|
172
|
-
if self._rename_phase and var_name == "phase":
|
173
|
-
var_name = "phase_var"
|
174
|
-
return f"{var_name}: {self.visit(var_decl.quantum_type)}"
|
174
|
+
return f"{var_decl.name}: {self.visit(var_decl.quantum_type)}"
|
175
175
|
|
176
176
|
def visit_AnonPortDeclaration(self, port_decl: AnonPortDeclaration) -> str:
|
177
177
|
dir_str = (
|
@@ -179,12 +179,7 @@ class DSLPrettyPrinter(Visitor):
|
|
179
179
|
if port_decl.direction != PortDeclarationDirection.Inout
|
180
180
|
else ""
|
181
181
|
)
|
182
|
-
|
183
|
-
port_decl.name
|
184
|
-
if not (self._rename_phase and port_decl.name == "phase")
|
185
|
-
else "phase_var"
|
186
|
-
)
|
187
|
-
param_name = f"{port_name}: " if port_decl.name is not None else ""
|
182
|
+
param_name = f"{port_decl.name}: " if port_decl.name is not None else ""
|
188
183
|
return f"{dir_str}{param_name}{self.visit(port_decl.quantum_type)}"
|
189
184
|
|
190
185
|
def visit_QuantumBit(self, qtype: QuantumBit) -> str:
|
@@ -250,6 +245,10 @@ class DSLPrettyPrinter(Visitor):
|
|
250
245
|
return self.visit_AnonQuantumOperandDeclaration(op_decl)
|
251
246
|
|
252
247
|
def visit_NativeFunctionDefinition(self, func_def: NativeFunctionDefinition) -> str:
|
248
|
+
if not self._emit_open_lib_functions and func_def.name in [
|
249
|
+
qfunc_.func_decl.name for qfunc_ in OPEN_LIBRARY_FUNCTIONS
|
250
|
+
]:
|
251
|
+
return ""
|
253
252
|
self._level += 1
|
254
253
|
body = "".join(self.visit(qvar_decl) for qvar_decl in func_def.body)
|
255
254
|
self._level -= 1
|
@@ -350,11 +349,7 @@ class DSLPrettyPrinter(Visitor):
|
|
350
349
|
return f"lambda({positional_args}) {{\n{body}{self._indent}}}"
|
351
350
|
|
352
351
|
def visit_HandleBinding(self, var_ref: HandleBinding) -> str:
|
353
|
-
return
|
354
|
-
var_ref.name
|
355
|
-
if not (self._rename_phase and var_ref.name == "phase")
|
356
|
-
else "phase_var"
|
357
|
-
)
|
352
|
+
return var_ref.name
|
358
353
|
|
359
354
|
def visit_SlicedHandleBinding(self, var_ref: SlicedHandleBinding) -> str:
|
360
355
|
return f"{self.visit(var_ref.base_handle)}[{self.visit(var_ref.start)}:{self.visit(var_ref.end)}]"
|
@@ -391,6 +386,9 @@ class DSLPrettyPrinter(Visitor):
|
|
391
386
|
def visit_list(self, node: list) -> str:
|
392
387
|
return "[" + ", ".join(self.visit(elem) for elem in node) + "]"
|
393
388
|
|
389
|
+
def visit_OperandIdentifier(self, op: OperandIdentifier) -> str:
|
390
|
+
return str(op)
|
391
|
+
|
394
392
|
@property
|
395
393
|
def _indent(self) -> str:
|
396
394
|
return " " * self._level
|
@@ -52,7 +52,6 @@ from classiq.interface.model.quantum_expressions.arithmetic_operation import (
|
|
52
52
|
ArithmeticOperationKind,
|
53
53
|
)
|
54
54
|
from classiq.interface.model.quantum_function_call import (
|
55
|
-
OperandIdentifier,
|
56
55
|
QuantumFunctionCall,
|
57
56
|
)
|
58
57
|
from classiq.interface.model.quantum_function_declaration import (
|
@@ -61,7 +60,10 @@ from classiq.interface.model.quantum_function_declaration import (
|
|
61
60
|
QuantumFunctionDeclaration,
|
62
61
|
QuantumOperandDeclaration,
|
63
62
|
)
|
64
|
-
from classiq.interface.model.quantum_lambda_function import
|
63
|
+
from classiq.interface.model.quantum_lambda_function import (
|
64
|
+
OperandIdentifier,
|
65
|
+
QuantumLambdaFunction,
|
66
|
+
)
|
65
67
|
from classiq.interface.model.quantum_type import (
|
66
68
|
QuantumBit,
|
67
69
|
QuantumBitvector,
|
@@ -285,10 +287,8 @@ class PythonPrettyPrinter(Visitor):
|
|
285
287
|
raise ClassiqInternalError
|
286
288
|
|
287
289
|
is_unsigned = (
|
288
|
-
is_signed_expr.is_evaluated()
|
289
|
-
|
290
|
-
or is_signed_expr.expr == "UNSIGNED"
|
291
|
-
)
|
290
|
+
is_signed_expr.is_evaluated() and not is_signed_expr.to_bool_value()
|
291
|
+
) or is_signed_expr.expr == "UNSIGNED"
|
292
292
|
is_integer = (
|
293
293
|
fraction_digits_expr.is_evaluated()
|
294
294
|
and fraction_digits_expr.to_int_value() == 0
|
@@ -526,6 +526,9 @@ class PythonPrettyPrinter(Visitor):
|
|
526
526
|
def visit_list(self, node: list) -> str:
|
527
527
|
return "[" + ", ".join(self.visit(elem) for elem in node) + "]"
|
528
528
|
|
529
|
+
def visit_OperandIdentifier(self, op: OperandIdentifier) -> str:
|
530
|
+
return str(op)
|
531
|
+
|
529
532
|
@property
|
530
533
|
def _indent(self) -> str:
|
531
534
|
return " " * self._level
|