classiq 0.38.0__py3-none-any.whl → 0.65.3__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 (499) hide show
  1. classiq/__init__.py +47 -32
  2. classiq/_analyzer_extras/_ipywidgets_async_extension.py +2 -1
  3. classiq/_internals/api_wrapper.py +235 -97
  4. classiq/_internals/async_utils.py +1 -3
  5. classiq/_internals/authentication/auth0.py +26 -10
  6. classiq/_internals/authentication/authentication.py +11 -0
  7. classiq/_internals/authentication/device.py +10 -5
  8. classiq/_internals/authentication/password_manager.py +18 -6
  9. classiq/_internals/authentication/token_manager.py +10 -5
  10. classiq/_internals/client.py +94 -33
  11. classiq/_internals/config.py +3 -4
  12. classiq/_internals/host_checker.py +38 -15
  13. classiq/_internals/jobs.py +60 -57
  14. classiq/_internals/type_validation.py +9 -9
  15. classiq/analyzer/__init__.py +1 -3
  16. classiq/analyzer/analyzer.py +24 -19
  17. classiq/analyzer/analyzer_utilities.py +10 -10
  18. classiq/analyzer/rb.py +15 -15
  19. classiq/analyzer/show_interactive_hack.py +27 -4
  20. classiq/analyzer/url_utils.py +2 -3
  21. classiq/applications/__init__.py +3 -12
  22. classiq/applications/chemistry/__init__.py +14 -10
  23. classiq/applications/chemistry/ansatz_parameters.py +4 -4
  24. classiq/{applications_model_constructors → applications/chemistry}/chemistry_model_constructor.py +165 -158
  25. classiq/applications/chemistry/ground_state_problem.py +1 -1
  26. classiq/{applications_model_constructors → applications}/combinatorial_helpers/allowed_constraints.py +4 -1
  27. classiq/{applications_model_constructors → applications}/combinatorial_helpers/arithmetic/arithmetic_expression.py +1 -1
  28. classiq/{applications_model_constructors → applications}/combinatorial_helpers/arithmetic/isolation.py +1 -1
  29. classiq/{applications_model_constructors → applications}/combinatorial_helpers/combinatorial_problem_utils.py +51 -15
  30. classiq/{applications_model_constructors → applications}/combinatorial_helpers/encoding_mapping.py +12 -12
  31. classiq/{applications_model_constructors → applications}/combinatorial_helpers/encoding_utils.py +8 -6
  32. classiq/{applications_model_constructors → applications}/combinatorial_helpers/memory.py +7 -11
  33. classiq/{applications_model_constructors → applications}/combinatorial_helpers/optimization_model.py +67 -40
  34. classiq/applications/combinatorial_helpers/pauli_helpers/pauli_utils.py +46 -0
  35. classiq/applications/combinatorial_helpers/pyomo_utils.py +447 -0
  36. classiq/{applications_model_constructors → applications}/combinatorial_helpers/sympy_utils.py +2 -2
  37. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/encoding.py +15 -20
  38. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/fixed_variables.py +14 -15
  39. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/ising_converter.py +11 -15
  40. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/penalty.py +1 -2
  41. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/penalty_support.py +3 -7
  42. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/sign_seperation.py +2 -3
  43. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/slack_variables.py +5 -8
  44. classiq/applications/combinatorial_optimization/__init__.py +20 -6
  45. classiq/applications/combinatorial_optimization/combinatorial_optimization_config.py +2 -2
  46. classiq/{applications_model_constructors → applications/combinatorial_optimization}/combinatorial_optimization_model_constructor.py +35 -33
  47. classiq/applications/combinatorial_optimization/combinatorial_problem.py +229 -0
  48. classiq/applications/combinatorial_optimization/examples/__init__.py +1 -3
  49. classiq/applications/finance/__init__.py +4 -5
  50. classiq/{applications_model_constructors → applications/finance}/finance_model_constructor.py +48 -42
  51. classiq/applications/grover/__init__.py +9 -0
  52. classiq/{applications_model_constructors → applications/grover}/grover_model_constructor.py +52 -51
  53. classiq/applications/hamiltonian/pauli_decomposition.py +113 -0
  54. classiq/applications/libraries/qmci_library.py +22 -0
  55. classiq/applications/qnn/__init__.py +2 -4
  56. classiq/applications/qnn/circuit_utils.py +6 -6
  57. classiq/applications/qnn/datasets/__init__.py +9 -11
  58. classiq/applications/qnn/datasets/dataset_base_classes.py +7 -5
  59. classiq/applications/qnn/datasets/dataset_not.py +2 -1
  60. classiq/applications/qnn/datasets/dataset_parity.py +2 -2
  61. classiq/applications/qnn/gradients/quantum_gradient.py +1 -1
  62. classiq/applications/qnn/gradients/simple_quantum_gradient.py +2 -1
  63. classiq/applications/qnn/qlayer.py +30 -10
  64. classiq/applications/qnn/torch_utils.py +4 -3
  65. classiq/applications/qnn/types.py +5 -5
  66. classiq/applications/qsvm/__init__.py +6 -4
  67. classiq/applications/qsvm/qsvm.py +3 -6
  68. classiq/applications/qsvm/qsvm_data_generation.py +3 -3
  69. classiq/{applications_model_constructors → applications/qsvm}/qsvm_model_constructor.py +30 -28
  70. classiq/execution/__init__.py +8 -3
  71. classiq/execution/all_hardware_devices.py +11 -0
  72. classiq/execution/execution_session.py +400 -0
  73. classiq/execution/iqcc.py +63 -0
  74. classiq/execution/jobs.py +197 -25
  75. classiq/execution/qnn.py +79 -0
  76. classiq/executor.py +20 -115
  77. classiq/interface/_version.py +1 -1
  78. classiq/interface/analyzer/analysis_params.py +43 -13
  79. classiq/interface/analyzer/cytoscape_graph.py +15 -9
  80. classiq/interface/analyzer/result.py +28 -32
  81. classiq/interface/applications/qsvm.py +20 -29
  82. classiq/interface/ast_node.py +16 -0
  83. classiq/interface/backend/backend_preferences.py +390 -121
  84. classiq/interface/backend/ionq/ionq_quantum_program.py +15 -23
  85. classiq/interface/backend/pydantic_backend.py +25 -22
  86. classiq/interface/backend/quantum_backend_providers.py +69 -16
  87. classiq/interface/chemistry/fermionic_operator.py +30 -21
  88. classiq/interface/chemistry/ground_state_problem.py +28 -25
  89. classiq/interface/chemistry/molecule.py +14 -10
  90. classiq/interface/chemistry/operator.py +64 -231
  91. classiq/interface/combinatorial_optimization/encoding_types.py +1 -1
  92. classiq/interface/combinatorial_optimization/examples/ascending_sequence.py +1 -3
  93. classiq/interface/combinatorial_optimization/examples/integer_portfolio_optimization.py +2 -4
  94. classiq/interface/combinatorial_optimization/examples/knapsack.py +3 -3
  95. classiq/interface/combinatorial_optimization/examples/mht.py +10 -6
  96. classiq/interface/combinatorial_optimization/examples/portfolio_variations.py +2 -2
  97. classiq/interface/combinatorial_optimization/examples/set_cover.py +1 -2
  98. classiq/interface/combinatorial_optimization/mht_qaoa_input.py +8 -9
  99. classiq/interface/combinatorial_optimization/optimization_problem.py +2 -2
  100. classiq/interface/combinatorial_optimization/result.py +1 -3
  101. classiq/interface/combinatorial_optimization/solver_types.py +1 -1
  102. classiq/interface/debug_info/debug_info.py +86 -0
  103. classiq/{exceptions.py → interface/exceptions.py} +37 -9
  104. classiq/interface/execution/iqcc.py +19 -0
  105. classiq/interface/execution/jobs.py +15 -12
  106. classiq/interface/execution/primitives.py +18 -0
  107. classiq/interface/executor/constants.py +1 -0
  108. classiq/interface/executor/execution_preferences.py +26 -114
  109. classiq/interface/executor/execution_request.py +24 -46
  110. classiq/interface/executor/execution_result.py +30 -8
  111. classiq/interface/executor/iqae_result.py +4 -6
  112. classiq/interface/executor/optimizer_preferences.py +17 -14
  113. classiq/interface/executor/quantum_code.py +28 -24
  114. classiq/interface/executor/quantum_instruction_set.py +2 -2
  115. classiq/interface/executor/register_initialization.py +11 -14
  116. classiq/interface/executor/result.py +83 -56
  117. classiq/interface/executor/vqe_result.py +10 -10
  118. classiq/interface/finance/function_input.py +35 -25
  119. classiq/interface/finance/gaussian_model_input.py +5 -5
  120. classiq/interface/finance/log_normal_model_input.py +4 -4
  121. classiq/interface/finance/model_input.py +4 -4
  122. classiq/interface/generator/adjacency.py +1 -3
  123. classiq/interface/generator/amplitude_loading.py +22 -12
  124. classiq/interface/generator/ansatz_library.py +5 -5
  125. classiq/interface/generator/application_apis/arithmetic_declarations.py +8 -5
  126. classiq/interface/generator/application_apis/chemistry_declarations.py +27 -187
  127. classiq/interface/generator/application_apis/combinatorial_optimization_declarations.py +18 -21
  128. classiq/interface/generator/application_apis/entangler_declarations.py +11 -6
  129. classiq/interface/generator/application_apis/finance_declarations.py +48 -69
  130. classiq/interface/generator/application_apis/qsvm_declarations.py +0 -70
  131. classiq/interface/generator/arith/argument_utils.py +46 -5
  132. classiq/interface/generator/arith/arithmetic.py +35 -16
  133. classiq/interface/generator/arith/arithmetic_arg_type_validator.py +6 -7
  134. classiq/interface/generator/arith/arithmetic_expression_abc.py +66 -25
  135. classiq/interface/generator/arith/arithmetic_expression_parser.py +11 -11
  136. classiq/interface/generator/arith/arithmetic_expression_validator.py +47 -43
  137. classiq/interface/generator/arith/arithmetic_operations.py +14 -6
  138. classiq/interface/generator/arith/arithmetic_param_getters.py +7 -8
  139. classiq/interface/generator/arith/arithmetic_result_builder.py +21 -17
  140. classiq/interface/generator/arith/ast_node_rewrite.py +3 -2
  141. classiq/interface/generator/arith/binary_ops.py +218 -130
  142. classiq/interface/generator/arith/endianness.py +1 -1
  143. classiq/interface/generator/arith/extremum_operations.py +96 -25
  144. classiq/interface/generator/arith/logical_ops.py +14 -12
  145. classiq/interface/generator/arith/number_utils.py +12 -6
  146. classiq/interface/generator/arith/register_user_input.py +60 -37
  147. classiq/interface/generator/arith/unary_ops.py +49 -29
  148. classiq/interface/generator/arith/uncomputation_methods.py +1 -1
  149. classiq/interface/generator/builtin_api_builder.py +2 -9
  150. classiq/interface/generator/chemistry_function_params.py +3 -3
  151. classiq/interface/generator/circuit_code/circuit_code.py +7 -7
  152. classiq/interface/generator/circuit_code/types_and_constants.py +4 -7
  153. classiq/interface/generator/commuting_pauli_exponentiation.py +7 -7
  154. classiq/interface/generator/compiler_keywords.py +5 -1
  155. classiq/interface/generator/complex_type.py +13 -18
  156. classiq/interface/generator/constant.py +3 -4
  157. classiq/interface/generator/control_state.py +34 -29
  158. classiq/interface/generator/copy.py +47 -0
  159. classiq/interface/generator/custom_ansatz.py +2 -5
  160. classiq/interface/generator/distance.py +3 -5
  161. classiq/interface/generator/excitations.py +3 -2
  162. classiq/interface/generator/expressions/atomic_expression_functions.py +21 -5
  163. classiq/interface/generator/expressions/enums/__init__.py +0 -10
  164. classiq/interface/generator/expressions/enums/finance_functions.py +12 -22
  165. classiq/interface/generator/expressions/evaluated_expression.py +5 -5
  166. classiq/interface/generator/expressions/expression.py +26 -14
  167. classiq/interface/generator/expressions/expression_constants.py +9 -3
  168. classiq/interface/generator/expressions/non_symbolic_expr.py +119 -0
  169. classiq/interface/generator/expressions/qmod_qarray_proxy.py +99 -0
  170. classiq/interface/generator/expressions/qmod_qscalar_proxy.py +34 -8
  171. classiq/interface/generator/expressions/qmod_qstruct_proxy.py +36 -0
  172. classiq/interface/generator/expressions/qmod_sized_proxy.py +30 -2
  173. classiq/interface/generator/expressions/qmod_struct_instance.py +14 -2
  174. classiq/interface/generator/expressions/sympy_supported_expressions.py +19 -11
  175. classiq/interface/generator/finance.py +2 -2
  176. classiq/interface/generator/function_param_library.py +6 -6
  177. classiq/interface/generator/function_param_list_without_self_reference.py +2 -10
  178. classiq/interface/generator/function_params.py +36 -64
  179. classiq/interface/generator/functions/__init__.py +0 -22
  180. classiq/interface/generator/functions/builtins/internal_operators.py +16 -0
  181. classiq/interface/generator/functions/classical_function_declaration.py +18 -9
  182. classiq/interface/generator/functions/classical_type.py +47 -166
  183. classiq/interface/generator/functions/concrete_types.py +55 -0
  184. classiq/interface/generator/functions/function_declaration.py +13 -14
  185. classiq/interface/generator/functions/port_declaration.py +1 -13
  186. classiq/interface/generator/functions/qmod_python_interface.py +2 -1
  187. classiq/interface/generator/functions/type_name.py +90 -0
  188. classiq/interface/generator/generated_circuit_data.py +153 -20
  189. classiq/interface/generator/grover_diffuser.py +32 -25
  190. classiq/interface/generator/grover_operator.py +34 -25
  191. classiq/interface/generator/hamiltonian_evolution/exponentiation.py +4 -6
  192. classiq/interface/generator/hamiltonian_evolution/qdrift.py +4 -4
  193. classiq/interface/generator/hamiltonian_evolution/suzuki_trotter.py +9 -9
  194. classiq/interface/generator/hardware/hardware_data.py +72 -34
  195. classiq/interface/generator/hardware_efficient_ansatz.py +20 -16
  196. classiq/interface/generator/hartree_fock.py +13 -5
  197. classiq/interface/generator/identity.py +10 -6
  198. classiq/interface/generator/linear_pauli_rotations.py +32 -20
  199. classiq/interface/generator/mcmt_method.py +1 -1
  200. classiq/interface/generator/mcu.py +17 -15
  201. classiq/interface/generator/mcx.py +24 -17
  202. classiq/interface/generator/model/__init__.py +2 -5
  203. classiq/interface/generator/model/constraints.py +26 -8
  204. classiq/interface/generator/model/model.py +27 -190
  205. classiq/interface/generator/model/preferences/preferences.py +115 -41
  206. classiq/{quantum_register.py → interface/generator/model/quantum_register.py} +14 -17
  207. classiq/interface/generator/oracles/arithmetic_oracle.py +2 -4
  208. classiq/interface/generator/oracles/custom_oracle.py +15 -13
  209. classiq/interface/generator/oracles/oracle_abc.py +7 -7
  210. classiq/interface/generator/partitioned_register.py +7 -7
  211. classiq/interface/generator/piecewise_linear_amplitude_loading.py +45 -29
  212. classiq/interface/generator/preferences/optimization.py +1 -2
  213. classiq/interface/generator/qpe.py +41 -30
  214. classiq/interface/generator/qsvm.py +9 -10
  215. classiq/interface/generator/quantum_function_call.py +88 -73
  216. classiq/interface/generator/quantum_program.py +41 -24
  217. classiq/interface/generator/range_types.py +11 -12
  218. classiq/interface/generator/register_role.py +18 -6
  219. classiq/interface/generator/slice_parsing_utils.py +5 -5
  220. classiq/interface/generator/standard_gates/controlled_standard_gates.py +30 -39
  221. classiq/interface/generator/standard_gates/standard_angle_metaclass.py +2 -6
  222. classiq/interface/generator/standard_gates/standard_gates.py +3 -3
  223. classiq/interface/generator/standard_gates/u_gate.py +7 -10
  224. classiq/interface/generator/state_preparation/bell_state_preparation.py +3 -3
  225. classiq/interface/generator/state_preparation/computational_basis_state_preparation.py +2 -1
  226. classiq/interface/generator/state_preparation/distributions.py +16 -15
  227. classiq/interface/generator/state_preparation/metrics.py +4 -7
  228. classiq/interface/generator/state_preparation/state_preparation.py +25 -20
  229. classiq/interface/generator/synthesis_metadata/synthesis_duration.py +0 -4
  230. classiq/interface/generator/synthesis_metadata/synthesis_execution_data.py +20 -6
  231. classiq/interface/generator/transpiler_basis_gates.py +7 -3
  232. classiq/interface/generator/types/builtin_enum_declarations.py +178 -0
  233. classiq/interface/generator/types/compilation_metadata.py +6 -0
  234. classiq/interface/generator/types/enum_declaration.py +54 -0
  235. classiq/interface/generator/types/qstruct_declaration.py +18 -0
  236. classiq/interface/generator/types/struct_declaration.py +7 -11
  237. classiq/interface/generator/ucc.py +5 -4
  238. classiq/interface/generator/unitary_gate.py +5 -5
  239. classiq/interface/generator/user_defined_function_params.py +4 -1
  240. classiq/interface/generator/validations/flow_graph.py +7 -7
  241. classiq/interface/generator/validations/validator_functions.py +4 -4
  242. classiq/interface/generator/visitor.py +23 -16
  243. classiq/interface/hardware.py +29 -8
  244. classiq/interface/helpers/classproperty.py +8 -0
  245. classiq/interface/helpers/custom_encoders.py +2 -2
  246. classiq/interface/helpers/custom_pydantic_types.py +40 -50
  247. classiq/interface/helpers/datastructures.py +26 -0
  248. classiq/interface/helpers/hashable_mixin.py +3 -2
  249. classiq/interface/helpers/hashable_pydantic_base_model.py +2 -1
  250. classiq/interface/helpers/pydantic_model_helpers.py +7 -5
  251. classiq/interface/helpers/validation_helpers.py +3 -20
  252. classiq/interface/helpers/versioned_model.py +1 -4
  253. classiq/interface/ide/ide_data.py +16 -20
  254. classiq/interface/ide/visual_model.py +130 -0
  255. classiq/interface/interface_version.py +1 -0
  256. classiq/interface/jobs.py +29 -69
  257. classiq/interface/model/allocate.py +16 -0
  258. classiq/interface/model/bind_operation.py +32 -9
  259. classiq/interface/model/classical_if.py +15 -0
  260. classiq/interface/model/classical_parameter_declaration.py +33 -3
  261. classiq/interface/model/control.py +45 -0
  262. classiq/interface/model/handle_binding.py +298 -20
  263. classiq/interface/model/inplace_binary_operation.py +29 -24
  264. classiq/interface/model/invert.py +12 -0
  265. classiq/interface/model/model.py +69 -61
  266. classiq/interface/model/native_function_definition.py +17 -20
  267. classiq/interface/model/parameter.py +13 -0
  268. classiq/interface/model/phase_operation.py +11 -0
  269. classiq/interface/model/port_declaration.py +27 -9
  270. classiq/interface/model/power.py +14 -0
  271. classiq/interface/model/quantum_expressions/amplitude_loading_operation.py +30 -18
  272. classiq/interface/model/quantum_expressions/arithmetic_operation.py +51 -14
  273. classiq/interface/model/quantum_expressions/quantum_expression.py +12 -35
  274. classiq/interface/model/quantum_function_call.py +141 -343
  275. classiq/interface/model/quantum_function_declaration.py +190 -157
  276. classiq/interface/model/quantum_lambda_function.py +33 -32
  277. classiq/interface/model/quantum_statement.py +71 -12
  278. classiq/interface/model/quantum_type.py +177 -40
  279. classiq/interface/model/quantum_variable_declaration.py +3 -25
  280. classiq/interface/model/repeat.py +15 -0
  281. classiq/interface/model/statement_block.py +40 -14
  282. classiq/interface/model/validation_handle.py +13 -6
  283. classiq/interface/model/variable_declaration_statement.py +3 -1
  284. classiq/interface/model/within_apply_operation.py +7 -5
  285. classiq/interface/server/global_versions.py +6 -7
  286. classiq/interface/server/routes.py +17 -21
  287. classiq/interface/source_reference.py +59 -0
  288. classiq/model_expansions/atomic_expression_functions_defs.py +253 -0
  289. classiq/model_expansions/capturing/__init__.py +0 -0
  290. classiq/model_expansions/capturing/captured_vars.py +435 -0
  291. classiq/model_expansions/capturing/mangling_utils.py +56 -0
  292. classiq/model_expansions/closure.py +171 -0
  293. classiq/model_expansions/debug_flag.py +3 -0
  294. classiq/model_expansions/evaluators/__init__.py +0 -0
  295. classiq/model_expansions/evaluators/arg_type_match.py +158 -0
  296. classiq/model_expansions/evaluators/argument_types.py +42 -0
  297. classiq/model_expansions/evaluators/classical_expression.py +36 -0
  298. classiq/model_expansions/evaluators/control.py +144 -0
  299. classiq/model_expansions/evaluators/parameter_types.py +226 -0
  300. classiq/model_expansions/evaluators/quantum_type_utils.py +239 -0
  301. classiq/model_expansions/evaluators/type_type_match.py +90 -0
  302. classiq/model_expansions/expression_evaluator.py +135 -0
  303. classiq/model_expansions/expression_renamer.py +76 -0
  304. classiq/model_expansions/function_builder.py +247 -0
  305. classiq/model_expansions/generative_functions.py +158 -0
  306. classiq/model_expansions/interpreters/__init__.py +0 -0
  307. classiq/model_expansions/interpreters/base_interpreter.py +263 -0
  308. classiq/model_expansions/interpreters/frontend_generative_interpreter.py +28 -0
  309. classiq/model_expansions/interpreters/generative_interpreter.py +249 -0
  310. classiq/model_expansions/model_tables.py +18 -0
  311. classiq/model_expansions/quantum_operations/__init__.py +9 -0
  312. classiq/model_expansions/quantum_operations/bind.py +60 -0
  313. classiq/model_expansions/quantum_operations/call_emitter.py +266 -0
  314. classiq/model_expansions/quantum_operations/classicalif.py +53 -0
  315. classiq/model_expansions/quantum_operations/declarative_call_emitter.py +87 -0
  316. classiq/model_expansions/quantum_operations/emitter.py +181 -0
  317. classiq/model_expansions/quantum_operations/quantum_function_call.py +33 -0
  318. classiq/model_expansions/quantum_operations/repeat.py +56 -0
  319. classiq/model_expansions/quantum_operations/shallow_emitter.py +180 -0
  320. classiq/model_expansions/quantum_operations/variable_decleration.py +28 -0
  321. classiq/model_expansions/scope.py +240 -0
  322. classiq/model_expansions/scope_initialization.py +150 -0
  323. classiq/model_expansions/sympy_conversion/__init__.py +0 -0
  324. classiq/model_expansions/sympy_conversion/arithmetics.py +49 -0
  325. classiq/model_expansions/sympy_conversion/expression_to_sympy.py +179 -0
  326. classiq/model_expansions/sympy_conversion/sympy_to_python.py +123 -0
  327. classiq/model_expansions/transformers/__init__.py +0 -0
  328. classiq/model_expansions/transformers/ast_renamer.py +26 -0
  329. classiq/model_expansions/transformers/var_splitter.py +299 -0
  330. classiq/model_expansions/utils/__init__.py +0 -0
  331. classiq/model_expansions/utils/counted_name_allocator.py +11 -0
  332. classiq/model_expansions/utils/handles_collector.py +33 -0
  333. classiq/model_expansions/visitors/__init__.py +0 -0
  334. classiq/model_expansions/visitors/boolean_expression_transformers.py +214 -0
  335. classiq/model_expansions/visitors/variable_references.py +144 -0
  336. classiq/open_library/__init__.py +4 -0
  337. classiq/open_library/functions/__init__.py +130 -0
  338. classiq/open_library/functions/amplitude_estimation.py +30 -0
  339. classiq/open_library/functions/discrete_sine_cosine_transform.py +181 -0
  340. classiq/open_library/functions/grover.py +157 -0
  341. classiq/open_library/functions/hea.py +115 -0
  342. classiq/open_library/functions/linear_pauli_rotation.py +82 -0
  343. classiq/open_library/functions/modular_exponentiation.py +201 -0
  344. classiq/open_library/functions/qaoa_penalty.py +117 -0
  345. classiq/open_library/functions/qft_functions.py +54 -0
  346. classiq/open_library/functions/qpe.py +46 -0
  347. classiq/open_library/functions/qsvt.py +331 -0
  348. classiq/open_library/functions/state_preparation.py +301 -0
  349. classiq/open_library/functions/swap_test.py +27 -0
  350. classiq/open_library/functions/utility_functions.py +81 -0
  351. classiq/open_library/functions/variational.py +52 -0
  352. classiq/qmod/__init__.py +10 -10
  353. classiq/qmod/builtins/__init__.py +19 -2
  354. classiq/qmod/builtins/classical_execution_primitives.py +36 -14
  355. classiq/qmod/builtins/classical_functions.py +39 -43
  356. classiq/qmod/builtins/constants.py +10 -0
  357. classiq/qmod/builtins/enums.py +208 -0
  358. classiq/qmod/builtins/functions/__init__.py +137 -0
  359. classiq/qmod/builtins/functions/allocation.py +150 -0
  360. classiq/qmod/builtins/functions/arithmetic.py +55 -0
  361. classiq/qmod/builtins/functions/benchmarking.py +8 -0
  362. classiq/qmod/builtins/functions/chemistry.py +91 -0
  363. classiq/qmod/builtins/functions/exponentiation.py +105 -0
  364. classiq/qmod/builtins/functions/finance.py +34 -0
  365. classiq/qmod/builtins/functions/operators.py +16 -0
  366. classiq/qmod/builtins/functions/qsvm.py +24 -0
  367. classiq/qmod/builtins/functions/standard_gates.py +651 -0
  368. classiq/qmod/builtins/operations.py +373 -40
  369. classiq/qmod/builtins/structs.py +103 -80
  370. classiq/qmod/cfunc.py +2 -2
  371. classiq/qmod/classical_function.py +4 -8
  372. classiq/qmod/cparam.py +64 -0
  373. classiq/qmod/create_model_function.py +56 -0
  374. classiq/qmod/declaration_inferrer.py +143 -101
  375. classiq/qmod/expression_query.py +20 -4
  376. classiq/qmod/generative.py +42 -0
  377. classiq/qmod/model_state_container.py +18 -6
  378. classiq/qmod/native/__init__.py +7 -0
  379. classiq/qmod/native/expression_to_qmod.py +16 -11
  380. classiq/qmod/native/pretty_printer.py +187 -97
  381. classiq/qmod/pretty_print/__init__.py +7 -0
  382. classiq/qmod/pretty_print/expression_to_python.py +222 -0
  383. classiq/qmod/pretty_print/pretty_printer.py +572 -0
  384. classiq/qmod/python_classical_type.py +67 -0
  385. classiq/qmod/qfunc.py +60 -8
  386. classiq/qmod/qmod_constant.py +93 -26
  387. classiq/qmod/qmod_parameter.py +68 -59
  388. classiq/qmod/qmod_variable.py +468 -155
  389. classiq/qmod/quantum_callable.py +17 -7
  390. classiq/qmod/quantum_expandable.py +269 -96
  391. classiq/qmod/quantum_function.py +196 -41
  392. classiq/qmod/semantics/__init__.py +0 -0
  393. classiq/qmod/semantics/annotation/__init__.py +0 -0
  394. classiq/qmod/semantics/annotation/call_annotation.py +92 -0
  395. classiq/qmod/semantics/annotation/qstruct_annotator.py +23 -0
  396. classiq/qmod/semantics/error_manager.py +88 -0
  397. classiq/qmod/semantics/lambdas.py +25 -0
  398. classiq/qmod/semantics/static_semantics_visitor.py +384 -0
  399. classiq/qmod/semantics/validation/__init__.py +0 -0
  400. classiq/qmod/semantics/validation/constants_validation.py +16 -0
  401. classiq/qmod/semantics/validation/func_call_validation.py +99 -0
  402. classiq/qmod/semantics/validation/function_name_collisions_validation.py +23 -0
  403. classiq/qmod/semantics/validation/handle_validation.py +85 -0
  404. classiq/qmod/semantics/validation/main_validation.py +33 -0
  405. classiq/qmod/semantics/validation/types_validation.py +128 -0
  406. classiq/qmod/symbolic.py +147 -123
  407. classiq/qmod/symbolic_expr.py +27 -12
  408. classiq/qmod/symbolic_type.py +2 -5
  409. classiq/qmod/type_attribute_remover.py +32 -0
  410. classiq/qmod/utilities.py +98 -4
  411. classiq/qmod/write_qmod.py +17 -3
  412. classiq/synthesis.py +210 -22
  413. {classiq-0.38.0.dist-info → classiq-0.65.3.dist-info}/METADATA +16 -9
  414. classiq-0.65.3.dist-info/RECORD +521 -0
  415. classiq/_internals/_qfunc_ext.py +0 -6
  416. classiq/applications/benchmarking/__init__.py +0 -9
  417. classiq/applications/benchmarking/mirror_benchmarking.py +0 -70
  418. classiq/applications/numpy_utils.py +0 -37
  419. classiq/applications_model_constructors/__init__.py +0 -25
  420. classiq/applications_model_constructors/combinatorial_helpers/multiple_comp_basis_sp.py +0 -34
  421. classiq/applications_model_constructors/combinatorial_helpers/pauli_helpers/pauli_utils.py +0 -65
  422. classiq/applications_model_constructors/combinatorial_helpers/pyomo_utils.py +0 -243
  423. classiq/applications_model_constructors/libraries/ampltitude_estimation_library.py +0 -11
  424. classiq/applications_model_constructors/libraries/qmci_library.py +0 -107
  425. classiq/builtin_functions/__init__.py +0 -43
  426. classiq/builtin_functions/amplitude_loading.py +0 -3
  427. classiq/builtin_functions/binary_ops.py +0 -1
  428. classiq/builtin_functions/exponentiation.py +0 -5
  429. classiq/builtin_functions/qpe.py +0 -4
  430. classiq/builtin_functions/qsvm.py +0 -7
  431. classiq/builtin_functions/range_types.py +0 -5
  432. classiq/builtin_functions/standard_gates.py +0 -1
  433. classiq/builtin_functions/state_preparation.py +0 -6
  434. classiq/builtin_functions/suzuki_trotter.py +0 -3
  435. classiq/interface/executor/aws_execution_cost.py +0 -73
  436. classiq/interface/executor/error_mitigation.py +0 -6
  437. classiq/interface/generator/credit_risk_example/linear_gci.py +0 -122
  438. classiq/interface/generator/credit_risk_example/weighted_adder.py +0 -69
  439. classiq/interface/generator/expressions/enums/chemistry.py +0 -28
  440. classiq/interface/generator/expressions/enums/classical_enum.py +0 -5
  441. classiq/interface/generator/expressions/enums/ladder_operator.py +0 -16
  442. classiq/interface/generator/expressions/enums/optimizers.py +0 -9
  443. classiq/interface/generator/expressions/enums/pauli.py +0 -8
  444. classiq/interface/generator/expressions/enums/qsvm_feature_map_entanglement.py +0 -9
  445. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/__init__.py +0 -18
  446. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/atomic_quantum_functions.py +0 -641
  447. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/exponentiation_functions.py +0 -89
  448. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/std_lib_functions.py +0 -1229
  449. classiq/interface/generator/functions/core_lib_declarations/quantum_operators.py +0 -95
  450. classiq/interface/generator/functions/foreign_function_definition.py +0 -114
  451. classiq/interface/generator/functions/function_implementation.py +0 -107
  452. classiq/interface/generator/functions/native_function_definition.py +0 -155
  453. classiq/interface/generator/functions/quantum_function_declaration.py +0 -69
  454. classiq/interface/generator/functions/register.py +0 -44
  455. classiq/interface/generator/functions/register_mapping_data.py +0 -106
  456. classiq/interface/generator/inequality_mixer.py +0 -51
  457. classiq/interface/generator/model/classical_main_validator.py +0 -106
  458. classiq/interface/generator/range_mixer.py +0 -56
  459. classiq/interface/generator/state_propagator.py +0 -74
  460. classiq/interface/generator/types/builtin_struct_declarations/__init__.py +0 -1
  461. classiq/interface/generator/types/builtin_struct_declarations/pauli_struct_declarations.py +0 -22
  462. classiq/interface/ide/show.py +0 -34
  463. classiq/interface/model/call_synthesis_data.py +0 -68
  464. classiq/interface/model/common_model_types.py +0 -23
  465. classiq/interface/model/quantum_expressions/control_state.py +0 -38
  466. classiq/interface/model/quantum_if_operation.py +0 -94
  467. classiq/interface/model/resolvers/function_call_resolver.py +0 -43
  468. classiq/interface/model/validations/handle_validation_base.py +0 -55
  469. classiq/interface/model/validations/handles_validator.py +0 -156
  470. classiq/interface/model/validations/port_to_wire_name_generator.py +0 -12
  471. classiq/model/__init__.py +0 -14
  472. classiq/model/composite_function_generator.py +0 -33
  473. classiq/model/function_handler.py +0 -462
  474. classiq/model/logic_flow.py +0 -149
  475. classiq/model/logic_flow_change_handler.py +0 -71
  476. classiq/model/model.py +0 -229
  477. classiq/qmod/builtins/functions.py +0 -913
  478. classiq/qmod/qmod_struct.py +0 -37
  479. classiq/quantum_functions/__init__.py +0 -17
  480. classiq/quantum_functions/annotation_parser.py +0 -205
  481. classiq/quantum_functions/decorators.py +0 -22
  482. classiq/quantum_functions/function_library.py +0 -181
  483. classiq/quantum_functions/function_parser.py +0 -74
  484. classiq/quantum_functions/quantum_function.py +0 -236
  485. classiq-0.38.0.dist-info/RECORD +0 -454
  486. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/__init__.py +0 -0
  487. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/arithmetic/__init__.py +0 -0
  488. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/pauli_helpers/__init__.py +0 -0
  489. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/pauli_helpers/pauli_sparsing.py +0 -0
  490. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/py.typed +0 -0
  491. /classiq/{applications_model_constructors/combinatorial_helpers/transformations → applications/combinatorial_helpers/solvers}/__init__.py +0 -0
  492. /classiq/{applications_model_constructors/libraries → applications/combinatorial_helpers/transformations}/__init__.py +0 -0
  493. /classiq/{interface/generator/credit_risk_example → applications/hamiltonian}/__init__.py +0 -0
  494. /classiq/{interface/generator/functions/core_lib_declarations → applications/libraries}/__init__.py +0 -0
  495. /classiq/interface/{model/resolvers → debug_info}/__init__.py +0 -0
  496. /classiq/{_internals → interface}/enum_utils.py +0 -0
  497. /classiq/interface/{model/validations → generator/functions/builtins}/__init__.py +0 -0
  498. /classiq/{interface/generator/functions/core_lib_declarations/quantum_functions/chemistry_functions.py → model_expansions/__init__.py} +0 -0
  499. {classiq-0.38.0.dist-info → classiq-0.65.3.dist-info}/WHEEL +0 -0
@@ -0,0 +1,400 @@
1
+ import json
2
+ import random
3
+ from types import TracebackType
4
+ from typing import Callable, Optional, Union, cast
5
+
6
+ import numpy as np
7
+
8
+ from classiq.interface.chemistry.operator import PauliOperator, pauli_integers_to_str
9
+ from classiq.interface.exceptions import ClassiqError, ClassiqValueError
10
+ from classiq.interface.execution.primitives import EstimateInput, PrimitivesInput
11
+ from classiq.interface.executor.execution_preferences import ExecutionPreferences
12
+ from classiq.interface.executor.result import (
13
+ EstimationResult,
14
+ ExecutionDetails,
15
+ ParsedState,
16
+ )
17
+ from classiq.interface.generator.arith import number_utils
18
+ from classiq.interface.generator.functions.qmod_python_interface import QmodPyStruct
19
+ from classiq.interface.generator.quantum_program import QuantumProgram
20
+ from classiq.interface.model.quantum_type import QuantumBit, QuantumNumeric
21
+
22
+ from classiq._internals import async_utils
23
+ from classiq._internals.api_wrapper import ApiWrapper
24
+ from classiq._internals.client import client
25
+ from classiq.applications.combinatorial_helpers.pauli_helpers.pauli_utils import (
26
+ _pauli_dict_to_pauli_terms,
27
+ )
28
+ from classiq.execution.jobs import ExecutionJob
29
+ from classiq.qmod.builtins import PauliTerm
30
+ from classiq.qmod.builtins.classical_execution_primitives import (
31
+ CARRAY_SEPARATOR,
32
+ ExecutionParams,
33
+ )
34
+ from classiq.synthesis import SerializedQuantumProgram
35
+
36
+ Hamiltonian = Union[list[QmodPyStruct], list[PauliTerm]]
37
+ Program = Union[SerializedQuantumProgram, QuantumProgram]
38
+ ParsedExecutionParams = dict[str, Union[float, int]]
39
+ ExecutionParameters = Optional[Union[ExecutionParams, list[ExecutionParams]]]
40
+ ParsedExecutionParameters = Optional[
41
+ Union[ParsedExecutionParams, list[ParsedExecutionParams]]
42
+ ]
43
+
44
+
45
+ def _deserialize_program(program: Program) -> QuantumProgram:
46
+ return (
47
+ program
48
+ if isinstance(program, QuantumProgram)
49
+ else QuantumProgram.model_validate(json.loads(program))
50
+ )
51
+
52
+
53
+ def hamiltonian_to_pauli_terms(hamiltonian: Hamiltonian) -> list[PauliTerm]:
54
+ if isinstance(hamiltonian[0], PauliTerm):
55
+ return cast(list[PauliTerm], hamiltonian)
56
+ else:
57
+ return _pauli_dict_to_pauli_terms(cast(list[QmodPyStruct], hamiltonian))
58
+
59
+
60
+ def _hamiltonian_to_pauli_operator(hamiltonian: Hamiltonian) -> PauliOperator:
61
+ pauli_list = [
62
+ (
63
+ pauli_integers_to_str(elem.pauli), # type: ignore[arg-type]
64
+ elem.coefficient,
65
+ )
66
+ for elem in hamiltonian_to_pauli_terms(hamiltonian)
67
+ ]
68
+ return PauliOperator(pauli_list=pauli_list)
69
+
70
+
71
+ def parse_params(params: ExecutionParams) -> ParsedExecutionParams:
72
+ result = {}
73
+ for key, values in params.items():
74
+ if isinstance(values, list):
75
+ for index, value in enumerate(values):
76
+ new_key = f"{key}{CARRAY_SEPARATOR}{index}"
77
+ result[new_key] = value
78
+ elif isinstance(values, (int, float)):
79
+ result[key] = values
80
+ else:
81
+ raise TypeError("Parameters were provided in un-supported format")
82
+ return result
83
+
84
+
85
+ class ExecutionSession:
86
+ """
87
+ A session for executing a quantum program.
88
+ `ExecutionSession` allows to execute the quantum program with different parameters and operations without the need to re-synthesize the model.
89
+ The session must be closed in order to ensure resources are properly cleaned up. It's recommended to use `ExecutionSession` as a context manager for this purpose. Alternatively, you can directly use the `close` method.
90
+
91
+ Attributes:
92
+ quantum_program (Union[SerializedQuantumProgram, QuantumProgram]): The quantum program to execute.
93
+ execution_preferences (Optional[ExecutionPreferences]): Execution preferences for the Quantum Program.
94
+ """
95
+
96
+ def __init__(
97
+ self,
98
+ quantum_program: Program,
99
+ execution_preferences: Optional[ExecutionPreferences] = None,
100
+ ):
101
+ self.program: QuantumProgram = _deserialize_program(quantum_program)
102
+ self.update_execution_preferences(execution_preferences)
103
+ # We never use classical_execution_code in ExecutionSession, and we don't want
104
+ # the conversion route to fail because cmain is expected in some cases
105
+ self.program.model.classical_execution_code = "dummy"
106
+
107
+ self._random_seed = self.program.model.execution_preferences.random_seed
108
+ self._rng = random.Random(self._random_seed) # noqa: S311
109
+
110
+ self._async_client = client().async_client()
111
+
112
+ self._session_id: str | None = None
113
+
114
+ def __enter__(self) -> "ExecutionSession":
115
+ return self
116
+
117
+ def __exit__(
118
+ self,
119
+ exc_type: Optional[type[BaseException]],
120
+ exc_val: Optional[BaseException],
121
+ exc_tb: Optional[TracebackType],
122
+ ) -> None:
123
+ self.close()
124
+
125
+ def close(self) -> None:
126
+ """
127
+ Close the session and clean up its resources.
128
+ """
129
+ async_utils.run(self._async_client.aclose())
130
+
131
+ def get_session_id(self) -> str:
132
+ if self._session_id is None:
133
+ self._session_id = async_utils.run(
134
+ ApiWrapper.call_create_execution_session(
135
+ self.program, self._async_client
136
+ )
137
+ )
138
+ return self._session_id
139
+
140
+ def _execute(self, primitives_input: PrimitivesInput) -> ExecutionJob:
141
+ primitives_input.random_seed = self._random_seed
142
+ self._random_seed = self._rng.randint(0, 2**32 - 1)
143
+ result = async_utils.run(
144
+ ApiWrapper.call_create_session_job(
145
+ self.get_session_id(), primitives_input, self._async_client
146
+ )
147
+ )
148
+ return ExecutionJob(details=result)
149
+
150
+ def update_execution_preferences(
151
+ self, execution_preferences: Optional[ExecutionPreferences]
152
+ ) -> None:
153
+ """
154
+ Update the execution preferences for the session.
155
+
156
+ Args:
157
+ execution_preferences: The execution preferences to update.
158
+
159
+ Returns:
160
+ None
161
+ """
162
+ if execution_preferences is not None:
163
+ self.program.model.execution_preferences = execution_preferences
164
+
165
+ def sample(self, parameters: Optional[ExecutionParams] = None) -> ExecutionDetails:
166
+ """
167
+ Samples the quantum program with the given parameters, if any.
168
+
169
+ Args:
170
+ parameters: The values to set for the parameters of the quantum program when sampling. Each key should be the name of a parameter in the quantum program (parameters of the main function), and the value should be the value to set for that parameter.
171
+
172
+ Returns:
173
+ The result of the sampling.
174
+ """
175
+ job = self.submit_sample(parameters=parameters)
176
+ return job.get_sample_result(_http_client=self._async_client)
177
+
178
+ def submit_sample(
179
+ self, parameters: Optional[ExecutionParams] = None
180
+ ) -> ExecutionJob:
181
+ """
182
+ Initiates an execution job with the `sample` primitive.
183
+
184
+ This is a non-blocking version of `sample`: it gets the same parameters and initiates the same execution job, but instead
185
+ of waiting for the result, it returns the job object immediately.
186
+
187
+ Args:
188
+ parameters: The values to set for the parameters of the quantum program when sampling. Each key should be the name of a parameter in the quantum program (parameters of the main function), and the value should be the value to set for that parameter.
189
+
190
+ Returns:
191
+ The execution job.
192
+ """
193
+ execution_primitives_input = PrimitivesInput(
194
+ sample=[parse_params(parameters)] if parameters is not None else [{}]
195
+ )
196
+ return self._execute(execution_primitives_input)
197
+
198
+ def batch_sample(self, parameters: list[ExecutionParams]) -> list[ExecutionDetails]:
199
+ """
200
+ Samples the quantum program multiple times with the given parameters for each iteration. The number of samples is determined by the length of the parameters list.
201
+
202
+ Args:
203
+ parameters: A list of the parameters for each iteration. Each item is a dictionary where each key should be the name of a parameter in the quantum program (parameters of the main function), and the value should be the value to set for that parameter.
204
+
205
+ Returns:
206
+ List[ExecutionDetails]: The results of all the sampling iterations.
207
+ """
208
+ job = self.submit_batch_sample(parameters=parameters)
209
+ return job.get_batch_sample_result(_http_client=self._async_client)
210
+
211
+ def submit_batch_sample(self, parameters: list[ExecutionParams]) -> ExecutionJob:
212
+ """
213
+ Initiates an execution job with the `batch_sample` primitive.
214
+
215
+ This is a non-blocking version of `batch_sample`: it gets the same parameters and initiates the same execution job, but instead
216
+ of waiting for the result, it returns the job object immediately.
217
+
218
+ Args:
219
+ parameters: A list of the parameters for each iteration. Each item is a dictionary where each key should be the name of a parameter in the quantum program (parameters of the main function), and the value should be the value to set for that parameter.
220
+
221
+ Returns:
222
+ The execution job.
223
+ """
224
+ execution_primitives_input = PrimitivesInput(
225
+ sample=[parse_params(params) for params in parameters]
226
+ )
227
+ return self._execute(execution_primitives_input)
228
+
229
+ def estimate(
230
+ self, hamiltonian: Hamiltonian, parameters: Optional[ExecutionParams] = None
231
+ ) -> EstimationResult:
232
+ """
233
+ Estimates the expectation value of the given Hamiltonian using the quantum program.
234
+
235
+ Args:
236
+ hamiltonian: The Hamiltonian to estimate the expectation value of.
237
+ parameters: The values to set for the parameters of the quantum program when estimating. Each key should be the name of a parameter in the quantum program (parameters of the main function), and the value should be the value to set for that parameter.
238
+
239
+ Returns:
240
+ EstimationResult: The result of the estimation.
241
+ """
242
+ job = self.submit_estimate(hamiltonian=hamiltonian, parameters=parameters)
243
+ return job.get_estimate_result(_http_client=self._async_client)
244
+
245
+ def submit_estimate(
246
+ self, hamiltonian: Hamiltonian, parameters: Optional[ExecutionParams] = None
247
+ ) -> ExecutionJob:
248
+ """
249
+ Initiates an execution job with the `estimate` primitive.
250
+
251
+ This is a non-blocking version of `estimate`: it gets the same parameters and initiates the same execution job, but instead
252
+ of waiting for the result, it returns the job object immediately.
253
+
254
+ Args:
255
+ hamiltonian: The Hamiltonian to estimate the expectation value of.
256
+ parameters: The values to set for the parameters of the quantum program when estimating. Each key should be the name of a parameter in the quantum program (parameters of the main function), and the value should be the value to set for that parameter.
257
+
258
+ Returns:
259
+ The execution job.
260
+ """
261
+ execution_primitives_input = PrimitivesInput(
262
+ estimate=EstimateInput(
263
+ hamiltonian=_hamiltonian_to_pauli_operator(hamiltonian),
264
+ parameters=(
265
+ [parse_params(parameters)] if parameters is not None else [{}]
266
+ ),
267
+ )
268
+ )
269
+ return self._execute(execution_primitives_input)
270
+
271
+ def batch_estimate(
272
+ self, hamiltonian: Hamiltonian, parameters: list[ExecutionParams]
273
+ ) -> list[EstimationResult]:
274
+ """
275
+ Estimates the expectation value of the given Hamiltonian multiple times using the quantum program, with the given parameters for each iteration. The number of estimations is determined by the length of the parameters list.
276
+
277
+ Args:
278
+ hamiltonian: The Hamiltonian to estimate the expectation value of.
279
+ parameters: A list of the parameters for each iteration. Each item is a dictionary where each key should be the name of a parameter in the quantum program (parameters of the main function), and the value should be the value to set for that parameter.
280
+
281
+ Returns:
282
+ List[EstimationResult]: The results of all the estimation iterations.
283
+ """
284
+ job = self.submit_batch_estimate(hamiltonian=hamiltonian, parameters=parameters)
285
+ return job.get_batch_estimate_result(_http_client=self._async_client)
286
+
287
+ def submit_batch_estimate(
288
+ self, hamiltonian: Hamiltonian, parameters: list[ExecutionParams]
289
+ ) -> ExecutionJob:
290
+ """
291
+ Initiates an execution job with the `batch_estimate` primitive.
292
+
293
+ This is a non-blocking version of `batch_estimate`: it gets the same parameters and initiates the same execution job, but instead
294
+ of waiting for the result, it returns the job object immediately.
295
+
296
+ Args:
297
+ hamiltonian: The Hamiltonian to estimate the expectation value of.
298
+ parameters: A list of the parameters for each iteration. Each item is a dictionary where each key should be the name of a parameter in the quantum program (parameters of the main function), and the value should be the value to set for that parameter.
299
+
300
+ Returns:
301
+ The execution job.
302
+ """
303
+ execution_primitives_input = PrimitivesInput(
304
+ estimate=EstimateInput(
305
+ hamiltonian=_hamiltonian_to_pauli_operator(hamiltonian),
306
+ parameters=[parse_params(params) for params in parameters],
307
+ )
308
+ )
309
+ return self._execute(execution_primitives_input)
310
+
311
+ def estimate_cost(
312
+ self,
313
+ cost_func: Callable[[ParsedState], float],
314
+ parameters: Optional[ExecutionParams] = None,
315
+ quantile: float = 1.0,
316
+ ) -> float:
317
+ """
318
+ Estimates circuit cost using a classical cost function.
319
+
320
+ Args:
321
+ cost_func: classical circuit sample cost function
322
+ parameters: execution parameters sent to 'sample'
323
+ quantile: drop cost values outside the specified quantile
324
+
325
+ Returns:
326
+ cost estimation
327
+
328
+ See Also:
329
+ sample
330
+ """
331
+ if quantile < 0 or quantile > 1:
332
+ raise ClassiqValueError("'quantile' must be between 0 and 1")
333
+ res = self.sample(parameters)
334
+
335
+ counts = np.array(res.parsed_counts)
336
+ costs = np.vectorize(lambda sample: cost_func(sample.state))(counts)
337
+ shots = np.vectorize(lambda sample: sample.shots)(counts)
338
+
339
+ if quantile == 1:
340
+ return float(np.average(costs, weights=shots))
341
+ costs = np.repeat(costs, shots)
342
+ sort_idx = costs.argsort()
343
+ sort_idx = sort_idx[: int(quantile * len(costs))]
344
+ costs = costs[sort_idx]
345
+ if costs.size == 0:
346
+ return np.nan
347
+ return float(np.average(costs))
348
+
349
+ def set_measured_state_filter(
350
+ self,
351
+ output_name: str,
352
+ condition: Callable,
353
+ ) -> None:
354
+ """
355
+ EXPERIMENTAL
356
+
357
+ When simulating on a statevector simulator, emulate the behavior of postprocessing
358
+ by discarding amplitudes for which their states are "undesirable".
359
+
360
+ Args:
361
+ output_name: The name of the register to filter
362
+ condition: Filter out values of the statevector for which this callable is False
363
+ """
364
+ if self._session_id is not None:
365
+ raise ClassiqError(
366
+ "set_measured_state_filter must be called before use of the first primitive (sample, estimate...)"
367
+ )
368
+
369
+ if output_name not in self.program.model.circuit_outputs:
370
+ raise ClassiqValueError(f"{output_name} is not an output of the model")
371
+ output_type = self.program.model.circuit_output_types[output_name].quantum_types
372
+
373
+ legal_bitstrings = []
374
+
375
+ if isinstance(output_type, QuantumBit):
376
+ if condition(0):
377
+ legal_bitstrings.append("0")
378
+ if condition(1):
379
+ legal_bitstrings.append("1")
380
+ elif isinstance(output_type, QuantumNumeric):
381
+ size = output_type.size_in_bits
382
+ for i in range(2**size):
383
+ number_string = f"{i:0{size}b}"
384
+ val = number_utils.binary_to_float_or_int(
385
+ number_string,
386
+ output_type.fraction_digits_value,
387
+ output_type.sign_value,
388
+ )
389
+ if condition(val):
390
+ legal_bitstrings.append(number_string)
391
+ if len(legal_bitstrings) > 1:
392
+ raise NotImplementedError(
393
+ "Filtering is only supported on a single value per model output"
394
+ )
395
+ else:
396
+ raise NotImplementedError(
397
+ "Filtering is only supported on QuantumBit and QuantumNumeric"
398
+ )
399
+
400
+ self.program.model.register_filter_bitstrings[output_name] = legal_bitstrings
@@ -0,0 +1,63 @@
1
+ import time
2
+ import webbrowser
3
+
4
+ from classiq.interface.exceptions import ClassiqError
5
+ from classiq.interface.execution.iqcc import IQCCInitAuthData, IQCCProbeAuthData
6
+
7
+ from classiq._internals.api_wrapper import ApiWrapper
8
+ from classiq._internals.async_utils import syncify_function
9
+
10
+
11
+ async def generate_iqcc_token_async(
12
+ auth_scope_id: str,
13
+ auth_method_id: str,
14
+ timeout: float = 120,
15
+ probe_interval: float = 1,
16
+ print_auth_url: bool = True,
17
+ ) -> str:
18
+ """Interactively generate a token for use in IQCC backends.
19
+
20
+ Args:
21
+ auth_scope_id: The ID of the IQCC Boundary authentication scope.
22
+ auth_method_id: The ID of the IQCC Boundary authentication method.
23
+ timeout: Number of seconds to wait for the interactive authentication to complete.
24
+ probe_interval: Number of seconds to wait between probes of the authentication.
25
+ print_auth_url: Whether to print the authentication URL, useful for headless machines with no browser.
26
+
27
+ Returns:
28
+ The authentication token string to use directly in `IQCCBackendPreferences`.
29
+
30
+ Raises:
31
+ ClassiqError: In case timeout has reached before a successful authentication.
32
+ """
33
+ initiate_response = await ApiWrapper().call_iqcc_init_auth(
34
+ IQCCInitAuthData(auth_scope_id=auth_scope_id, auth_method_id=auth_method_id)
35
+ )
36
+
37
+ if print_auth_url:
38
+ print("Please proceed with authentication on your web browser.") # noqa: T201
39
+ print("If no window has opened, use this link to authenticate:") # noqa: T201
40
+ print(initiate_response.auth_url) # noqa: T201
41
+
42
+ webbrowser.open_new_tab(initiate_response.auth_url)
43
+
44
+ start_time = time.monotonic()
45
+ while True:
46
+ time.sleep(probe_interval)
47
+ probe_response = await ApiWrapper().call_iqcc_probe_auth(
48
+ IQCCProbeAuthData(
49
+ auth_scope_id=auth_scope_id,
50
+ auth_method_id=auth_method_id,
51
+ token_id=initiate_response.token_id,
52
+ )
53
+ )
54
+ if probe_response is not None:
55
+ return probe_response.auth_token
56
+
57
+ if time.monotonic() - start_time > timeout:
58
+ raise ClassiqError(
59
+ f"Timeout has reached while probing IQCC authentication. Please try again and make sure to authenticate within {timeout} seconds, or increase the timeout."
60
+ )
61
+
62
+
63
+ generate_iqcc_token = syncify_function(generate_iqcc_token_async)