classiq 0.93.0__py3-none-any.whl → 0.99.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 (315) hide show
  1. classiq/__init__.py +11 -19
  2. classiq/_analyzer_extras/_ipywidgets_async_extension.py +7 -7
  3. classiq/_analyzer_extras/interactive_hardware.py +19 -12
  4. classiq/_internals/api_wrapper.py +31 -142
  5. classiq/_internals/async_utils.py +4 -7
  6. classiq/_internals/authentication/auth0.py +41 -15
  7. classiq/_internals/authentication/authorization_code.py +9 -0
  8. classiq/_internals/authentication/authorization_flow.py +41 -0
  9. classiq/_internals/authentication/device.py +33 -52
  10. classiq/_internals/authentication/hybrid_flow.py +19 -0
  11. classiq/_internals/authentication/password_manager.py +13 -13
  12. classiq/_internals/authentication/token_manager.py +9 -9
  13. classiq/_internals/client.py +17 -44
  14. classiq/_internals/config.py +19 -5
  15. classiq/_internals/help.py +1 -2
  16. classiq/_internals/host_checker.py +3 -3
  17. classiq/_internals/jobs.py +14 -14
  18. classiq/_internals/type_validation.py +3 -3
  19. classiq/analyzer/analyzer.py +18 -18
  20. classiq/analyzer/rb.py +17 -8
  21. classiq/analyzer/show_interactive_hack.py +1 -1
  22. classiq/applications/__init__.py +2 -2
  23. classiq/applications/chemistry/__init__.py +0 -30
  24. classiq/applications/chemistry/op_utils.py +4 -4
  25. classiq/applications/chemistry/problems.py +3 -3
  26. classiq/applications/chemistry/ucc.py +1 -2
  27. classiq/applications/chemistry/z2_symmetries.py +4 -4
  28. classiq/applications/combinatorial_helpers/allowed_constraints.py +1 -3
  29. classiq/applications/combinatorial_helpers/arithmetic/arithmetic_expression.py +2 -1
  30. classiq/applications/combinatorial_helpers/combinatorial_problem_utils.py +2 -2
  31. classiq/applications/combinatorial_helpers/encoding_mapping.py +2 -3
  32. classiq/applications/combinatorial_helpers/encoding_utils.py +2 -2
  33. classiq/applications/combinatorial_helpers/optimization_model.py +3 -4
  34. classiq/applications/combinatorial_helpers/pauli_helpers/pauli_sparsing.py +2 -2
  35. classiq/applications/combinatorial_helpers/pyomo_utils.py +8 -8
  36. classiq/applications/combinatorial_helpers/sympy_utils.py +1 -3
  37. classiq/applications/combinatorial_helpers/transformations/encoding.py +3 -3
  38. classiq/applications/combinatorial_helpers/transformations/fixed_variables.py +1 -2
  39. classiq/applications/combinatorial_optimization/combinatorial_optimization_config.py +2 -3
  40. classiq/applications/combinatorial_optimization/combinatorial_optimization_model_constructor.py +4 -6
  41. classiq/applications/combinatorial_optimization/combinatorial_problem.py +15 -10
  42. classiq/applications/hamiltonian/pauli_decomposition.py +6 -4
  43. classiq/applications/iqae/iqae.py +14 -11
  44. classiq/applications/qnn/datasets/dataset_base_classes.py +6 -6
  45. classiq/applications/qnn/datasets/dataset_parity.py +6 -6
  46. classiq/applications/qnn/gradients/simple_quantum_gradient.py +1 -1
  47. classiq/applications/qnn/qlayer.py +9 -8
  48. classiq/applications/qnn/torch_utils.py +5 -6
  49. classiq/applications/qnn/types.py +2 -1
  50. classiq/applications/qsp/__init__.py +20 -2
  51. classiq/applications/qsp/qsp.py +238 -10
  52. classiq/applications/qsvm/qsvm_data_generation.py +1 -2
  53. classiq/evaluators/classical_expression.py +0 -4
  54. classiq/evaluators/parameter_types.py +10 -8
  55. classiq/evaluators/qmod_annotated_expression.py +31 -26
  56. classiq/evaluators/qmod_expression_visitors/qmod_expression_evaluator.py +14 -14
  57. classiq/evaluators/qmod_expression_visitors/qmod_expression_simplifier.py +2 -1
  58. classiq/evaluators/qmod_expression_visitors/sympy_wrappers.py +8 -8
  59. classiq/evaluators/qmod_node_evaluators/binary_op_evaluation.py +4 -4
  60. classiq/evaluators/qmod_node_evaluators/classical_function_evaluation.py +14 -4
  61. classiq/evaluators/qmod_node_evaluators/list_evaluation.py +2 -2
  62. classiq/evaluators/qmod_node_evaluators/numeric_attrs_utils.py +3 -3
  63. classiq/evaluators/qmod_node_evaluators/subscript_evaluation.py +9 -9
  64. classiq/evaluators/qmod_node_evaluators/utils.py +6 -6
  65. classiq/evaluators/qmod_type_inference/classical_type_inference.py +9 -10
  66. classiq/evaluators/qmod_type_inference/quantum_type_inference.py +5 -5
  67. classiq/execution/__init__.py +0 -3
  68. classiq/execution/execution_session.py +28 -21
  69. classiq/execution/jobs.py +26 -26
  70. classiq/execution/qnn.py +1 -2
  71. classiq/execution/user_budgets.py +71 -37
  72. classiq/executor.py +1 -3
  73. classiq/interface/_version.py +1 -1
  74. classiq/interface/analyzer/analysis_params.py +4 -4
  75. classiq/interface/analyzer/cytoscape_graph.py +3 -3
  76. classiq/interface/analyzer/result.py +4 -4
  77. classiq/interface/ast_node.py +3 -3
  78. classiq/interface/backend/backend_preferences.py +26 -50
  79. classiq/interface/backend/ionq/ionq_quantum_program.py +5 -5
  80. classiq/interface/backend/provider_config/__init__.py +0 -0
  81. classiq/interface/backend/provider_config/provider_config.py +8 -0
  82. classiq/interface/backend/provider_config/providers/__init__.py +0 -0
  83. classiq/interface/backend/provider_config/providers/alice_bob.py +47 -0
  84. classiq/interface/backend/provider_config/providers/aqt.py +16 -0
  85. classiq/interface/backend/provider_config/providers/azure.py +37 -0
  86. classiq/interface/backend/provider_config/providers/braket.py +39 -0
  87. classiq/interface/backend/provider_config/providers/ibm.py +26 -0
  88. classiq/interface/backend/provider_config/providers/ionq.py +22 -0
  89. classiq/interface/backend/quantum_backend_providers.py +20 -2
  90. classiq/interface/chemistry/ansatz_library.py +3 -5
  91. classiq/interface/chemistry/operator.py +3 -3
  92. classiq/interface/combinatorial_optimization/examples/knapsack.py +2 -4
  93. classiq/interface/combinatorial_optimization/examples/tsp_digraph.py +1 -2
  94. classiq/interface/compression_utils.py +2 -3
  95. classiq/interface/debug_info/debug_info.py +8 -7
  96. classiq/interface/exceptions.py +6 -7
  97. classiq/interface/execution/primitives.py +6 -6
  98. classiq/interface/executor/estimate_cost.py +1 -1
  99. classiq/interface/executor/execution_preferences.py +3 -5
  100. classiq/interface/executor/execution_request.py +10 -10
  101. classiq/interface/executor/execution_result.py +1 -2
  102. classiq/interface/executor/quantum_code.py +8 -8
  103. classiq/interface/executor/result.py +28 -18
  104. classiq/interface/executor/user_budget.py +25 -17
  105. classiq/interface/executor/vqe_result.py +5 -6
  106. classiq/interface/generator/ansatz_library.py +6 -8
  107. classiq/interface/generator/application_apis/__init__.py +0 -3
  108. classiq/interface/generator/arith/arithmetic.py +2 -2
  109. classiq/interface/generator/arith/arithmetic_arg_type_validator.py +2 -3
  110. classiq/interface/generator/arith/arithmetic_expression_abc.py +4 -5
  111. classiq/interface/generator/arith/arithmetic_expression_parser.py +11 -4
  112. classiq/interface/generator/arith/arithmetic_expression_validator.py +12 -15
  113. classiq/interface/generator/arith/arithmetic_operations.py +4 -6
  114. classiq/interface/generator/arith/arithmetic_param_getters.py +70 -107
  115. classiq/interface/generator/arith/arithmetic_result_builder.py +4 -4
  116. classiq/interface/generator/arith/ast_node_rewrite.py +8 -4
  117. classiq/interface/generator/arith/binary_ops.py +15 -40
  118. classiq/interface/generator/arith/logical_ops.py +2 -3
  119. classiq/interface/generator/arith/number_utils.py +2 -2
  120. classiq/interface/generator/arith/register_user_input.py +3 -3
  121. classiq/interface/generator/arith/unary_ops.py +2 -2
  122. classiq/interface/generator/circuit_code/circuit_code.py +8 -10
  123. classiq/interface/generator/circuit_code/types_and_constants.py +1 -1
  124. classiq/interface/generator/complex_type.py +2 -2
  125. classiq/interface/generator/copy.py +1 -3
  126. classiq/interface/generator/expressions/atomic_expression_functions.py +0 -5
  127. classiq/interface/generator/expressions/evaluated_expression.py +2 -3
  128. classiq/interface/generator/expressions/expression.py +2 -2
  129. classiq/interface/generator/expressions/proxies/classical/classical_array_proxy.py +4 -7
  130. classiq/interface/generator/function_param_list.py +0 -40
  131. classiq/interface/generator/function_params.py +5 -6
  132. classiq/interface/generator/functions/classical_function_declaration.py +2 -2
  133. classiq/interface/generator/functions/classical_type.py +3 -3
  134. classiq/interface/generator/functions/type_modifier.py +0 -15
  135. classiq/interface/generator/functions/type_name.py +2 -2
  136. classiq/interface/generator/generated_circuit_data.py +14 -18
  137. classiq/interface/generator/hamiltonian_evolution/exponentiation.py +2 -4
  138. classiq/interface/generator/hardware/hardware_data.py +8 -8
  139. classiq/interface/generator/hardware_efficient_ansatz.py +9 -9
  140. classiq/interface/generator/mcu.py +3 -3
  141. classiq/interface/generator/mcx.py +3 -3
  142. classiq/interface/generator/model/constraints.py +34 -5
  143. classiq/interface/generator/model/preferences/preferences.py +15 -21
  144. classiq/interface/generator/model/quantum_register.py +7 -10
  145. classiq/interface/generator/noise_properties.py +3 -7
  146. classiq/interface/generator/parameters.py +1 -1
  147. classiq/interface/generator/partitioned_register.py +1 -2
  148. classiq/interface/generator/preferences/qasm_to_qmod_params.py +11 -0
  149. classiq/interface/generator/quantum_function_call.py +9 -12
  150. classiq/interface/generator/quantum_program.py +10 -23
  151. classiq/interface/generator/range_types.py +3 -3
  152. classiq/interface/generator/slice_parsing_utils.py +4 -5
  153. classiq/interface/generator/standard_gates/standard_gates.py +2 -4
  154. classiq/interface/generator/synthesis_execution_parameter.py +1 -3
  155. classiq/interface/generator/synthesis_metadata/synthesis_duration.py +9 -0
  156. classiq/interface/generator/synthesis_metadata/synthesis_execution_data.py +2 -3
  157. classiq/interface/generator/transpiler_basis_gates.py +12 -4
  158. classiq/interface/generator/types/builtin_enum_declarations.py +0 -145
  159. classiq/interface/generator/types/compilation_metadata.py +12 -1
  160. classiq/interface/generator/types/enum_declaration.py +2 -1
  161. classiq/interface/generator/validations/flow_graph.py +3 -3
  162. classiq/interface/generator/visitor.py +10 -12
  163. classiq/interface/hardware.py +2 -3
  164. classiq/interface/helpers/classproperty.py +2 -2
  165. classiq/interface/helpers/custom_encoders.py +2 -1
  166. classiq/interface/helpers/custom_pydantic_types.py +1 -1
  167. classiq/interface/helpers/text_utils.py +1 -4
  168. classiq/interface/ide/visual_model.py +6 -5
  169. classiq/interface/interface_version.py +1 -1
  170. classiq/interface/jobs.py +3 -3
  171. classiq/interface/model/allocate.py +4 -4
  172. classiq/interface/model/block.py +6 -2
  173. classiq/interface/model/bounds.py +3 -3
  174. classiq/interface/model/classical_if.py +4 -0
  175. classiq/interface/model/control.py +8 -1
  176. classiq/interface/model/inplace_binary_operation.py +2 -2
  177. classiq/interface/model/invert.py +4 -0
  178. classiq/interface/model/model.py +4 -4
  179. classiq/interface/model/model_visitor.py +40 -1
  180. classiq/interface/model/parameter.py +1 -3
  181. classiq/interface/model/port_declaration.py +1 -1
  182. classiq/interface/model/power.py +4 -0
  183. classiq/interface/model/quantum_expressions/quantum_expression.py +1 -2
  184. classiq/interface/model/quantum_function_call.py +3 -6
  185. classiq/interface/model/quantum_function_declaration.py +1 -0
  186. classiq/interface/model/quantum_lambda_function.py +4 -4
  187. classiq/interface/model/quantum_statement.py +11 -4
  188. classiq/interface/model/quantum_type.py +14 -14
  189. classiq/interface/model/repeat.py +4 -0
  190. classiq/interface/model/skip_control.py +4 -0
  191. classiq/interface/model/validation_handle.py +2 -3
  192. classiq/interface/model/variable_declaration_statement.py +2 -2
  193. classiq/interface/model/within_apply_operation.py +4 -0
  194. classiq/interface/pretty_print/expression_to_qmod.py +3 -4
  195. classiq/interface/server/routes.py +0 -16
  196. classiq/interface/source_reference.py +3 -4
  197. classiq/model_expansions/arithmetic.py +11 -7
  198. classiq/model_expansions/arithmetic_compute_result_attrs.py +30 -27
  199. classiq/model_expansions/capturing/captured_vars.py +3 -3
  200. classiq/model_expansions/capturing/mangling_utils.py +1 -2
  201. classiq/model_expansions/closure.py +12 -11
  202. classiq/model_expansions/function_builder.py +14 -6
  203. classiq/model_expansions/generative_functions.py +7 -12
  204. classiq/model_expansions/interpreters/base_interpreter.py +3 -7
  205. classiq/model_expansions/interpreters/frontend_generative_interpreter.py +2 -1
  206. classiq/model_expansions/interpreters/generative_interpreter.py +5 -3
  207. classiq/model_expansions/quantum_operations/allocate.py +4 -4
  208. classiq/model_expansions/quantum_operations/assignment_result_processor.py +2 -4
  209. classiq/model_expansions/quantum_operations/call_emitter.py +31 -37
  210. classiq/model_expansions/quantum_operations/declarative_call_emitter.py +2 -2
  211. classiq/model_expansions/quantum_operations/emitter.py +3 -5
  212. classiq/model_expansions/quantum_operations/expression_evaluator.py +3 -3
  213. classiq/model_expansions/quantum_operations/skip_control_verifier.py +1 -2
  214. classiq/model_expansions/quantum_operations/variable_decleration.py +2 -2
  215. classiq/model_expansions/scope.py +7 -7
  216. classiq/model_expansions/scope_initialization.py +4 -0
  217. classiq/model_expansions/visitors/symbolic_param_inference.py +6 -6
  218. classiq/model_expansions/visitors/uncomputation_signature_inference.py +328 -0
  219. classiq/model_expansions/visitors/variable_references.py +15 -14
  220. classiq/open_library/functions/__init__.py +28 -11
  221. classiq/open_library/functions/amplitude_loading.py +81 -0
  222. classiq/open_library/functions/discrete_sine_cosine_transform.py +5 -5
  223. classiq/open_library/functions/grover.py +8 -10
  224. classiq/open_library/functions/lcu.py +47 -18
  225. classiq/open_library/functions/modular_exponentiation.py +93 -8
  226. classiq/open_library/functions/qsvt.py +66 -79
  227. classiq/open_library/functions/qsvt_temp.py +536 -0
  228. classiq/open_library/functions/state_preparation.py +130 -27
  229. classiq/qmod/__init__.py +6 -4
  230. classiq/qmod/builtins/classical_execution_primitives.py +4 -23
  231. classiq/qmod/builtins/classical_functions.py +1 -42
  232. classiq/qmod/builtins/enums.py +15 -153
  233. classiq/qmod/builtins/functions/__init__.py +9 -18
  234. classiq/qmod/builtins/functions/allocation.py +25 -4
  235. classiq/qmod/builtins/functions/arithmetic.py +22 -27
  236. classiq/qmod/builtins/functions/exponentiation.py +51 -2
  237. classiq/qmod/builtins/functions/mcx_func.py +7 -0
  238. classiq/qmod/builtins/functions/standard_gates.py +46 -27
  239. classiq/qmod/builtins/operations.py +165 -79
  240. classiq/qmod/builtins/structs.py +24 -91
  241. classiq/qmod/cfunc.py +3 -2
  242. classiq/qmod/classical_function.py +2 -1
  243. classiq/qmod/cparam.py +2 -8
  244. classiq/qmod/create_model_function.py +7 -7
  245. classiq/qmod/declaration_inferrer.py +33 -30
  246. classiq/qmod/expression_query.py +7 -4
  247. classiq/qmod/model_state_container.py +2 -2
  248. classiq/qmod/native/pretty_printer.py +25 -14
  249. classiq/qmod/pretty_print/expression_to_python.py +5 -3
  250. classiq/qmod/pretty_print/pretty_printer.py +39 -17
  251. classiq/qmod/python_classical_type.py +40 -13
  252. classiq/qmod/qfunc.py +124 -19
  253. classiq/qmod/qmod_constant.py +2 -2
  254. classiq/qmod/qmod_parameter.py +5 -2
  255. classiq/qmod/qmod_variable.py +47 -46
  256. classiq/qmod/quantum_callable.py +18 -13
  257. classiq/qmod/quantum_expandable.py +31 -26
  258. classiq/qmod/quantum_function.py +84 -36
  259. classiq/qmod/semantics/annotation/call_annotation.py +5 -5
  260. classiq/qmod/semantics/error_manager.py +12 -14
  261. classiq/qmod/semantics/lambdas.py +1 -2
  262. classiq/qmod/semantics/validation/types_validation.py +1 -2
  263. classiq/qmod/symbolic.py +2 -4
  264. classiq/qmod/utilities.py +13 -20
  265. classiq/qmod/write_qmod.py +3 -4
  266. classiq/quantum_program.py +1 -3
  267. classiq/synthesis.py +11 -7
  268. {classiq-0.93.0.dist-info → classiq-0.99.0.dist-info}/METADATA +2 -3
  269. {classiq-0.93.0.dist-info → classiq-0.99.0.dist-info}/RECORD +271 -299
  270. {classiq-0.93.0.dist-info → classiq-0.99.0.dist-info}/WHEEL +1 -1
  271. classiq/applications/chemistry/ansatz_parameters.py +0 -29
  272. classiq/applications/chemistry/chemistry_execution_parameters.py +0 -16
  273. classiq/applications/chemistry/chemistry_model_constructor.py +0 -532
  274. classiq/applications/chemistry/ground_state_problem.py +0 -42
  275. classiq/applications/qsvm/__init__.py +0 -8
  276. classiq/applications/qsvm/qsvm.py +0 -11
  277. classiq/evaluators/qmod_expression_visitors/qmod_expression_bwc.py +0 -129
  278. classiq/execution/iqcc.py +0 -128
  279. classiq/interface/applications/qsvm.py +0 -117
  280. classiq/interface/chemistry/elements.py +0 -120
  281. classiq/interface/chemistry/fermionic_operator.py +0 -208
  282. classiq/interface/chemistry/ground_state_problem.py +0 -132
  283. classiq/interface/chemistry/ground_state_result.py +0 -8
  284. classiq/interface/chemistry/molecule.py +0 -71
  285. classiq/interface/execution/iqcc.py +0 -44
  286. classiq/interface/generator/application_apis/chemistry_declarations.py +0 -69
  287. classiq/interface/generator/application_apis/entangler_declarations.py +0 -29
  288. classiq/interface/generator/application_apis/qsvm_declarations.py +0 -6
  289. classiq/interface/generator/chemistry_function_params.py +0 -50
  290. classiq/interface/generator/entangler_params.py +0 -72
  291. classiq/interface/generator/entanglers.py +0 -14
  292. classiq/interface/generator/hamiltonian_evolution/qdrift.py +0 -27
  293. classiq/interface/generator/hartree_fock.py +0 -26
  294. classiq/interface/generator/hva.py +0 -22
  295. classiq/interface/generator/linear_pauli_rotations.py +0 -92
  296. classiq/interface/generator/qft.py +0 -37
  297. classiq/interface/generator/qsvm.py +0 -96
  298. classiq/interface/generator/state_preparation/__init__.py +0 -14
  299. classiq/interface/generator/state_preparation/bell_state_preparation.py +0 -27
  300. classiq/interface/generator/state_preparation/computational_basis_state_preparation.py +0 -28
  301. classiq/interface/generator/state_preparation/distributions.py +0 -53
  302. classiq/interface/generator/state_preparation/exponential_state_preparation.py +0 -14
  303. classiq/interface/generator/state_preparation/ghz_state_preparation.py +0 -14
  304. classiq/interface/generator/state_preparation/metrics.py +0 -41
  305. classiq/interface/generator/state_preparation/state_preparation.py +0 -113
  306. classiq/interface/generator/state_preparation/state_preparation_abc.py +0 -24
  307. classiq/interface/generator/state_preparation/uniform_distibution_state_preparation.py +0 -13
  308. classiq/interface/generator/state_preparation/w_state_preparation.py +0 -13
  309. classiq/interface/generator/ucc.py +0 -74
  310. classiq/interface/helpers/backward_compatibility.py +0 -9
  311. classiq/model_expansions/transformers/type_modifier_inference.py +0 -392
  312. classiq/open_library/functions/lookup_table.py +0 -58
  313. classiq/qmod/builtins/functions/chemistry.py +0 -123
  314. classiq/qmod/builtins/functions/qsvm.py +0 -24
  315. {classiq-0.93.0.dist-info → classiq-0.99.0.dist-info}/licenses/LICENSE.txt +0 -0
@@ -9,6 +9,7 @@ from classiq.open_library.functions.utility_functions import switch
9
9
  from classiq.qmod.builtins.functions import IDENTITY, X, Y, Z, inplace_prepare_state
10
10
  from classiq.qmod.builtins.operations import (
11
11
  control,
12
+ if_,
12
13
  repeat,
13
14
  within_apply,
14
15
  )
@@ -16,7 +17,7 @@ from classiq.qmod.builtins.structs import IndexedPauli, SparsePauliOp
16
17
  from classiq.qmod.cparam import CArray
17
18
  from classiq.qmod.qfunc import qfunc
18
19
  from classiq.qmod.qmod_variable import QArray, QBit, QNum
19
- from classiq.qmod.quantum_callable import QCallableList
20
+ from classiq.qmod.quantum_callable import QCallable, QCallableList
20
21
 
21
22
 
22
23
  @qfunc
@@ -36,27 +37,23 @@ def apply_pauli_term(pauli_string: CArray[IndexedPauli], x: QArray[QBit]) -> Non
36
37
 
37
38
 
38
39
  @qfunc
39
- def lcu(
40
+ def prepare_select(
40
41
  coefficients: list[float],
41
- unitaries: QCallableList,
42
+ select: QCallable[QNum],
42
43
  block: QNum[Literal["max(ceiling(log(coefficients.len, 2)), 1)"]],
43
44
  ) -> None:
44
45
  """
45
46
  [Qmod Classiq-library function]
46
47
 
47
- Implements a general linear combination of unitaries (LCU) procedure. The algorithm prepares a superposition
48
- over the `unitaries` according to `magnitudes`, and then conditionally applies each unitary controlled by the `block`.
49
-
50
- The operation is of the form:
51
-
52
- $$\\sum_j \\alpha_j U_j$$
53
-
54
- where $U_j$ is a unitary operation applied to `data`.
48
+ Applies the 'Prepare-Select' scheme used for Linear Combination of Unitaries (LCU).
49
+ Compared to the `lcu` function, here the Select operator should be provided directly, allowing to take advantage of some structure for
50
+ the unitaries of the LCU.
51
+ The select operator is defined by: $\\mathrm{SELECT} = \\sum_{j=0}^{m-1} |j\rangle\\!\\langle j|_{block} \\otimes U_j$.
55
52
 
56
53
  Args:
57
54
  coefficients: L1-normalized array of $\\{ \\alpha_j \\}$ of the LCU coefficients.
58
- unitaries: A list of quantum callable functions to be applied conditionally.
59
- block: Quantum variable that holds the superposition index used for conditional application of each unitary.
55
+ select: A quantum callable to be applied between the state preparation and its inverse. Its input is the `block` variable, labeling the index of the unitaries in the LCU.
56
+ block: A Quantum variable that holds the index used as input for the 'select' operator.
60
57
  """
61
58
  coefficients = coefficients + [0] * (
62
59
  2**block.size - len(coefficients) # type:ignore[operator]
@@ -68,16 +65,48 @@ def lcu(
68
65
  within_apply(
69
66
  lambda: inplace_prepare_state(magnitudes, 0, block),
70
67
  lambda: [
71
- repeat(
72
- count=unitaries.len,
73
- iteration=lambda i: control(block == i, lambda: unitaries[i]()),
68
+ select(block),
69
+ if_(
70
+ not np.allclose(np.array(phases) % (2 * np.pi), 0),
71
+ lambda: apply_phase_table(phases, block),
74
72
  ),
75
- # TODO: replace to sparse constant phase
76
- apply_phase_table(phases, block),
77
73
  ],
78
74
  )
79
75
 
80
76
 
77
+ @qfunc
78
+ def lcu(
79
+ coefficients: list[float],
80
+ unitaries: QCallableList,
81
+ block: QNum[Literal["max(ceiling(log(coefficients.len, 2)), 1)"]],
82
+ ) -> None:
83
+ """
84
+ [Qmod Classiq-library function]
85
+
86
+ Implements a general linear combination of unitaries (LCU) procedure. The algorithm prepares a superposition
87
+ over the `unitaries` according to the given `coefficients`, and then conditionally applies each unitary controlled by the `block`.
88
+
89
+ The operation is of the form:
90
+
91
+ $$\\sum_j \\alpha_j U_j$$
92
+
93
+ where $U_j$ is a unitary operation applied to `data`.
94
+
95
+ Args:
96
+ coefficients: L1-normalized array of $\\{ \\alpha_j \\}$ of the LCU coefficients.
97
+ unitaries: A list of quantum callable functions to be applied conditionally.
98
+ block: Quantum variable that holds the superposition index used for conditional application of each unitary.
99
+ """
100
+ prepare_select(
101
+ coefficients,
102
+ lambda _block: repeat(
103
+ count=unitaries.len,
104
+ iteration=lambda i: control(_block == i, lambda: unitaries[i]()),
105
+ ),
106
+ block,
107
+ )
108
+
109
+
81
110
  @qfunc
82
111
  def lcu_pauli(
83
112
  operator: SparsePauliOp,
@@ -8,11 +8,12 @@ from classiq.qmod.builtins.operations import (
8
8
  control,
9
9
  invert,
10
10
  repeat,
11
+ skip_control,
11
12
  within_apply,
12
13
  )
13
14
  from classiq.qmod.cparam import CInt
14
- from classiq.qmod.qfunc import qfunc
15
- from classiq.qmod.qmod_variable import Const, Permutable, QArray, QBit
15
+ from classiq.qmod.qfunc import qfunc, qperm
16
+ from classiq.qmod.qmod_variable import Const, QArray, QBit
16
17
  from classiq.qmod.symbolic import min, mod_inverse
17
18
 
18
19
 
@@ -51,9 +52,9 @@ def qft_space_add_const(value: CInt, phi_b: QArray[QBit]) -> None:
51
52
  )
52
53
 
53
54
 
54
- @qfunc(unchecked=["phi_b"])
55
+ @qperm(disable_perm_check=True)
55
56
  def cc_modular_add(
56
- n: CInt, a: CInt, phi_b: Permutable[QArray[QBit]], c1: Const[QBit], c2: Const[QBit]
57
+ n: CInt, a: CInt, phi_b: QArray[QBit], c1: Const[QBit], c2: Const[QBit]
57
58
  ) -> None:
58
59
  """
59
60
  [Qmod Classiq-library function]
@@ -91,11 +92,11 @@ def cc_modular_add(
91
92
  free(aux)
92
93
 
93
94
 
94
- @qfunc(unchecked=["b"])
95
+ @qperm(disable_perm_check=True)
95
96
  def c_modular_multiply(
96
97
  n: CInt,
97
98
  a: CInt,
98
- b: Permutable[QArray[QBit]],
99
+ b: QArray[QBit],
99
100
  x: Const[QArray[QBit]],
100
101
  ctrl: Const[QBit],
101
102
  ) -> None:
@@ -123,8 +124,8 @@ def c_modular_multiply(
123
124
  )
124
125
 
125
126
 
126
- @qfunc
127
- def multiswap(x: Permutable[QArray[QBit]], y: Permutable[QArray[QBit]]) -> None:
127
+ @qperm
128
+ def multiswap(x: QArray[QBit], y: QArray[QBit]) -> None:
128
129
  """
129
130
  [Qmod Classiq-library function]
130
131
 
@@ -164,6 +165,90 @@ def inplace_c_modular_multiply(n: CInt, a: CInt, x: QArray[QBit], ctrl: QBit) ->
164
165
  free(b)
165
166
 
166
167
 
168
+ @qperm(disable_perm_check=True)
169
+ def modular_add_qft_space(n: CInt, a: CInt, phi_b: QArray[QBit]) -> None:
170
+ """
171
+ [Qmod Classiq-library function]
172
+
173
+ Adds a constant `a` to a quantum number `phi_b` modulo the constant `n`.
174
+ The quantum number `phi_b` is assumed to be in the QFT space.
175
+
176
+ Args:
177
+ n: The modulo number.
178
+ a: The constant to add to the quantum number.
179
+ phi_b: The quantum number to which the constant is added.
180
+
181
+ """
182
+ aux = QBit()
183
+
184
+ allocate(aux)
185
+ qft_space_add_const(a, phi_b),
186
+ skip_control(
187
+ lambda: (
188
+ invert(lambda: qft_space_add_const(n, phi_b)),
189
+ _check_msb(1, phi_b, aux),
190
+ control(aux, lambda: qft_space_add_const(n, phi_b)),
191
+ )
192
+ )
193
+ invert(lambda: qft_space_add_const(a, phi_b))
194
+ skip_control(lambda: _check_msb(0, phi_b, aux))
195
+ qft_space_add_const(a, phi_b)
196
+ free(aux)
197
+
198
+
199
+ @qperm(disable_perm_check=True)
200
+ def modular_multiply(
201
+ n: CInt,
202
+ a: CInt,
203
+ b: QArray[QBit],
204
+ x: Const[QArray[QBit]],
205
+ ) -> None:
206
+ """
207
+ [Qmod Classiq-library function]
208
+
209
+ Performs out-of-place multiplication of a quantum number `x` by a classical number `a` modulo classical number `n`,
210
+ and adds the result to a quantum array `b` (Applies $b += xa \\mod n$).
211
+
212
+ Args:
213
+ n: The modulo number. Should be non-negative.
214
+ a: The classical factor. Should be non-negative.
215
+ b: The quantum number added to the multiplication result. Stores the result of the multiplication.
216
+ x: The quantum factor.
217
+ """
218
+ within_apply(
219
+ lambda: qft(b),
220
+ lambda: repeat(
221
+ count=x.len,
222
+ iteration=lambda index: control(
223
+ x[index], lambda: modular_add_qft_space(n, (a * (2**index)) % n, b)
224
+ ),
225
+ ),
226
+ )
227
+
228
+
229
+ @qfunc
230
+ def inplace_modular_multiply(n: CInt, a: CInt, x: QArray[QBit]) -> None:
231
+ """
232
+ [Qmod Classiq-library function]
233
+
234
+ Performs multiplication of a quantum number `x` by a classical number `a` modulo classical number `n`
235
+ (Applies $x=xa \\mod n$).
236
+
237
+ Args:
238
+ n: The modulo number. Should be non-negative.
239
+ a: The classical factor. Should be non-negative.
240
+ x: The quantum factor.
241
+
242
+ Comment: It is assumed that `a` has an inverse modulo `n`
243
+ """
244
+ b: QArray[QBit] = QArray(length=x.len + 1)
245
+ allocate(b)
246
+ modular_multiply(n, a, b, x)
247
+ multiswap(x, b)
248
+ invert(lambda: modular_multiply(n, mod_inverse(a, n), b, x))
249
+ free(b)
250
+
251
+
167
252
  @qfunc
168
253
  def modular_exp(n: CInt, a: CInt, x: QArray[QBit], power: QArray[QBit]) -> None:
169
254
  """
@@ -1,8 +1,10 @@
1
- from classiq.qmod.builtins.functions.standard_gates import IDENTITY, RZ, H, U, X, Z
1
+ from typing import Literal
2
+
3
+ from classiq.qmod.builtins.functions.standard_gates import RZ, H, U, X, Z
2
4
  from classiq.qmod.builtins.operations import control, if_, invert, repeat, within_apply
3
5
  from classiq.qmod.qfunc import qfunc
4
6
  from classiq.qmod.qmod_parameter import CArray, CInt, CReal
5
- from classiq.qmod.qmod_variable import QArray, QBit
7
+ from classiq.qmod.qmod_variable import QBit
6
8
  from classiq.qmod.quantum_callable import QCallable
7
9
  from classiq.qmod.symbolic import floor, min as qmin
8
10
 
@@ -11,10 +13,9 @@ from classiq.qmod.symbolic import floor, min as qmin
11
13
  def qsvt_step(
12
14
  phase1: CReal,
13
15
  phase2: CReal,
14
- proj_cnot_1: QCallable[QArray[QBit], QBit],
15
- proj_cnot_2: QCallable[QArray[QBit], QBit],
16
- u: QCallable[QArray[QBit]],
17
- qvar: QArray[QBit],
16
+ proj_cnot_1: QCallable[QBit],
17
+ proj_cnot_2: QCallable[QBit],
18
+ u: QCallable,
18
19
  aux: QBit,
19
20
  ) -> None:
20
21
  """
@@ -29,25 +30,23 @@ def qsvt_step(
29
30
  Args:
30
31
  phase1: 1st rotation phase.
31
32
  phase2: 2nd rotation phase.
32
- 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.
33
- 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.
34
- u: A block encoded unitary matrix.
35
- qvar: The quantum variable to which U is applied, which resides in the entire block encoding space.
33
+ 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.
34
+ 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.
35
+ u: A block encoding unitary matrix.
36
36
  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.
37
37
  """
38
- u(qvar)
39
- projector_controlled_phase(phase1, proj_cnot_2, qvar, aux)
40
- invert(lambda: u(qvar))
41
- projector_controlled_phase(phase2, proj_cnot_1, qvar, aux)
38
+ u()
39
+ projector_controlled_phase(phase1, proj_cnot_2, aux)
40
+ invert(lambda: u())
41
+ projector_controlled_phase(phase2, proj_cnot_1, aux)
42
42
 
43
43
 
44
44
  @qfunc
45
45
  def qsvt(
46
46
  phase_seq: CArray[CReal],
47
- proj_cnot_1: QCallable[QArray[QBit], QBit],
48
- proj_cnot_2: QCallable[QArray[QBit], QBit],
49
- u: QCallable[QArray[QBit]],
50
- qvar: QArray[QBit],
47
+ proj_cnot_1: QCallable[QBit],
48
+ proj_cnot_2: QCallable[QBit],
49
+ u: QCallable,
51
50
  aux: QBit,
52
51
  ) -> None:
53
52
  """
@@ -72,15 +71,14 @@ def qsvt(
72
71
 
73
72
  Args:
74
73
  phase_seq: A sequence of phase angles of length d+1.
75
- 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.
76
- 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.
77
- u: A block encoded unitary matrix.
78
- qvar: The quantum variable to which U is applied, which resides in the entire block encoding space.
74
+ 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.
75
+ 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.
76
+ u: A block encoding unitary matrix.
79
77
  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.
80
78
  """
81
79
  H(aux)
82
80
 
83
- projector_controlled_phase(phase_seq[0], proj_cnot_1, qvar, aux)
81
+ projector_controlled_phase(phase_seq[0], proj_cnot_1, aux)
84
82
  repeat(
85
83
  count=floor((phase_seq.len - 1) / 2),
86
84
  iteration=lambda index: qsvt_step(
@@ -89,20 +87,18 @@ def qsvt(
89
87
  proj_cnot_1,
90
88
  proj_cnot_2,
91
89
  u,
92
- qvar,
93
90
  aux,
94
91
  ),
95
92
  )
96
93
 
97
94
  if_(
98
95
  condition=phase_seq.len % 2 == 1,
99
- then=lambda: IDENTITY(qvar),
96
+ then=lambda: None,
100
97
  else_=lambda: (
101
- u(qvar),
98
+ u(),
102
99
  projector_controlled_phase(
103
100
  phase_seq[phase_seq.len - 1],
104
101
  proj_cnot_2,
105
- qvar,
106
102
  aux,
107
103
  ),
108
104
  ),
@@ -114,8 +110,7 @@ def qsvt(
114
110
  @qfunc
115
111
  def projector_controlled_phase(
116
112
  phase: CReal,
117
- proj_cnot: QCallable[QArray[QBit], QBit],
118
- qvar: QArray[QBit],
113
+ proj_cnot: QCallable[QBit],
119
114
  aux: QBit,
120
115
  ) -> None:
121
116
  """
@@ -130,18 +125,16 @@ def projector_controlled_phase(
130
125
  Args:
131
126
  phase: A rotation phase.
132
127
  proj_cnot: Projector-controlled-not unitary that sets an auxilliary qubit to |1> when the state is in the projection.
133
- qvar: The quantum variable to which the rotation applies, which resides in the entire block encoding space.
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.
128
+ aux: A zero auxilliary qubit, used for the projector-controlled-phase rotation.
135
129
  """
136
- within_apply(lambda: proj_cnot(qvar, aux), lambda: RZ(phase, aux))
130
+ within_apply(lambda: proj_cnot(aux), lambda: RZ(phase, aux))
137
131
 
138
132
 
139
133
  @qfunc
140
134
  def qsvt_inversion(
141
135
  phase_seq: CArray[CReal],
142
- block_encoding_cnot: QCallable[QArray[QBit], QBit],
143
- u: QCallable[QArray[QBit]],
144
- qvar: QArray[QBit],
136
+ block_encoding_cnot: QCallable[QBit],
137
+ u: QCallable,
145
138
  aux: QBit,
146
139
  ) -> None:
147
140
  """
@@ -152,17 +145,15 @@ def qsvt_inversion(
152
145
 
153
146
  Args:
154
147
  phase_seq: A sequence of phase angles of length d+1, corresponding to an odd polynomial approximation of the scaled inverse function.
155
- 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.
156
- u: A block encoded unitary matrix.
157
- qvar: The quantum variable to which U is applied, which resides in the entire block encoding space.
148
+ 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.
149
+ u: A block encoding unitary matrix.
158
150
  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.
159
151
  """
160
152
  qsvt(
161
153
  phase_seq,
162
154
  block_encoding_cnot,
163
155
  block_encoding_cnot,
164
- lambda x: invert(lambda: u(x)),
165
- qvar,
156
+ lambda: invert(lambda: u()),
166
157
  aux,
167
158
  )
168
159
 
@@ -171,8 +162,7 @@ def qsvt_inversion(
171
162
  def projector_controlled_double_phase(
172
163
  phase_even: CReal,
173
164
  phase_odd: CReal,
174
- proj_cnot: QCallable[QArray[QBit], QBit],
175
- qvar: QArray[QBit],
165
+ proj_cnot: QCallable[QBit],
176
166
  aux: QBit,
177
167
  lcu: QBit,
178
168
  ) -> None:
@@ -187,15 +177,15 @@ def projector_controlled_double_phase(
187
177
  $$
188
178
 
189
179
  Args:
190
- phase_even: Rotation phase, corresponds to 'lcu'=1.
191
- phase_odd: Rotation phase, corresponds to 'lcu'=0.
180
+ phase_even: Rotation phase, corresponds to 'lcu'=0.
181
+ phase_odd: Rotation phase, corresponds to 'lcu'=1.
192
182
  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
183
  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.
184
+ lcu: The quantum variable used for controlling the phase assignment.
195
185
  """
196
186
  within_apply(
197
- lambda: proj_cnot(qvar, aux),
198
- lambda: control(lcu, lambda: RZ(phase_even, aux), lambda: RZ(phase_odd, aux)),
187
+ lambda: proj_cnot(aux),
188
+ lambda: control(lcu, lambda: RZ(phase_odd, aux), lambda: RZ(phase_even, aux)),
199
189
  )
200
190
 
201
191
 
@@ -203,10 +193,9 @@ def projector_controlled_double_phase(
203
193
  def qsvt_lcu_step(
204
194
  phases_even: CArray[CReal],
205
195
  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],
196
+ proj_cnot_1: QCallable[QBit],
197
+ proj_cnot_2: QCallable[QBit],
198
+ u: QCallable,
210
199
  aux: QBit,
211
200
  lcu: QBit,
212
201
  ) -> None:
@@ -222,20 +211,19 @@ def qsvt_lcu_step(
222
211
  Args:
223
212
  phases_even: 2 rotation phases for the even polynomial
224
213
  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.
214
+ 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.
215
+ 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.
216
+ u: A block encoding unitary matrix.
229
217
  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
218
  lcu: A qubit used for the combination of 2 polynomials within a single qsvt application
231
219
  """
232
- u(qvar)
220
+ u()
233
221
  projector_controlled_double_phase(
234
- phases_even[0], phases_odd[0], proj_cnot_2, qvar, aux, lcu
222
+ phases_even[0], phases_odd[0], proj_cnot_2, aux, lcu
235
223
  )
236
- invert(lambda: u(qvar))
224
+ invert(lambda: u())
237
225
  projector_controlled_double_phase(
238
- phases_even[1], phases_odd[1], proj_cnot_1, qvar, aux, lcu
226
+ phases_even[1], phases_odd[1], proj_cnot_1, aux, lcu
239
227
  )
240
228
 
241
229
 
@@ -243,10 +231,9 @@ def qsvt_lcu_step(
243
231
  def qsvt_lcu(
244
232
  phase_seq_even: CArray[CReal],
245
233
  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],
234
+ proj_cnot_1: QCallable[QBit],
235
+ proj_cnot_2: QCallable[QBit],
236
+ u: QCallable,
250
237
  aux: QBit,
251
238
  lcu: QBit,
252
239
  ) -> None:
@@ -262,23 +249,22 @@ def qsvt_lcu(
262
249
 
263
250
  The function is intended to be called within a context of LCU, where it is called as the SELECT operator, and wrapped
264
251
  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$.
252
+ The even polynomial corresponds to the case where the $lcu=|0\\rangle$, while the odd to $lcu=|1\\rangle$.
266
253
 
267
254
  Note: the two polynomials should have the same degree up to a difference of 1.
268
255
 
269
256
  Args:
270
257
  phase_seq_odd: A sequence of phase angles of length d+(d%2) for the odd polynomial.
271
258
  phase_seq_even: A sequence of phase angles of length d+(d+1)%2 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.
259
+ 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.
260
+ 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.
261
+ u: A block encoding unitary matrix.
276
262
  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
263
  lcu: A qubit used for the combination of 2 polynomials within a single qsvt application
278
264
  """
279
265
  H(aux)
280
266
  projector_controlled_double_phase(
281
- phase_seq_even[0], phase_seq_odd[0], proj_cnot_1, qvar, aux, lcu
267
+ phase_seq_even[0], phase_seq_odd[0], proj_cnot_1, aux, lcu
282
268
  )
283
269
  repeat(
284
270
  count=floor((qmin(phase_seq_odd.len - 1, phase_seq_even.len - 1)) / 2),
@@ -288,7 +274,6 @@ def qsvt_lcu(
288
274
  proj_cnot_1,
289
275
  proj_cnot_2,
290
276
  u,
291
- qvar,
292
277
  aux,
293
278
  lcu,
294
279
  ),
@@ -296,11 +281,11 @@ def qsvt_lcu(
296
281
  if_(
297
282
  condition=phase_seq_odd.len > phase_seq_even.len,
298
283
  then=lambda: control(
299
- lcu == 0,
284
+ lcu,
300
285
  lambda: [
301
- u(qvar),
286
+ u(),
302
287
  projector_controlled_phase(
303
- phase_seq_odd[phase_seq_odd.len - 1], proj_cnot_2, qvar, aux
288
+ phase_seq_odd[phase_seq_odd.len - 1], proj_cnot_2, aux
304
289
  ),
305
290
  ],
306
291
  ),
@@ -308,21 +293,20 @@ def qsvt_lcu(
308
293
  if_(
309
294
  condition=phase_seq_odd.len < phase_seq_even.len,
310
295
  then=lambda: (
311
- u(qvar),
296
+ u(),
312
297
  projector_controlled_double_phase(
313
298
  phase_seq_even[phase_seq_even.len - 2],
314
299
  phase_seq_odd[phase_seq_odd.len - 1],
315
300
  proj_cnot_2,
316
- qvar,
317
301
  aux,
318
302
  lcu,
319
303
  ),
320
304
  control(
321
- lcu,
305
+ lcu == 0,
322
306
  lambda: [
323
- invert(lambda: u(qvar)),
307
+ invert(lambda: u()),
324
308
  projector_controlled_phase(
325
- phase_seq_even[phase_seq_even.len - 1], proj_cnot_1, qvar, aux
309
+ phase_seq_even[phase_seq_even.len - 1], proj_cnot_1, aux
326
310
  ),
327
311
  ],
328
312
  ),
@@ -342,7 +326,10 @@ def _gqsp_r_gate(theta: CReal, phi: CReal, _lambda: CReal, q: QBit) -> None:
342
326
 
343
327
  @qfunc
344
328
  def gqsp(
345
- u: QCallable, aux: QBit, phases: CArray[CArray[CReal], 3], negative_power: CInt # type: ignore[valid-type]
329
+ u: QCallable,
330
+ aux: QBit,
331
+ phases: CArray[CArray[CReal], Literal[3]],
332
+ negative_power: CInt,
346
333
  ) -> None:
347
334
  """
348
335
  Implements Generalized Quantum Signal Processing (GQSP), which realizes a