classiq 0.99.0__py3-none-any.whl → 0.102.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 (54) hide show
  1. classiq/__init__.py +3 -0
  2. classiq/_internals/api_wrapper.py +29 -4
  3. classiq/applications/chemistry/op_utils.py +31 -1
  4. classiq/applications/chemistry/problems.py +18 -6
  5. classiq/applications/chemistry/ucc.py +2 -2
  6. classiq/evaluators/parameter_types.py +1 -4
  7. classiq/evaluators/qmod_node_evaluators/utils.py +6 -3
  8. classiq/execution/__init__.py +11 -1
  9. classiq/execution/jobs.py +122 -5
  10. classiq/interface/_version.py +1 -1
  11. classiq/interface/exceptions.py +0 -42
  12. classiq/interface/executor/execution_request.py +1 -0
  13. classiq/interface/executor/quantum_code.py +0 -6
  14. classiq/interface/executor/user_budget.py +2 -6
  15. classiq/interface/generator/generation_request.py +40 -0
  16. classiq/interface/generator/quantum_program.py +8 -36
  17. classiq/interface/generator/transpiler_basis_gates.py +1 -3
  18. classiq/interface/generator/types/compilation_metadata.py +1 -1
  19. classiq/interface/helpers/model_normalizer.py +24 -0
  20. classiq/interface/helpers/text_utils.py +20 -5
  21. classiq/interface/model/bind_operation.py +3 -0
  22. classiq/interface/model/invert.py +7 -0
  23. classiq/interface/model/model.py +42 -3
  24. classiq/interface/model/quantum_function_call.py +17 -5
  25. classiq/model_expansions/arithmetic_compute_result_attrs.py +10 -1
  26. classiq/model_expansions/interpreters/base_interpreter.py +3 -2
  27. classiq/model_expansions/quantum_operations/call_emitter.py +0 -3
  28. classiq/model_expansions/visitors/uncomputation_signature_inference.py +15 -38
  29. classiq/open_library/functions/__init__.py +55 -27
  30. classiq/open_library/functions/bit_operations.py +30 -0
  31. classiq/open_library/functions/encodings.py +182 -0
  32. classiq/open_library/functions/modular_arithmetics.py +597 -0
  33. classiq/open_library/functions/qft_space_arithmetics.py +81 -0
  34. classiq/open_library/functions/state_preparation.py +13 -7
  35. classiq/open_library/functions/utility_functions.py +22 -3
  36. classiq/qmod/builtins/functions/exponentiation.py +2 -2
  37. classiq/qmod/builtins/operations.py +29 -4
  38. classiq/qmod/native/pretty_printer.py +15 -4
  39. classiq/qmod/pretty_print/pretty_printer.py +14 -2
  40. classiq/qmod/qmod_variable.py +1 -1
  41. classiq/qmod/quantum_callable.py +8 -2
  42. classiq/qmod/quantum_expandable.py +3 -1
  43. classiq/qmod/quantum_function.py +2 -1
  44. classiq/qmod/semantics/error_manager.py +11 -1
  45. classiq/qmod/utilities.py +7 -4
  46. classiq/synthesis_action/__init__.py +20 -0
  47. classiq/synthesis_action/actions.py +106 -0
  48. {classiq-0.99.0.dist-info → classiq-0.102.0.dist-info}/METADATA +1 -1
  49. {classiq-0.99.0.dist-info → classiq-0.102.0.dist-info}/RECORD +51 -47
  50. classiq/interface/executor/register_initialization.py +0 -36
  51. classiq/open_library/functions/modular_exponentiation.py +0 -272
  52. classiq/open_library/functions/qsvt_temp.py +0 -536
  53. {classiq-0.99.0.dist-info → classiq-0.102.0.dist-info}/WHEEL +0 -0
  54. {classiq-0.99.0.dist-info → classiq-0.102.0.dist-info}/licenses/LICENSE.txt +0 -0
@@ -1,536 +0,0 @@
1
- import warnings
2
-
3
- from classiq.interface.exceptions import ClassiqDeprecationWarning
4
-
5
- from classiq.qmod.builtins.functions.standard_gates import IDENTITY, RZ, H
6
- from classiq.qmod.builtins.operations import control, if_, invert, repeat, within_apply
7
- from classiq.qmod.qfunc import qfunc
8
- from classiq.qmod.qmod_parameter import CArray, CReal
9
- from classiq.qmod.qmod_variable import QArray, QBit
10
- from classiq.qmod.quantum_callable import QCallable
11
- from classiq.qmod.symbolic import floor, min as qmin
12
-
13
- from .qsvt import (
14
- projector_controlled_double_phase as projector_controlled_double_phase_new,
15
- projector_controlled_phase as projector_controlled_phase_new,
16
- qsvt as qsvt_new,
17
- qsvt_inversion as qsvt_inversion_new,
18
- qsvt_lcu as qsvt_lcu_new,
19
- qsvt_lcu_step as qsvt_lcu_step_new,
20
- qsvt_step as qsvt_step_new,
21
- )
22
-
23
-
24
- @qfunc
25
- def qsvt_step_old(
26
- phase1: CReal,
27
- phase2: CReal,
28
- proj_cnot_1: QCallable[QArray[QBit], QBit],
29
- proj_cnot_2: QCallable[QArray[QBit], QBit],
30
- u: QCallable[QArray[QBit]],
31
- qvar: QArray[QBit],
32
- aux: QBit,
33
- ) -> None:
34
- """
35
- [Qmod Classiq-library function]
36
-
37
- Applies a single QSVT step, composed of 2 projector-controlled-phase rotations, and applications of the block encoding unitary `u` and its inverse:
38
-
39
- $$
40
- \\Pi_{\\phi_2}U^{\\dagger}\\tilde{\\Pi}_{\\phi_{1}}U
41
- $$
42
-
43
- Args:
44
- phase1: 1st rotation phase.
45
- phase2: 2nd rotation phase.
46
- 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.
47
- 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.
48
- u: A block encoding unitary matrix.
49
- qvar: The quantum variable to which U is applied, which resides in the entire block encoding space.
50
- 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.
51
- """
52
- u(qvar)
53
- projector_controlled_phase_old(phase1, proj_cnot_2, qvar, aux)
54
- invert(lambda: u(qvar))
55
- projector_controlled_phase_old(phase2, proj_cnot_1, qvar, aux)
56
-
57
-
58
- def qsvt_step(*args, **kwargs): # type: ignore[no-untyped-def]
59
- """
60
- [Qmod Classiq-library function]
61
-
62
- Applies a single QSVT step, composed of 2 projector-controlled-phase rotations, and applications of the block encoding unitary `u` and its inverse:
63
-
64
- $$
65
- \\Pi_{\\phi_2}U^{\\dagger}\\tilde{\\Pi}_{\\phi_{1}}U
66
- $$
67
-
68
- Args:
69
- phase1: 1st rotation phase.
70
- phase2: 2nd rotation phase.
71
- proj_cnot_1: Projector-controlled-not unitary that locates the encoded matrix columns within U. Accepts a qubit that should be set to |1> when the state is in the block.
72
- proj_cnot_2: Projector-controlled-not unitary that locates the encoded matrix rows within U. Accepts a qubit that should be set to |1> when the state is in the block.
73
- u: A block encoding unitary matrix.
74
- 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.
75
- """
76
- if len(args) + len(kwargs) == 7:
77
- return qsvt_step_old(*args, **kwargs)
78
- return qsvt_step_new(*args, **kwargs)
79
-
80
-
81
- @qfunc
82
- def qsvt_old(
83
- phase_seq: CArray[CReal],
84
- proj_cnot_1: QCallable[QArray[QBit], QBit],
85
- proj_cnot_2: QCallable[QArray[QBit], QBit],
86
- u: QCallable[QArray[QBit]],
87
- qvar: QArray[QBit],
88
- aux: QBit,
89
- ) -> None:
90
- """
91
- [Qmod Classiq-library function]
92
-
93
- 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:
94
- 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:
95
-
96
- $$
97
- \\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}}
98
- $$
99
-
100
- for odd $d$, and:
101
-
102
- $$
103
- \\prod_{k=1}^{d/2} (\\Pi_{\\phi_{d-(2k-1)}} U^{\\dagger}\\tilde{\\Pi}_{\\phi_{d-2k}}U)\\Pi_{\\phi_{1}}
104
- $$
105
-
106
- for even $d$.
107
-
108
- Each of the $\\Pi$s is a projector-controlled-phase unitary, according to the given projectors.
109
-
110
- Args:
111
- phase_seq: A sequence of phase angles of length d+1.
112
- 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.
113
- 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.
114
- u: A block encoding unitary matrix.
115
- qvar: The quantum variable to which U is applied, which resides in the entire block encoding space.
116
- 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.
117
- """
118
- H(aux)
119
-
120
- projector_controlled_phase_old(phase_seq[0], proj_cnot_1, qvar, aux)
121
- repeat(
122
- count=floor((phase_seq.len - 1) / 2),
123
- iteration=lambda index: qsvt_step_old(
124
- phase_seq[2 * index + 1],
125
- phase_seq[2 * index + 2],
126
- proj_cnot_1,
127
- proj_cnot_2,
128
- u,
129
- qvar,
130
- aux,
131
- ),
132
- )
133
-
134
- if_(
135
- condition=phase_seq.len % 2 == 1,
136
- then=lambda: IDENTITY(qvar),
137
- else_=lambda: (
138
- u(qvar),
139
- projector_controlled_phase_old(
140
- phase_seq[phase_seq.len - 1],
141
- proj_cnot_2,
142
- qvar,
143
- aux,
144
- ),
145
- ),
146
- )
147
-
148
- H(aux)
149
-
150
-
151
- def qsvt(*args, **kwargs): # type: ignore[no-untyped-def]
152
- """
153
- [Qmod Classiq-library function]
154
-
155
- 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:
156
- 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:
157
-
158
- $$
159
- \\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}}
160
- $$
161
-
162
- for odd $d$, and:
163
-
164
- $$
165
- \\prod_{k=1}^{d/2} (\\Pi_{\\phi_{d-(2k-1)}} U^{\\dagger}\\tilde{\\Pi}_{\\phi_{d-2k}}U)\\Pi_{\\phi_{1}}
166
- $$
167
-
168
- for even $d$.
169
-
170
- Each of the $\\Pi$s is a projector-controlled-phase unitary, according to the given projectors.
171
-
172
- Args:
173
- phase_seq: A sequence of phase angles of length d+1.
174
- proj_cnot_1: Projector-controlled-not unitary that locates the encoded matrix columns within U. Accepts a qubit that should be set to |1> when the state is in the block.
175
- proj_cnot_2: Projector-controlled-not unitary that locates the encoded matrix rows within U. Accepts a qubit that should be set to |1> when the state is in the block.
176
- u: A block encoding unitary matrix.
177
- 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.
178
- """
179
- if len(args) + len(kwargs) == 6:
180
- warnings.warn(
181
- "The 'qsvt' function signature has changed and the old version will be deprecated"
182
- " starting on 2025-12-13 at the earliest",
183
- ClassiqDeprecationWarning,
184
- stacklevel=2,
185
- )
186
- return qsvt_old(*args, **kwargs)
187
- return qsvt_new(*args, **kwargs)
188
-
189
-
190
- @qfunc
191
- def projector_controlled_phase_old(
192
- phase: CReal,
193
- proj_cnot: QCallable[QArray[QBit], QBit],
194
- qvar: QArray[QBit],
195
- aux: QBit,
196
- ) -> None:
197
- """
198
- [Qmod Classiq-library function]
199
-
200
- Assigns a phase to the entire subspace determined by the given projector. Corresponds to the operation:
201
-
202
- $$
203
- \\Pi_{\\phi} = (C_{\\Pi}NOT) e^{-i\frac{\\phi}{2}Z}(C_{\\Pi}NOT)
204
- $$
205
-
206
- Args:
207
- phase: A rotation phase.
208
- proj_cnot: Projector-controlled-not unitary that sets an auxilliary qubit to |1> when the state is in the projection.
209
- qvar: The quantum variable to which the rotation applies, which resides in the entire block encoding space.
210
- 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.
211
- """
212
- within_apply(lambda: proj_cnot(qvar, aux), lambda: RZ(phase, aux))
213
-
214
-
215
- def projector_controlled_phase(*args, **kwargs): # type: ignore[no-untyped-def]
216
- """
217
- [Qmod Classiq-library function]
218
-
219
- Assigns a phase to the entire subspace determined by the given projector. Corresponds to the operation:
220
-
221
- $$
222
- \\Pi_{\\phi} = (C_{\\Pi}NOT) e^{-i\frac{\\phi}{2}Z}(C_{\\Pi}NOT)
223
- $$
224
-
225
- Args:
226
- phase: A rotation phase.
227
- proj_cnot: Projector-controlled-not unitary that sets an auxilliary qubit to |1> when the state is in the projection.
228
- aux: A zero auxilliary qubit, used for the projector-controlled-phase rotation.
229
- """
230
- if len(args) + len(kwargs) == 4:
231
- return projector_controlled_phase_old(*args, **kwargs)
232
- return projector_controlled_phase_new(*args, **kwargs)
233
-
234
-
235
- @qfunc
236
- def qsvt_inversion_old(
237
- phase_seq: CArray[CReal],
238
- block_encoding_cnot: QCallable[QArray[QBit], QBit],
239
- u: QCallable[QArray[QBit]],
240
- qvar: QArray[QBit],
241
- aux: QBit,
242
- ) -> None:
243
- """
244
- [Qmod Classiq-library function]
245
-
246
- Implements matrix inversion on a given block-encoding of a square matrix, using the QSVT framework. Applies a polynomial approximation
247
- of the inverse of the singular values of the matrix encoded in `u`. The phases for the polynomial should be pre-calculated and passed into the function.
248
-
249
- Args:
250
- phase_seq: A sequence of phase angles of length d+1, corresponding to an odd polynomial approximation of the scaled inverse function.
251
- block_encoding_cnot: 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.
252
- u: A block encoding unitary matrix.
253
- qvar: The quantum variable to which U is applied, which resides in the entire block encoding space.
254
- 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.
255
- """
256
- qsvt_old(
257
- phase_seq,
258
- block_encoding_cnot,
259
- block_encoding_cnot,
260
- lambda x: invert(lambda: u(x)),
261
- qvar,
262
- aux,
263
- )
264
-
265
-
266
- def qsvt_inversion(*args, **kwargs): # type: ignore[no-untyped-def]
267
- """
268
- [Qmod Classiq-library function]
269
-
270
- Implements matrix inversion on a given block-encoding of a square matrix, using the QSVT framework. Applies a polynomial approximation
271
- of the inverse of the singular values of the matrix encoded in `u`. The phases for the polynomial should be pre-calculated and passed into the function.
272
-
273
- Args:
274
- phase_seq: A sequence of phase angles of length d+1, corresponding to an odd polynomial approximation of the scaled inverse function.
275
- block_encoding_cnot: Projector-controlled-not unitary that locates the encoded matrix columns within U. Accepts a quantum variable that should be set to |1> when the state is in the block.
276
- u: A block encoding unitary matrix.
277
- 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.
278
- """
279
- if len(args) + len(kwargs) == 5:
280
- warnings.warn(
281
- "The 'qsvt_inversion' function signature has changed and the old version will be deprecated"
282
- " starting on 2025-12-13 at the earliest",
283
- ClassiqDeprecationWarning,
284
- stacklevel=2,
285
- )
286
- return qsvt_inversion_old(*args, **kwargs)
287
- return qsvt_inversion_new(*args, **kwargs)
288
-
289
-
290
- @qfunc
291
- def projector_controlled_double_phase_old(
292
- phase_even: CReal,
293
- phase_odd: CReal,
294
- proj_cnot: QCallable[QArray[QBit], QBit],
295
- qvar: QArray[QBit],
296
- aux: QBit,
297
- lcu: QBit,
298
- ) -> None:
299
- """
300
- [Qmod Classiq-library function]
301
-
302
- Assigns 2 phases to the entire subspace determined by the given projector, each one is controlled differentely on a given `lcu` qvar.
303
- Used in the context of the `qsvt_lcu` function. Corresponds to the operation:
304
-
305
- $$
306
- \\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)
307
- $$
308
-
309
- Args:
310
- phase_even: Rotation phase, corresponds to 'lcu'=0.
311
- phase_odd: Rotation phase, corresponds to 'lcu'=1.
312
- proj_cnot: Projector-controlled-not unitary that sets an auxilliary qubit to |1> when the state is in the projection.
313
- qvar: The quantum variable to which the rotation applies, which resides in the entire block encoding space.
314
- 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.
315
- lcu: The quantum variable used for controlling the phase assignment.
316
- """
317
- within_apply(
318
- lambda: proj_cnot(qvar, aux),
319
- lambda: control(lcu, lambda: RZ(phase_odd, aux), lambda: RZ(phase_even, aux)),
320
- )
321
-
322
-
323
- def projector_controlled_double_phase(*args, **kwargs): # type: ignore[no-untyped-def]
324
- """
325
- [Qmod Classiq-library function]
326
-
327
- Assigns 2 phases to the entire subspace determined by the given projector, each one is controlled differentely on a given `lcu` qvar.
328
- Used in the context of the `qsvt_lcu` function. Corresponds to the operation:
329
-
330
- $$
331
- \\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)
332
- $$
333
-
334
- Args:
335
- phase_even: Rotation phase, corresponds to 'lcu'=0.
336
- phase_odd: Rotation phase, corresponds to 'lcu'=1.
337
- proj_cnot: Projector-controlled-not unitary that sets an auxilliary qubit to |1> when the state is in the projection.
338
- 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.
339
- lcu: The quantum variable used for controlling the phase assignment.
340
- """
341
- if len(args) + len(kwargs) == 6:
342
- return projector_controlled_double_phase_old(*args, **kwargs)
343
- return projector_controlled_double_phase_new(*args, **kwargs)
344
-
345
-
346
- @qfunc
347
- def qsvt_lcu_step_old(
348
- phases_even: CArray[CReal],
349
- phases_odd: CArray[CReal],
350
- proj_cnot_1: QCallable[QArray[QBit], QBit],
351
- proj_cnot_2: QCallable[QArray[QBit], QBit],
352
- u: QCallable[QArray[QBit]],
353
- qvar: QArray[QBit],
354
- aux: QBit,
355
- lcu: QBit,
356
- ) -> None:
357
- """
358
- [Qmod Classiq-library function]
359
-
360
- 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:
361
-
362
- $$
363
- (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
364
- $$
365
-
366
- Args:
367
- phases_even: 2 rotation phases for the even polynomial
368
- phases_odd: 2 rotation phases for the odd polynomial
369
- 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.
370
- 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.
371
- u: A block encoding unitary matrix.
372
- qvar: The quantum variable to which U is applied, which resides in the entire block encoding space.
373
- 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.
374
- lcu: A qubit used for the combination of 2 polynomials within a single qsvt application
375
- """
376
- u(qvar)
377
- projector_controlled_double_phase_old(
378
- phases_even[0], phases_odd[0], proj_cnot_2, qvar, aux, lcu
379
- )
380
- invert(lambda: u(qvar))
381
- projector_controlled_double_phase_old(
382
- phases_even[1], phases_odd[1], proj_cnot_1, qvar, aux, lcu
383
- )
384
-
385
-
386
- def qsvt_lcu_step(*args, **kwargs): # type: ignore[no-untyped-def]
387
- """
388
- [Qmod Classiq-library function]
389
-
390
- 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:
391
-
392
- $$
393
- (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
394
- $$
395
-
396
- Args:
397
- phases_even: 2 rotation phases for the even polynomial
398
- phases_odd: 2 rotation phases for the odd polynomial
399
- proj_cnot_1: Projector-controlled-not unitary that locates the encoded matrix columns within U. Accepts a qubit that should be set to |1> when the state is in the block.
400
- proj_cnot_2: Projector-controlled-not unitary that locates the encoded matrix rows within U. Accepts a qubit that should be set to |1> when the state is in the block.
401
- u: A block encoding unitary matrix.
402
- 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.
403
- lcu: A qubit used for the combination of 2 polynomials within a single qsvt application
404
- """
405
- if len(args) + len(kwargs) == 8:
406
- return qsvt_lcu_step_old(*args, **kwargs)
407
- return qsvt_lcu_step_new(*args, **kwargs)
408
-
409
-
410
- @qfunc
411
- def qsvt_lcu_old(
412
- phase_seq_even: CArray[CReal],
413
- phase_seq_odd: CArray[CReal],
414
- proj_cnot_1: QCallable[QArray[QBit], QBit],
415
- proj_cnot_2: QCallable[QArray[QBit], QBit],
416
- u: QCallable[QArray[QBit]],
417
- qvar: QArray[QBit],
418
- aux: QBit,
419
- lcu: QBit,
420
- ) -> None:
421
- """
422
- [Qmod Classiq-library function]
423
-
424
- Implements the Quantum Singular Value Transformation (QSVT) for a linear combination of odd and even polynomials, so that
425
- it is possible to encode a polynomial of indefinite parity, such as approximation to exp(i*A) or exp(A). Should work
426
- for Hermitian block encodings.
427
-
428
- The function is equivalent to applying the `qsvt` function for odd and even polynomials with a LCU function, but
429
- is more efficient as the two polynomials share the same applications of the given unitary.
430
-
431
- The function is intended to be called within a context of LCU, where it is called as the SELECT operator, and wrapped
432
- with initialization of the `lcu` qubit to get the desired combination coefficients.
433
- The even polynomial corresponds to the case where the $lcu=|0\\rangle$, while the odd to $lcu=|1\\rangle$.
434
-
435
- Note: the two polynomials should have the same degree up to a difference of 1.
436
-
437
- Args:
438
- phase_seq_odd: A sequence of phase angles of length d+(d%2) for the odd polynomial.
439
- phase_seq_even: A sequence of phase angles of length d+(d+1)%2 for the even polynomial.
440
- 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.
441
- 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.
442
- u: A block encoding unitary matrix.
443
- qvar: The quantum variable to which U is applied, which resides in the entire block encoding space.
444
- 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.
445
- lcu: A qubit used for the combination of 2 polynomials within a single qsvt application
446
- """
447
- H(aux)
448
- projector_controlled_double_phase_old(
449
- phase_seq_even[0], phase_seq_odd[0], proj_cnot_1, qvar, aux, lcu
450
- )
451
- repeat(
452
- count=floor((qmin(phase_seq_odd.len - 1, phase_seq_even.len - 1)) / 2),
453
- iteration=lambda index: qsvt_lcu_step_old(
454
- phase_seq_even[2 * index + 1 : 2 * index + 3],
455
- phase_seq_odd[2 * index + 1 : 2 * index + 3],
456
- proj_cnot_1,
457
- proj_cnot_2,
458
- u,
459
- qvar,
460
- aux,
461
- lcu,
462
- ),
463
- )
464
- if_(
465
- condition=phase_seq_odd.len > phase_seq_even.len,
466
- then=lambda: control(
467
- lcu,
468
- lambda: [
469
- u(qvar),
470
- projector_controlled_phase_old(
471
- phase_seq_odd[phase_seq_odd.len - 1], proj_cnot_2, qvar, aux
472
- ),
473
- ],
474
- ),
475
- )
476
- if_(
477
- condition=phase_seq_odd.len < phase_seq_even.len,
478
- then=lambda: (
479
- u(qvar),
480
- projector_controlled_double_phase_old(
481
- phase_seq_even[phase_seq_even.len - 2],
482
- phase_seq_odd[phase_seq_odd.len - 1],
483
- proj_cnot_2,
484
- qvar,
485
- aux,
486
- lcu,
487
- ),
488
- control(
489
- lcu == 0,
490
- lambda: [
491
- invert(lambda: u(qvar)),
492
- projector_controlled_phase_old(
493
- phase_seq_even[phase_seq_even.len - 1], proj_cnot_1, qvar, aux
494
- ),
495
- ],
496
- ),
497
- ),
498
- )
499
- H(aux)
500
-
501
-
502
- def qsvt_lcu(*args, **kwargs): # type: ignore[no-untyped-def]
503
- """
504
- [Qmod Classiq-library function]
505
-
506
- Implements the Quantum Singular Value Transformation (QSVT) for a linear combination of odd and even polynomials, so that
507
- it is possible to encode a polynomial of indefinite parity, such as approximation to exp(i*A) or exp(A). Should work
508
- for Hermitian block encodings.
509
-
510
- The function is equivalent to applying the `qsvt` function for odd and even polynomials with a LCU function, but
511
- is more efficient as the two polynomials share the same applications of the given unitary.
512
-
513
- The function is intended to be called within a context of LCU, where it is called as the SELECT operator, and wrapped
514
- with initialization of the `lcu` qubit to get the desired combination coefficients.
515
- The even polynomial corresponds to the case where the $lcu=|0\\rangle$, while the odd to $lcu=|1\\rangle$.
516
-
517
- Note: the two polynomials should have the same degree up to a difference of 1.
518
-
519
- Args:
520
- phase_seq_odd: A sequence of phase angles of length d+(d%2) for the odd polynomial.
521
- phase_seq_even: A sequence of phase angles of length d+(d+1)%2 for the even polynomial.
522
- proj_cnot_1: Projector-controlled-not unitary that locates the encoded matrix columns within U. Accepts a qubit that should be set to |1> when the state is in the block.
523
- proj_cnot_2: Projector-controlled-not unitary that locates the encoded matrix rows within U. Accepts a qubit that should be set to |1> when the state is in the block.
524
- u: A block encoding unitary matrix.
525
- 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.
526
- lcu: A qubit used for the combination of 2 polynomials within a single qsvt application
527
- """
528
- if len(args) + len(kwargs) == 8:
529
- warnings.warn(
530
- "The 'qsvt_lcu' function signature has changed and the old version will be deprecated"
531
- " starting on 2025-12-13 at the earliest",
532
- ClassiqDeprecationWarning,
533
- stacklevel=2,
534
- )
535
- return qsvt_lcu_old(*args, **kwargs)
536
- return qsvt_lcu_new(*args, **kwargs)