classiq 0.60.1__py3-none-any.whl → 0.62.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.
Files changed (108) hide show
  1. classiq/__init__.py +2 -0
  2. classiq/_internals/client.py +6 -1
  3. classiq/applications/__init__.py +1 -1
  4. classiq/applications/chemistry/__init__.py +7 -7
  5. classiq/applications/chemistry/chemistry_model_constructor.py +17 -6
  6. classiq/applications/combinatorial_helpers/optimization_model.py +9 -2
  7. classiq/applications/combinatorial_helpers/pyomo_utils.py +60 -9
  8. classiq/applications/combinatorial_optimization/__init__.py +7 -1
  9. classiq/applications/combinatorial_optimization/combinatorial_optimization_model_constructor.py +2 -0
  10. classiq/applications/combinatorial_optimization/combinatorial_problem.py +230 -0
  11. classiq/applications/finance/finance_model_constructor.py +6 -6
  12. classiq/applications/grover/grover_model_constructor.py +3 -0
  13. classiq/applications/libraries/qmci_library.py +1 -10
  14. classiq/applications/qnn/__init__.py +1 -1
  15. classiq/applications/qnn/datasets/__init__.py +8 -8
  16. classiq/applications/qsvm/qsvm.py +1 -1
  17. classiq/execution/__init__.py +0 -2
  18. classiq/execution/execution_session.py +6 -0
  19. classiq/execution/jobs.py +9 -1
  20. classiq/executor.py +1 -1
  21. classiq/interface/_version.py +1 -1
  22. classiq/interface/backend/backend_preferences.py +33 -15
  23. classiq/interface/backend/quantum_backend_providers.py +3 -1
  24. classiq/interface/executor/execution_preferences.py +1 -1
  25. classiq/interface/generator/application_apis/chemistry_declarations.py +1 -1
  26. classiq/interface/generator/application_apis/finance_declarations.py +2 -2
  27. classiq/interface/generator/arith/arithmetic.py +16 -1
  28. classiq/interface/generator/arith/arithmetic_expression_validator.py +4 -3
  29. classiq/interface/generator/copy.py +47 -0
  30. classiq/interface/generator/expressions/expression_constants.py +3 -0
  31. classiq/interface/generator/function_param_list_without_self_reference.py +2 -0
  32. classiq/interface/generator/generated_circuit_data.py +58 -20
  33. classiq/interface/generator/model/__init__.py +1 -1
  34. classiq/interface/generator/model/preferences/preferences.py +1 -1
  35. classiq/interface/generator/model/quantum_register.py +3 -3
  36. classiq/interface/generator/standard_gates/controlled_standard_gates.py +20 -32
  37. classiq/interface/generator/types/compilation_metadata.py +2 -1
  38. classiq/interface/ide/visual_model.py +1 -0
  39. classiq/interface/interface_version.py +1 -1
  40. classiq/interface/model/model.py +2 -3
  41. classiq/interface/model/quantum_function_call.py +4 -7
  42. classiq/interface/model/quantum_function_declaration.py +7 -0
  43. classiq/interface/model/quantum_lambda_function.py +10 -1
  44. classiq/interface/model/quantum_type.py +3 -1
  45. classiq/model_expansions/atomic_expression_functions_defs.py +3 -1
  46. classiq/model_expansions/capturing/captured_vars.py +36 -17
  47. classiq/model_expansions/capturing/mangling_utils.py +23 -15
  48. classiq/model_expansions/closure.py +6 -9
  49. classiq/model_expansions/evaluators/arg_type_match.py +7 -7
  50. classiq/model_expansions/expression_evaluator.py +5 -2
  51. classiq/model_expansions/function_builder.py +26 -4
  52. classiq/model_expansions/generative_functions.py +13 -91
  53. classiq/model_expansions/interpreter.py +75 -46
  54. classiq/model_expansions/quantum_operations/call_emitter.py +42 -29
  55. classiq/model_expansions/quantum_operations/classicalif.py +1 -1
  56. classiq/model_expansions/quantum_operations/control.py +5 -31
  57. classiq/model_expansions/quantum_operations/emitter.py +29 -17
  58. classiq/model_expansions/quantum_operations/expression_operation.py +3 -5
  59. classiq/model_expansions/quantum_operations/inplace_binary_operation.py +57 -15
  60. classiq/model_expansions/quantum_operations/invert.py +1 -6
  61. classiq/model_expansions/quantum_operations/phase.py +2 -5
  62. classiq/model_expansions/quantum_operations/power.py +0 -4
  63. classiq/model_expansions/quantum_operations/quantum_assignment_operation.py +19 -30
  64. classiq/model_expansions/quantum_operations/quantum_function_call.py +4 -2
  65. classiq/model_expansions/quantum_operations/shallow_emitter.py +161 -0
  66. classiq/model_expansions/quantum_operations/within_apply.py +0 -14
  67. classiq/model_expansions/scope.py +12 -16
  68. classiq/model_expansions/scope_initialization.py +0 -11
  69. classiq/model_expansions/sympy_conversion/expression_to_sympy.py +7 -0
  70. classiq/model_expansions/sympy_conversion/sympy_to_python.py +12 -2
  71. classiq/model_expansions/transformers/ast_renamer.py +26 -0
  72. classiq/model_expansions/transformers/var_splitter.py +11 -12
  73. classiq/model_expansions/visitors/variable_references.py +20 -12
  74. classiq/qmod/builtins/classical_execution_primitives.py +6 -6
  75. classiq/qmod/builtins/classical_functions.py +10 -10
  76. classiq/qmod/builtins/functions/__init__.py +89 -103
  77. classiq/qmod/builtins/functions/amplitude_estimation.py +1 -1
  78. classiq/qmod/builtins/functions/arithmetic.py +1 -1
  79. classiq/qmod/builtins/functions/discrete_sine_cosine_transform.py +6 -6
  80. classiq/qmod/builtins/functions/grover.py +5 -5
  81. classiq/qmod/builtins/functions/hea.py +1 -1
  82. classiq/qmod/builtins/functions/linear_pauli_rotation.py +2 -2
  83. classiq/qmod/builtins/functions/modular_exponentiation.py +8 -8
  84. classiq/qmod/builtins/functions/operators.py +1 -1
  85. classiq/qmod/builtins/functions/qaoa_penalty.py +5 -5
  86. classiq/qmod/builtins/functions/qft_functions.py +2 -2
  87. classiq/qmod/builtins/functions/qpe.py +9 -12
  88. classiq/qmod/builtins/functions/qsvt.py +177 -15
  89. classiq/qmod/builtins/functions/state_preparation.py +9 -9
  90. classiq/qmod/builtins/functions/swap_test.py +1 -1
  91. classiq/qmod/builtins/functions/utility_functions.py +2 -2
  92. classiq/qmod/builtins/functions/variational.py +2 -2
  93. classiq/qmod/builtins/operations.py +22 -83
  94. classiq/qmod/builtins/structs.py +9 -9
  95. classiq/qmod/native/pretty_printer.py +17 -19
  96. classiq/qmod/pretty_print/pretty_printer.py +9 -6
  97. classiq/qmod/python_classical_type.py +1 -5
  98. classiq/qmod/qmod_variable.py +2 -5
  99. classiq/qmod/quantum_expandable.py +20 -5
  100. classiq/qmod/quantum_function.py +23 -10
  101. classiq/qmod/semantics/static_semantics_visitor.py +34 -16
  102. classiq/qmod/semantics/validation/func_call_validation.py +9 -5
  103. classiq/qmod/semantics/validation/function_name_collisions_validation.py +23 -0
  104. classiq/qmod/symbolic.py +47 -47
  105. {classiq-0.60.1.dist-info → classiq-0.62.0.dist-info}/METADATA +2 -1
  106. {classiq-0.60.1.dist-info → classiq-0.62.0.dist-info}/RECORD +107 -103
  107. classiq/execution/qaoa.py +0 -86
  108. {classiq-0.60.1.dist-info → classiq-0.62.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(external=True)
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(external=True)
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(external=True)
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(external=True)
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(external=True)
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(external=True)
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(external=True)
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 bind, control, invert, power, repeat
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(external=True)
12
- def qpe_flexible(unitary_with_power: QCallable[CInt], phase: QNum) -> None:
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
- phase_array: QArray = QArray("phase_array")
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=phase_array.len,
26
+ count=phase.len,
29
27
  iteration=lambda index: control(
30
- ctrl=phase_array[index], stmt_block=lambda: unitary_with_power(2**index)
28
+ ctrl=phase[index], stmt_block=lambda: unitary_with_power(2**index)
31
29
  ),
32
30
  )
33
31
 
34
- invert(lambda: qft(phase_array))
35
- bind(phase_array, phase)
32
+ invert(lambda: qft(phase))
36
33
 
37
34
 
38
- @qfunc(external=True)
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(external=True)
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}\tilde{\\Pi}_{\\phi_{1}}U
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(external=True)
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_{\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:
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
- \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}}
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}\tilde{\\Pi}_{\\phi_{d-2k}}U)\\Pi_{\\phi_{1}}
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(external=True)
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
- phase_seq: A rotation phase.
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(external=True)
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(external=True)
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(external=True)
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(external=True)
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(external=True)
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(external=True)
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(external=True)
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(external=True)
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(external=True)
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(external=True)
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(external=True)
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(external=True)
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(external=True)
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(external=True)
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(external=True)
31
+ @qfunc
32
32
  def encode_on_bloch(data: CArray[CReal], qba: Output[QArray]) -> None:
33
33
  """
34
34
  [Qmod Classiq-library function]