classiq 0.92.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 (318) 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 +239 -11
  52. classiq/applications/qsvm/qsvm_data_generation.py +1 -2
  53. classiq/evaluators/classical_expression.py +0 -4
  54. classiq/evaluators/parameter_types.py +20 -12
  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 +10 -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 +8 -4
  207. classiq/model_expansions/quantum_operations/allocate.py +4 -4
  208. classiq/model_expansions/quantum_operations/assignment_result_processor.py +8 -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 +61 -29
  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 +19 -14
  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 +173 -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/classical_variable.py +4 -2
  244. classiq/qmod/cparam.py +2 -8
  245. classiq/qmod/create_model_function.py +7 -7
  246. classiq/qmod/declaration_inferrer.py +33 -30
  247. classiq/qmod/expression_query.py +7 -4
  248. classiq/qmod/model_state_container.py +2 -2
  249. classiq/qmod/native/pretty_printer.py +25 -14
  250. classiq/qmod/pretty_print/expression_to_python.py +5 -3
  251. classiq/qmod/pretty_print/pretty_printer.py +39 -17
  252. classiq/qmod/python_classical_type.py +40 -13
  253. classiq/qmod/qfunc.py +124 -19
  254. classiq/qmod/qmod_constant.py +2 -2
  255. classiq/qmod/qmod_parameter.py +5 -2
  256. classiq/qmod/qmod_variable.py +47 -46
  257. classiq/qmod/quantum_callable.py +18 -13
  258. classiq/qmod/quantum_expandable.py +33 -26
  259. classiq/qmod/quantum_function.py +84 -36
  260. classiq/qmod/semantics/annotation/call_annotation.py +5 -5
  261. classiq/qmod/semantics/error_manager.py +12 -14
  262. classiq/qmod/semantics/lambdas.py +1 -2
  263. classiq/qmod/semantics/validation/types_validation.py +1 -2
  264. classiq/qmod/symbolic.py +2 -4
  265. classiq/qmod/symbolic_expr.py +12 -4
  266. classiq/qmod/utilities.py +13 -20
  267. classiq/qmod/write_qmod.py +3 -4
  268. classiq/quantum_program.py +1 -3
  269. classiq/synthesis.py +11 -7
  270. {classiq-0.92.0.dist-info → classiq-0.99.0.dist-info}/METADATA +38 -37
  271. {classiq-0.92.0.dist-info → classiq-0.99.0.dist-info}/RECORD +273 -300
  272. classiq-0.99.0.dist-info/WHEEL +4 -0
  273. classiq-0.99.0.dist-info/licenses/LICENSE.txt +27 -0
  274. classiq/applications/chemistry/ansatz_parameters.py +0 -29
  275. classiq/applications/chemistry/chemistry_execution_parameters.py +0 -16
  276. classiq/applications/chemistry/chemistry_model_constructor.py +0 -532
  277. classiq/applications/chemistry/ground_state_problem.py +0 -42
  278. classiq/applications/qsvm/__init__.py +0 -8
  279. classiq/applications/qsvm/qsvm.py +0 -11
  280. classiq/evaluators/qmod_expression_visitors/qmod_expression_bwc.py +0 -129
  281. classiq/execution/iqcc.py +0 -128
  282. classiq/interface/applications/qsvm.py +0 -117
  283. classiq/interface/chemistry/elements.py +0 -120
  284. classiq/interface/chemistry/fermionic_operator.py +0 -208
  285. classiq/interface/chemistry/ground_state_problem.py +0 -132
  286. classiq/interface/chemistry/ground_state_result.py +0 -8
  287. classiq/interface/chemistry/molecule.py +0 -71
  288. classiq/interface/execution/iqcc.py +0 -44
  289. classiq/interface/generator/application_apis/chemistry_declarations.py +0 -69
  290. classiq/interface/generator/application_apis/entangler_declarations.py +0 -29
  291. classiq/interface/generator/application_apis/qsvm_declarations.py +0 -6
  292. classiq/interface/generator/chemistry_function_params.py +0 -50
  293. classiq/interface/generator/entangler_params.py +0 -72
  294. classiq/interface/generator/entanglers.py +0 -14
  295. classiq/interface/generator/hamiltonian_evolution/qdrift.py +0 -27
  296. classiq/interface/generator/hartree_fock.py +0 -26
  297. classiq/interface/generator/hva.py +0 -22
  298. classiq/interface/generator/linear_pauli_rotations.py +0 -92
  299. classiq/interface/generator/qft.py +0 -37
  300. classiq/interface/generator/qsvm.py +0 -96
  301. classiq/interface/generator/state_preparation/__init__.py +0 -14
  302. classiq/interface/generator/state_preparation/bell_state_preparation.py +0 -27
  303. classiq/interface/generator/state_preparation/computational_basis_state_preparation.py +0 -28
  304. classiq/interface/generator/state_preparation/distributions.py +0 -53
  305. classiq/interface/generator/state_preparation/exponential_state_preparation.py +0 -14
  306. classiq/interface/generator/state_preparation/ghz_state_preparation.py +0 -14
  307. classiq/interface/generator/state_preparation/metrics.py +0 -41
  308. classiq/interface/generator/state_preparation/state_preparation.py +0 -113
  309. classiq/interface/generator/state_preparation/state_preparation_abc.py +0 -24
  310. classiq/interface/generator/state_preparation/uniform_distibution_state_preparation.py +0 -13
  311. classiq/interface/generator/state_preparation/w_state_preparation.py +0 -13
  312. classiq/interface/generator/ucc.py +0 -74
  313. classiq/interface/helpers/backward_compatibility.py +0 -9
  314. classiq/model_expansions/transformers/type_modifier_inference.py +0 -392
  315. classiq/open_library/functions/lookup_table.py +0 -58
  316. classiq/qmod/builtins/functions/chemistry.py +0 -123
  317. classiq/qmod/builtins/functions/qsvm.py +0 -24
  318. classiq-0.92.0.dist-info/WHEEL +0 -4
@@ -0,0 +1,81 @@
1
+ from typing import cast
2
+
3
+ import numpy as np
4
+ from sympy import fwht
5
+
6
+ from classiq.interface.exceptions import ClassiqValueError
7
+
8
+ from classiq.qmod.builtins.functions import CX, RY
9
+ from classiq.qmod.builtins.operations import skip_control
10
+ from classiq.qmod.qfunc import qfunc
11
+ from classiq.qmod.qmod_variable import Const, QArray, QBit
12
+
13
+
14
+ def _get_graycode(size: int, i: int) -> int:
15
+ if i == 2**size:
16
+ return _get_graycode(size, 0)
17
+ return i ^ (i >> 1)
18
+
19
+
20
+ def _get_graycode_angles_wh(size: int, angles: list[float]) -> list[float]:
21
+ transformed_angles = fwht(np.array(angles) / 2**size)
22
+ return [transformed_angles[_get_graycode(size, j)] for j in range(2**size)]
23
+
24
+
25
+ def _get_graycode_ctrls(size: int) -> list[int]:
26
+ return [
27
+ (_get_graycode(size, i) ^ _get_graycode(size, i + 1)).bit_length() - 1
28
+ for i in range(2**size)
29
+ ]
30
+
31
+
32
+ @qfunc
33
+ def assign_amplitude_table(
34
+ amplitudes: list[float], index: Const[QArray], indicator: QBit
35
+ ) -> None:
36
+ """
37
+ [Qmod Classiq-library function]
38
+
39
+ Load a specified list of real amplitudes into a quantum variable using an extra indicator qubit:
40
+ \\( |i\\rangle|0\\rangle \\rightarrow a(i)\\ |i\\rangle|1\\rangle + \\sqrt{1 - a(i)^2}\\ |i\\rangle|0\\rangle \\).
41
+ Here, \\(a(i)\\) is the i-th amplitude, determined by the QNum when the index is in state \\(i\\).
42
+ A list extracted from a given classical function \\(f(x)\\), with indexing according to a given QNum, can be obtained via the utility SDK function `lookup_table`.
43
+ This function expects the indicator qubit to be initialized to \\(|0\\rangle\\).
44
+
45
+ Args:
46
+ amplitudes: Real values for the amplitudes. Must be between -1 and 1
47
+ index: The quantum variable used for amplitude indexing
48
+ indicator: The quantum indicator qubit
49
+
50
+ Example:
51
+ ```python
52
+ from classiq import *
53
+
54
+
55
+ @qfunc
56
+ def main(x: Output[QNum[5, UNSIGNED, 5]], ind: Output[QBit]) -> None:
57
+ allocate(x)
58
+ hadamard_transform(x)
59
+ allocate(ind)
60
+
61
+ assign_amplitude_table(lookup_table(lambda x: x**2, x), x, ind)
62
+ ```
63
+ """
64
+ size = index.len
65
+ if len(amplitudes) != 2**size:
66
+ raise ClassiqValueError(
67
+ f"The number of amplitudes must be 2**index.size={2 ** size}, got "
68
+ f"{len(amplitudes)}"
69
+ )
70
+ if not all(-1 <= amp <= 1 for amp in amplitudes):
71
+ raise ClassiqValueError("All amplitudes must be between -1 and 1")
72
+
73
+ angles_to_load = cast(list[float], 2 * np.arcsin(amplitudes))
74
+ transformed_angles = _get_graycode_angles_wh(size, angles_to_load)
75
+ controllers = _get_graycode_ctrls(size)
76
+
77
+ for k in range(2**size):
78
+ RY(transformed_angles[k], indicator)
79
+ skip_control(
80
+ lambda k=k: CX(index[controllers[k]], indicator) # type:ignore[misc]
81
+ )
@@ -10,9 +10,10 @@ from classiq.qmod.builtins.operations import (
10
10
  repeat,
11
11
  within_apply,
12
12
  )
13
- from classiq.qmod.qfunc import qfunc
14
- from classiq.qmod.qmod_variable import Const, Permutable, QArray, QBit, QNum
13
+ from classiq.qmod.qfunc import qfunc, qperm
14
+ from classiq.qmod.qmod_variable import Const, QArray, QBit, QNum
15
15
  from classiq.qmod.symbolic import pi
16
+ from classiq.qmod.utilities import suppress_return_value
16
17
 
17
18
 
18
19
  def _b_operator(q: QBit) -> None:
@@ -26,8 +27,8 @@ def _qct_d_operator(x: Const[QNum], q: QBit) -> None:
26
27
  control(x == 0, lambda: invert(lambda: _b_operator(q)))
27
28
 
28
29
 
29
- @qfunc
30
- def _qct_pi_operator(x: Permutable[QArray[QBit]], q: Const[QBit]) -> None:
30
+ @qperm
31
+ def _qct_pi_operator(x: QNum, q: Const[QBit]) -> None:
31
32
  control(
32
33
  q == 1,
33
34
  lambda: [
@@ -65,8 +66,8 @@ def _d1_operator(x: QArray[QBit], q: QBit) -> None:
65
66
  PHASE(-omega_exp, q)
66
67
 
67
68
 
68
- def _pi2_operator(x: QArray[QBit], q: QBit) -> None:
69
- control(q == 1, lambda: inplace_add(1, x)) # type:ignore[arg-type]
69
+ def _pi2_operator(x: QNum, q: QBit) -> None:
70
+ control(q == 1, lambda: inplace_add(1, x)), # type:ignore[arg-type]
70
71
 
71
72
 
72
73
  def _j_operator(q: QBit) -> None:
@@ -78,19 +79,23 @@ def _b_t_operator(q: QBit) -> None:
78
79
  S(q)
79
80
 
80
81
 
81
- def _d0dt_operator(x: QArray, q: QBit) -> None:
82
- x_num: QNum = QNum(size=x.len)
83
- bind(x, x_num)
82
+ @suppress_return_value
83
+ def _d0dt_operator(x: QNum, q: QBit) -> None:
84
84
  _b_t_operator(q)
85
- control(x_num == 0, lambda: _j_operator(q))
86
- bind(x_num, x)
85
+ control(x == 0, lambda: _j_operator(q))
87
86
 
88
87
 
89
88
  def _un_dag_operator(x: QArray[QBit], q: QBit) -> None:
90
89
  _d1_operator(x, q)
91
90
  invert(lambda: _qct_pi_operator(x, q))
92
- _d0dt_operator(x, q)
93
- invert(lambda: _pi2_operator(x, q))
91
+ x_num: QNum = QNum(size=x.len)
92
+ within_apply(
93
+ lambda: bind(x, x_num),
94
+ lambda: [
95
+ _d0dt_operator(x_num, q),
96
+ invert(lambda: _pi2_operator(x_num, q)),
97
+ ],
98
+ )
94
99
 
95
100
 
96
101
  @qfunc
@@ -120,7 +125,7 @@ def qct_qst_type1(x: QArray[QBit]) -> None:
120
125
  within_apply(lambda: _t_operator(x), lambda: qft(x))
121
126
 
122
127
 
123
- @qfunc(unchecked=["q"])
128
+ @qfunc(disable_const_checks=["q"])
124
129
  def qct_qst_type2(x: QArray[QBit], q: Const[QBit]) -> None:
125
130
  """
126
131
  [Qmod Classiq-library function]
@@ -8,23 +8,21 @@ from classiq.qmod.builtins.operations import (
8
8
  power,
9
9
  within_apply,
10
10
  )
11
- from classiq.qmod.qfunc import qfunc
11
+ from classiq.qmod.qfunc import qfunc, qperm
12
12
  from classiq.qmod.qmod_parameter import CInt
13
- from classiq.qmod.qmod_variable import Const, Permutable, QArray, QBit, QNum
14
- from classiq.qmod.quantum_callable import QCallable
13
+ from classiq.qmod.qmod_variable import Const, QArray, QBit, QNum
14
+ from classiq.qmod.quantum_callable import QCallable, QPerm
15
15
  from classiq.qmod.symbolic import pi
16
16
 
17
17
 
18
- @qfunc(unchecked=["target"])
19
- def _cond_phase_flip(
20
- predicate: QCallable[Permutable[QBit]], target: Const[QBit]
21
- ) -> None:
18
+ @qperm(disable_perm_check=True, disable_const_checks=["target"])
19
+ def _cond_phase_flip(predicate: QPerm[QBit], target: Const[QBit]) -> None:
22
20
  within_apply(lambda: H(target), lambda: predicate(target))
23
21
 
24
22
 
25
- @qfunc
23
+ @qperm
26
24
  def phase_oracle(
27
- predicate: QCallable[Const[QArray[QBit]], Permutable[QBit]],
25
+ predicate: QPerm[Const[QArray[QBit]], QBit],
28
26
  target: Const[QArray[QBit]],
29
27
  ) -> None:
30
28
  """
@@ -55,7 +53,7 @@ def phase_oracle(
55
53
  )
56
54
 
57
55
 
58
- @qfunc(unchecked=["packed_vars"])
56
+ @qperm(disable_perm_check=True, disable_const_checks=["packed_vars"])
59
57
  def reflect_about_zero(packed_vars: Const[QArray[QBit]]) -> None:
60
58
  """
61
59
  [Qmod Classiq-library function]
@@ -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
  """