classiq 0.37.1__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 (516) hide show
  1. classiq/__init__.py +49 -34
  2. classiq/_analyzer_extras/_ipywidgets_async_extension.py +3 -2
  3. classiq/_analyzer_extras/interactive_hardware.py +3 -3
  4. classiq/_internals/api_wrapper.py +241 -95
  5. classiq/_internals/async_utils.py +2 -77
  6. classiq/_internals/authentication/auth0.py +26 -10
  7. classiq/_internals/authentication/authentication.py +11 -0
  8. classiq/_internals/authentication/device.py +18 -8
  9. classiq/_internals/authentication/password_manager.py +40 -13
  10. classiq/_internals/authentication/token_manager.py +11 -6
  11. classiq/_internals/client.py +106 -37
  12. classiq/_internals/config.py +3 -4
  13. classiq/_internals/host_checker.py +38 -15
  14. classiq/_internals/jobs.py +56 -50
  15. classiq/_internals/type_validation.py +9 -9
  16. classiq/analyzer/__init__.py +1 -3
  17. classiq/analyzer/analyzer.py +50 -47
  18. classiq/analyzer/analyzer_utilities.py +15 -15
  19. classiq/analyzer/rb.py +19 -20
  20. classiq/analyzer/show_interactive_hack.py +30 -7
  21. classiq/analyzer/url_utils.py +2 -3
  22. classiq/applications/__init__.py +3 -12
  23. classiq/applications/chemistry/__init__.py +14 -10
  24. classiq/applications/chemistry/ansatz_parameters.py +4 -4
  25. classiq/{applications_model_constructors → applications/chemistry}/chemistry_model_constructor.py +170 -170
  26. classiq/applications/chemistry/ground_state_problem.py +1 -1
  27. classiq/applications/combinatorial_helpers/allowed_constraints.py +23 -0
  28. classiq/applications/combinatorial_helpers/arithmetic/arithmetic_expression.py +35 -0
  29. classiq/applications/combinatorial_helpers/arithmetic/isolation.py +42 -0
  30. classiq/applications/combinatorial_helpers/combinatorial_problem_utils.py +166 -0
  31. classiq/applications/combinatorial_helpers/encoding_mapping.py +107 -0
  32. classiq/applications/combinatorial_helpers/encoding_utils.py +124 -0
  33. classiq/applications/combinatorial_helpers/memory.py +75 -0
  34. classiq/applications/combinatorial_helpers/optimization_model.py +193 -0
  35. classiq/applications/combinatorial_helpers/pauli_helpers/pauli_sparsing.py +31 -0
  36. classiq/applications/combinatorial_helpers/pauli_helpers/pauli_utils.py +46 -0
  37. classiq/applications/combinatorial_helpers/pyomo_utils.py +447 -0
  38. classiq/applications/combinatorial_helpers/sympy_utils.py +22 -0
  39. classiq/applications/combinatorial_helpers/transformations/encoding.py +189 -0
  40. classiq/applications/combinatorial_helpers/transformations/fixed_variables.py +143 -0
  41. classiq/applications/combinatorial_helpers/transformations/ising_converter.py +120 -0
  42. classiq/applications/combinatorial_helpers/transformations/penalty.py +31 -0
  43. classiq/applications/combinatorial_helpers/transformations/penalty_support.py +37 -0
  44. classiq/applications/combinatorial_helpers/transformations/sign_seperation.py +74 -0
  45. classiq/applications/combinatorial_helpers/transformations/slack_variables.py +87 -0
  46. classiq/applications/combinatorial_optimization/__init__.py +24 -5
  47. classiq/applications/combinatorial_optimization/combinatorial_optimization_config.py +2 -2
  48. classiq/applications/combinatorial_optimization/combinatorial_optimization_model_constructor.py +137 -0
  49. classiq/applications/combinatorial_optimization/combinatorial_problem.py +229 -0
  50. classiq/applications/combinatorial_optimization/examples/__init__.py +1 -3
  51. classiq/applications/finance/__init__.py +4 -5
  52. classiq/{applications_model_constructors → applications/finance}/finance_model_constructor.py +50 -57
  53. classiq/applications/grover/__init__.py +9 -0
  54. classiq/applications/grover/grover_model_constructor.py +157 -0
  55. classiq/applications/hamiltonian/__init__.py +0 -0
  56. classiq/applications/hamiltonian/pauli_decomposition.py +113 -0
  57. classiq/applications/libraries/__init__.py +0 -0
  58. classiq/applications/libraries/qmci_library.py +22 -0
  59. classiq/applications/qnn/__init__.py +2 -4
  60. classiq/applications/qnn/circuit_utils.py +8 -8
  61. classiq/applications/qnn/datasets/__init__.py +9 -11
  62. classiq/applications/qnn/datasets/dataset_base_classes.py +7 -5
  63. classiq/applications/qnn/datasets/dataset_not.py +2 -1
  64. classiq/applications/qnn/datasets/dataset_parity.py +2 -2
  65. classiq/applications/qnn/gradients/quantum_gradient.py +2 -2
  66. classiq/applications/qnn/gradients/simple_quantum_gradient.py +2 -1
  67. classiq/applications/qnn/qlayer.py +30 -10
  68. classiq/applications/qnn/torch_utils.py +4 -3
  69. classiq/applications/qnn/types.py +7 -7
  70. classiq/applications/qsvm/__init__.py +6 -4
  71. classiq/applications/qsvm/qsvm.py +4 -10
  72. classiq/applications/qsvm/qsvm_data_generation.py +5 -8
  73. classiq/{applications_model_constructors → applications/qsvm}/qsvm_model_constructor.py +30 -28
  74. classiq/execution/__init__.py +8 -3
  75. classiq/execution/all_hardware_devices.py +11 -0
  76. classiq/execution/execution_session.py +400 -0
  77. classiq/execution/iqcc.py +63 -0
  78. classiq/execution/jobs.py +197 -25
  79. classiq/execution/qnn.py +79 -0
  80. classiq/executor.py +23 -117
  81. classiq/interface/_version.py +1 -1
  82. classiq/interface/analyzer/analysis_params.py +49 -16
  83. classiq/interface/analyzer/cytoscape_graph.py +15 -9
  84. classiq/interface/analyzer/result.py +36 -32
  85. classiq/interface/applications/qsvm.py +28 -25
  86. classiq/interface/ast_node.py +16 -0
  87. classiq/interface/backend/backend_preferences.py +390 -119
  88. classiq/interface/backend/ionq/ionq_quantum_program.py +15 -23
  89. classiq/interface/backend/pydantic_backend.py +27 -22
  90. classiq/interface/backend/quantum_backend_providers.py +70 -16
  91. classiq/interface/chemistry/fermionic_operator.py +43 -32
  92. classiq/interface/chemistry/ground_state_problem.py +42 -24
  93. classiq/interface/chemistry/molecule.py +20 -14
  94. classiq/interface/chemistry/operator.py +75 -236
  95. classiq/interface/combinatorial_optimization/encoding_types.py +1 -1
  96. classiq/interface/combinatorial_optimization/examples/ascending_sequence.py +2 -4
  97. classiq/interface/combinatorial_optimization/examples/greater_than_ilp.py +1 -1
  98. classiq/interface/combinatorial_optimization/examples/ilp.py +2 -1
  99. classiq/interface/combinatorial_optimization/examples/integer_portfolio_optimization.py +2 -4
  100. classiq/interface/combinatorial_optimization/examples/knapsack.py +3 -3
  101. classiq/interface/combinatorial_optimization/examples/mds.py +2 -1
  102. classiq/interface/combinatorial_optimization/examples/mht.py +10 -6
  103. classiq/interface/combinatorial_optimization/examples/mis.py +4 -1
  104. classiq/interface/combinatorial_optimization/examples/mvc.py +2 -1
  105. classiq/interface/combinatorial_optimization/examples/portfolio_variations.py +2 -2
  106. classiq/interface/combinatorial_optimization/examples/set_cover.py +3 -3
  107. classiq/interface/combinatorial_optimization/examples/tsp.py +4 -3
  108. classiq/interface/combinatorial_optimization/examples/tsp_digraph.py +6 -2
  109. classiq/interface/combinatorial_optimization/mht_qaoa_input.py +14 -9
  110. classiq/interface/combinatorial_optimization/optimization_problem.py +2 -2
  111. classiq/interface/combinatorial_optimization/result.py +1 -3
  112. classiq/interface/combinatorial_optimization/solver_types.py +1 -1
  113. classiq/interface/debug_info/__init__.py +0 -0
  114. classiq/interface/debug_info/debug_info.py +86 -0
  115. classiq/interface/exceptions.py +201 -0
  116. classiq/interface/execution/iqcc.py +19 -0
  117. classiq/interface/execution/jobs.py +15 -12
  118. classiq/interface/execution/primitives.py +18 -0
  119. classiq/interface/executor/constants.py +1 -0
  120. classiq/interface/executor/estimation.py +2 -2
  121. classiq/interface/executor/execution_preferences.py +26 -143
  122. classiq/interface/executor/execution_request.py +36 -56
  123. classiq/interface/executor/execution_result.py +30 -8
  124. classiq/interface/executor/iqae_result.py +4 -6
  125. classiq/interface/executor/optimizer_preferences.py +34 -22
  126. classiq/interface/executor/{quantum_program.py → quantum_code.py} +44 -34
  127. classiq/interface/executor/quantum_instruction_set.py +3 -2
  128. classiq/interface/executor/register_initialization.py +12 -17
  129. classiq/interface/executor/result.py +122 -64
  130. classiq/interface/executor/vqe_result.py +11 -11
  131. classiq/interface/finance/function_input.py +42 -19
  132. classiq/interface/finance/gaussian_model_input.py +7 -5
  133. classiq/interface/finance/log_normal_model_input.py +6 -4
  134. classiq/interface/finance/model_input.py +6 -4
  135. classiq/interface/generator/adjacency.py +1 -3
  136. classiq/interface/generator/amplitude_loading.py +27 -14
  137. classiq/interface/generator/ansatz_library.py +5 -5
  138. classiq/interface/generator/application_apis/__init__.py +1 -0
  139. classiq/interface/generator/application_apis/arithmetic_declarations.py +17 -0
  140. classiq/interface/generator/application_apis/chemistry_declarations.py +27 -187
  141. classiq/interface/generator/application_apis/combinatorial_optimization_declarations.py +18 -21
  142. classiq/interface/generator/application_apis/entangler_declarations.py +11 -6
  143. classiq/interface/generator/application_apis/finance_declarations.py +48 -69
  144. classiq/interface/generator/application_apis/qsvm_declarations.py +0 -70
  145. classiq/interface/generator/arith/argument_utils.py +57 -6
  146. classiq/interface/generator/arith/arithmetic.py +37 -16
  147. classiq/interface/generator/arith/arithmetic_arg_type_validator.py +15 -17
  148. classiq/interface/generator/arith/arithmetic_expression_abc.py +70 -26
  149. classiq/interface/generator/arith/arithmetic_expression_parser.py +18 -12
  150. classiq/interface/generator/arith/arithmetic_expression_validator.py +61 -43
  151. classiq/interface/generator/arith/arithmetic_operations.py +19 -16
  152. classiq/interface/generator/arith/arithmetic_param_getters.py +7 -8
  153. classiq/interface/generator/arith/arithmetic_result_builder.py +21 -17
  154. classiq/interface/generator/arith/ast_node_rewrite.py +4 -3
  155. classiq/interface/generator/arith/binary_ops.py +375 -139
  156. classiq/interface/generator/arith/endianness.py +1 -1
  157. classiq/interface/generator/arith/extremum_operations.py +96 -23
  158. classiq/interface/generator/arith/logical_ops.py +16 -12
  159. classiq/interface/generator/arith/machine_precision.py +3 -0
  160. classiq/interface/generator/arith/number_utils.py +44 -48
  161. classiq/interface/generator/arith/register_user_input.py +70 -27
  162. classiq/interface/generator/arith/unary_ops.py +57 -46
  163. classiq/interface/generator/arith/uncomputation_methods.py +1 -1
  164. classiq/interface/generator/builtin_api_builder.py +2 -9
  165. classiq/interface/generator/chemistry_function_params.py +5 -5
  166. classiq/interface/generator/circuit_code/circuit_code.py +7 -7
  167. classiq/interface/generator/circuit_code/types_and_constants.py +4 -7
  168. classiq/interface/generator/commuting_pauli_exponentiation.py +8 -6
  169. classiq/interface/generator/compiler_keywords.py +8 -0
  170. classiq/interface/generator/complex_type.py +13 -25
  171. classiq/interface/generator/constant.py +3 -4
  172. classiq/interface/generator/control_state.py +35 -28
  173. classiq/interface/generator/copy.py +47 -0
  174. classiq/interface/generator/custom_ansatz.py +2 -5
  175. classiq/interface/generator/distance.py +3 -5
  176. classiq/interface/generator/excitations.py +3 -2
  177. classiq/interface/generator/expressions/atomic_expression_functions.py +26 -8
  178. classiq/interface/generator/expressions/enums/__init__.py +0 -10
  179. classiq/interface/generator/expressions/enums/finance_functions.py +12 -22
  180. classiq/interface/generator/expressions/evaluated_expression.py +21 -7
  181. classiq/interface/generator/expressions/expression.py +27 -15
  182. classiq/interface/generator/expressions/expression_constants.py +9 -3
  183. classiq/interface/generator/expressions/non_symbolic_expr.py +119 -0
  184. classiq/interface/generator/expressions/qmod_qarray_proxy.py +99 -0
  185. classiq/interface/generator/expressions/qmod_qscalar_proxy.py +59 -0
  186. classiq/interface/generator/expressions/qmod_qstruct_proxy.py +36 -0
  187. classiq/interface/generator/expressions/qmod_sized_proxy.py +30 -2
  188. classiq/interface/generator/expressions/qmod_struct_instance.py +14 -2
  189. classiq/interface/generator/expressions/sympy_supported_expressions.py +20 -11
  190. classiq/interface/generator/finance.py +3 -3
  191. classiq/interface/generator/function_param_library.py +6 -6
  192. classiq/interface/generator/function_param_list_without_self_reference.py +2 -10
  193. classiq/interface/generator/function_params.py +42 -69
  194. classiq/interface/generator/functions/__init__.py +0 -22
  195. classiq/interface/generator/functions/builtins/__init__.py +0 -0
  196. classiq/interface/generator/functions/builtins/internal_operators.py +16 -0
  197. classiq/interface/generator/functions/classical_function_declaration.py +18 -9
  198. classiq/interface/generator/functions/classical_type.py +47 -166
  199. classiq/interface/generator/functions/concrete_types.py +55 -0
  200. classiq/interface/generator/functions/function_declaration.py +13 -14
  201. classiq/interface/generator/functions/port_declaration.py +1 -13
  202. classiq/interface/generator/functions/qmod_python_interface.py +2 -1
  203. classiq/interface/generator/functions/type_name.py +90 -0
  204. classiq/interface/generator/generated_circuit_data.py +155 -22
  205. classiq/interface/generator/grover_diffuser.py +32 -25
  206. classiq/interface/generator/grover_operator.py +34 -23
  207. classiq/interface/generator/hamiltonian_evolution/exponentiation.py +4 -6
  208. classiq/interface/generator/hamiltonian_evolution/qdrift.py +4 -4
  209. classiq/interface/generator/hamiltonian_evolution/suzuki_trotter.py +12 -8
  210. classiq/interface/generator/hardware/hardware_data.py +76 -36
  211. classiq/interface/generator/hardware_efficient_ansatz.py +38 -17
  212. classiq/interface/generator/hartree_fock.py +14 -4
  213. classiq/interface/generator/identity.py +10 -6
  214. classiq/interface/generator/linear_pauli_rotations.py +33 -19
  215. classiq/interface/generator/mcmt_method.py +1 -1
  216. classiq/interface/generator/mcu.py +20 -16
  217. classiq/interface/generator/mcx.py +29 -20
  218. classiq/interface/generator/model/__init__.py +2 -5
  219. classiq/interface/generator/model/constraints.py +27 -8
  220. classiq/interface/generator/model/model.py +32 -203
  221. classiq/interface/generator/model/preferences/preferences.py +118 -43
  222. classiq/{quantum_register.py → interface/generator/model/quantum_register.py} +27 -22
  223. classiq/interface/generator/oracles/arithmetic_oracle.py +2 -4
  224. classiq/interface/generator/oracles/custom_oracle.py +17 -13
  225. classiq/interface/generator/oracles/oracle_abc.py +9 -9
  226. classiq/interface/generator/partitioned_register.py +7 -7
  227. classiq/interface/generator/piecewise_linear_amplitude_loading.py +45 -29
  228. classiq/interface/generator/preferences/optimization.py +1 -2
  229. classiq/interface/generator/qpe.py +47 -34
  230. classiq/interface/generator/qsvm.py +13 -17
  231. classiq/interface/generator/quantum_function_call.py +107 -87
  232. classiq/interface/generator/{generated_circuit.py → quantum_program.py} +50 -37
  233. classiq/interface/generator/range_types.py +13 -12
  234. classiq/interface/generator/register_role.py +18 -6
  235. classiq/interface/generator/slice_parsing_utils.py +11 -6
  236. classiq/interface/generator/standard_gates/controlled_standard_gates.py +32 -39
  237. classiq/interface/generator/standard_gates/standard_angle_metaclass.py +2 -6
  238. classiq/interface/generator/standard_gates/standard_gates.py +3 -3
  239. classiq/interface/generator/standard_gates/u_gate.py +7 -10
  240. classiq/interface/generator/state_preparation/bell_state_preparation.py +3 -3
  241. classiq/interface/generator/state_preparation/computational_basis_state_preparation.py +2 -1
  242. classiq/interface/generator/state_preparation/distributions.py +16 -15
  243. classiq/interface/generator/state_preparation/metrics.py +5 -7
  244. classiq/interface/generator/state_preparation/state_preparation.py +30 -23
  245. classiq/interface/generator/synthesis_metadata/synthesis_duration.py +0 -4
  246. classiq/interface/generator/synthesis_metadata/synthesis_execution_data.py +20 -6
  247. classiq/interface/generator/transpiler_basis_gates.py +7 -3
  248. classiq/interface/generator/types/builtin_enum_declarations.py +178 -0
  249. classiq/interface/generator/types/compilation_metadata.py +6 -0
  250. classiq/interface/generator/types/enum_declaration.py +54 -0
  251. classiq/interface/generator/types/qstruct_declaration.py +18 -0
  252. classiq/interface/generator/types/struct_declaration.py +15 -14
  253. classiq/interface/generator/ucc.py +9 -6
  254. classiq/interface/generator/unitary_gate.py +10 -6
  255. classiq/interface/generator/user_defined_function_params.py +4 -1
  256. classiq/interface/generator/validations/flow_graph.py +11 -9
  257. classiq/interface/generator/validations/validator_functions.py +8 -6
  258. classiq/interface/generator/visitor.py +23 -16
  259. classiq/interface/hardware.py +31 -10
  260. classiq/interface/helpers/classproperty.py +8 -0
  261. classiq/interface/helpers/custom_encoders.py +3 -0
  262. classiq/interface/helpers/custom_pydantic_types.py +40 -50
  263. classiq/interface/helpers/datastructures.py +26 -0
  264. classiq/interface/helpers/hashable_mixin.py +3 -2
  265. classiq/interface/helpers/hashable_pydantic_base_model.py +2 -1
  266. classiq/interface/helpers/pydantic_model_helpers.py +7 -11
  267. classiq/interface/helpers/validation_helpers.py +4 -21
  268. classiq/interface/helpers/versioned_model.py +1 -1
  269. classiq/interface/ide/ide_data.py +16 -20
  270. classiq/interface/ide/visual_model.py +130 -0
  271. classiq/interface/interface_version.py +1 -0
  272. classiq/interface/jobs.py +35 -6
  273. classiq/interface/model/allocate.py +16 -0
  274. classiq/interface/model/bind_operation.py +44 -14
  275. classiq/interface/model/classical_if.py +15 -0
  276. classiq/interface/model/classical_parameter_declaration.py +33 -3
  277. classiq/interface/model/control.py +45 -0
  278. classiq/interface/model/handle_binding.py +298 -20
  279. classiq/interface/model/inplace_binary_operation.py +31 -26
  280. classiq/interface/model/invert.py +12 -0
  281. classiq/interface/model/model.py +87 -73
  282. classiq/interface/model/native_function_definition.py +16 -21
  283. classiq/interface/model/parameter.py +13 -0
  284. classiq/interface/model/phase_operation.py +11 -0
  285. classiq/interface/model/port_declaration.py +27 -9
  286. classiq/interface/model/power.py +14 -0
  287. classiq/interface/model/quantum_expressions/amplitude_loading_operation.py +38 -21
  288. classiq/interface/model/quantum_expressions/arithmetic_operation.py +51 -14
  289. classiq/interface/model/quantum_expressions/quantum_expression.py +12 -35
  290. classiq/interface/model/quantum_function_call.py +146 -462
  291. classiq/interface/model/quantum_function_declaration.py +193 -152
  292. classiq/interface/model/quantum_lambda_function.py +65 -0
  293. classiq/interface/model/quantum_statement.py +71 -12
  294. classiq/interface/model/quantum_type.py +205 -67
  295. classiq/interface/model/quantum_variable_declaration.py +4 -26
  296. classiq/interface/model/repeat.py +15 -0
  297. classiq/interface/model/statement_block.py +58 -0
  298. classiq/interface/model/validation_handle.py +13 -6
  299. classiq/interface/model/variable_declaration_statement.py +3 -1
  300. classiq/interface/model/within_apply_operation.py +13 -0
  301. classiq/interface/pyomo_extension/pyomo_sympy_bimap.py +4 -1
  302. classiq/interface/server/global_versions.py +6 -7
  303. classiq/interface/server/routes.py +22 -21
  304. classiq/interface/source_reference.py +59 -0
  305. classiq/model_expansions/__init__.py +0 -0
  306. classiq/model_expansions/atomic_expression_functions_defs.py +253 -0
  307. classiq/model_expansions/capturing/__init__.py +0 -0
  308. classiq/model_expansions/capturing/captured_vars.py +435 -0
  309. classiq/model_expansions/capturing/mangling_utils.py +56 -0
  310. classiq/model_expansions/closure.py +171 -0
  311. classiq/model_expansions/debug_flag.py +3 -0
  312. classiq/model_expansions/evaluators/__init__.py +0 -0
  313. classiq/model_expansions/evaluators/arg_type_match.py +158 -0
  314. classiq/model_expansions/evaluators/argument_types.py +42 -0
  315. classiq/model_expansions/evaluators/classical_expression.py +36 -0
  316. classiq/model_expansions/evaluators/control.py +144 -0
  317. classiq/model_expansions/evaluators/parameter_types.py +226 -0
  318. classiq/model_expansions/evaluators/quantum_type_utils.py +239 -0
  319. classiq/model_expansions/evaluators/type_type_match.py +90 -0
  320. classiq/model_expansions/expression_evaluator.py +135 -0
  321. classiq/model_expansions/expression_renamer.py +76 -0
  322. classiq/model_expansions/function_builder.py +247 -0
  323. classiq/model_expansions/generative_functions.py +158 -0
  324. classiq/model_expansions/interpreters/__init__.py +0 -0
  325. classiq/model_expansions/interpreters/base_interpreter.py +263 -0
  326. classiq/model_expansions/interpreters/frontend_generative_interpreter.py +28 -0
  327. classiq/model_expansions/interpreters/generative_interpreter.py +249 -0
  328. classiq/model_expansions/model_tables.py +18 -0
  329. classiq/model_expansions/quantum_operations/__init__.py +9 -0
  330. classiq/model_expansions/quantum_operations/bind.py +60 -0
  331. classiq/model_expansions/quantum_operations/call_emitter.py +266 -0
  332. classiq/model_expansions/quantum_operations/classicalif.py +53 -0
  333. classiq/model_expansions/quantum_operations/declarative_call_emitter.py +87 -0
  334. classiq/model_expansions/quantum_operations/emitter.py +181 -0
  335. classiq/model_expansions/quantum_operations/quantum_function_call.py +33 -0
  336. classiq/model_expansions/quantum_operations/repeat.py +56 -0
  337. classiq/model_expansions/quantum_operations/shallow_emitter.py +180 -0
  338. classiq/model_expansions/quantum_operations/variable_decleration.py +28 -0
  339. classiq/model_expansions/scope.py +240 -0
  340. classiq/model_expansions/scope_initialization.py +150 -0
  341. classiq/model_expansions/sympy_conversion/__init__.py +0 -0
  342. classiq/model_expansions/sympy_conversion/arithmetics.py +49 -0
  343. classiq/model_expansions/sympy_conversion/expression_to_sympy.py +179 -0
  344. classiq/model_expansions/sympy_conversion/sympy_to_python.py +123 -0
  345. classiq/model_expansions/transformers/__init__.py +0 -0
  346. classiq/model_expansions/transformers/ast_renamer.py +26 -0
  347. classiq/model_expansions/transformers/var_splitter.py +299 -0
  348. classiq/model_expansions/utils/__init__.py +0 -0
  349. classiq/model_expansions/utils/counted_name_allocator.py +11 -0
  350. classiq/model_expansions/utils/handles_collector.py +33 -0
  351. classiq/model_expansions/visitors/__init__.py +0 -0
  352. classiq/model_expansions/visitors/boolean_expression_transformers.py +214 -0
  353. classiq/model_expansions/visitors/variable_references.py +144 -0
  354. classiq/open_library/__init__.py +4 -0
  355. classiq/open_library/functions/__init__.py +130 -0
  356. classiq/open_library/functions/amplitude_estimation.py +30 -0
  357. classiq/open_library/functions/discrete_sine_cosine_transform.py +181 -0
  358. classiq/open_library/functions/grover.py +157 -0
  359. classiq/open_library/functions/hea.py +115 -0
  360. classiq/open_library/functions/linear_pauli_rotation.py +82 -0
  361. classiq/open_library/functions/modular_exponentiation.py +201 -0
  362. classiq/open_library/functions/qaoa_penalty.py +117 -0
  363. classiq/open_library/functions/qft_functions.py +54 -0
  364. classiq/open_library/functions/qpe.py +46 -0
  365. classiq/open_library/functions/qsvt.py +331 -0
  366. classiq/open_library/functions/state_preparation.py +301 -0
  367. classiq/open_library/functions/swap_test.py +27 -0
  368. classiq/open_library/functions/utility_functions.py +81 -0
  369. classiq/open_library/functions/variational.py +52 -0
  370. classiq/qmod/__init__.py +17 -10
  371. classiq/qmod/builtins/__init__.py +19 -2
  372. classiq/qmod/builtins/classical_execution_primitives.py +60 -47
  373. classiq/qmod/builtins/classical_functions.py +44 -38
  374. classiq/qmod/builtins/constants.py +10 -0
  375. classiq/qmod/builtins/enums.py +208 -0
  376. classiq/qmod/builtins/functions/__init__.py +137 -0
  377. classiq/qmod/builtins/functions/allocation.py +150 -0
  378. classiq/qmod/builtins/functions/arithmetic.py +55 -0
  379. classiq/qmod/builtins/functions/benchmarking.py +8 -0
  380. classiq/qmod/builtins/functions/chemistry.py +91 -0
  381. classiq/qmod/builtins/functions/exponentiation.py +105 -0
  382. classiq/qmod/builtins/functions/finance.py +34 -0
  383. classiq/qmod/builtins/functions/operators.py +16 -0
  384. classiq/qmod/builtins/functions/qsvm.py +24 -0
  385. classiq/qmod/builtins/functions/standard_gates.py +651 -0
  386. classiq/qmod/builtins/operations.py +379 -57
  387. classiq/qmod/builtins/structs.py +103 -80
  388. classiq/qmod/cfunc.py +42 -0
  389. classiq/qmod/classical_function.py +8 -20
  390. classiq/qmod/cparam.py +64 -0
  391. classiq/qmod/create_model_function.py +56 -0
  392. classiq/qmod/declaration_inferrer.py +145 -112
  393. classiq/qmod/expression_query.py +39 -0
  394. classiq/qmod/generative.py +42 -0
  395. classiq/qmod/model_state_container.py +19 -5
  396. classiq/qmod/native/__init__.py +7 -0
  397. classiq/qmod/native/expression_to_qmod.py +194 -0
  398. classiq/qmod/native/pretty_printer.py +401 -0
  399. classiq/qmod/pretty_print/__init__.py +7 -0
  400. classiq/qmod/pretty_print/expression_to_python.py +222 -0
  401. classiq/qmod/pretty_print/pretty_printer.py +572 -0
  402. classiq/qmod/python_classical_type.py +67 -0
  403. classiq/qmod/qfunc.py +79 -0
  404. classiq/qmod/qmod_constant.py +143 -0
  405. classiq/qmod/qmod_parameter.py +84 -53
  406. classiq/qmod/qmod_variable.py +497 -100
  407. classiq/qmod/quantum_callable.py +17 -7
  408. classiq/qmod/quantum_expandable.py +278 -105
  409. classiq/qmod/quantum_function.py +232 -48
  410. classiq/qmod/semantics/__init__.py +0 -0
  411. classiq/qmod/semantics/annotation/__init__.py +0 -0
  412. classiq/qmod/semantics/annotation/call_annotation.py +92 -0
  413. classiq/qmod/semantics/annotation/qstruct_annotator.py +23 -0
  414. classiq/qmod/semantics/error_manager.py +88 -0
  415. classiq/qmod/semantics/lambdas.py +25 -0
  416. classiq/qmod/semantics/static_semantics_visitor.py +384 -0
  417. classiq/qmod/semantics/validation/__init__.py +0 -0
  418. classiq/qmod/semantics/validation/constants_validation.py +16 -0
  419. classiq/qmod/semantics/validation/func_call_validation.py +99 -0
  420. classiq/qmod/semantics/validation/function_name_collisions_validation.py +23 -0
  421. classiq/qmod/semantics/validation/handle_validation.py +85 -0
  422. classiq/qmod/semantics/validation/main_validation.py +33 -0
  423. classiq/qmod/semantics/validation/types_validation.py +128 -0
  424. classiq/qmod/symbolic.py +178 -111
  425. classiq/qmod/symbolic_expr.py +36 -12
  426. classiq/qmod/symbolic_type.py +2 -5
  427. classiq/qmod/type_attribute_remover.py +32 -0
  428. classiq/qmod/utilities.py +108 -1
  429. classiq/qmod/write_qmod.py +53 -0
  430. classiq/synthesis.py +210 -22
  431. {classiq-0.37.1.dist-info → classiq-0.65.3.dist-info}/METADATA +16 -8
  432. classiq-0.65.3.dist-info/RECORD +521 -0
  433. {classiq-0.37.1.dist-info → classiq-0.65.3.dist-info}/WHEEL +1 -1
  434. classiq/_internals/_qfunc_ext.py +0 -6
  435. classiq/applications/benchmarking/__init__.py +0 -9
  436. classiq/applications/benchmarking/mirror_benchmarking.py +0 -67
  437. classiq/applications/numpy_utils.py +0 -37
  438. classiq/applications_model_constructors/__init__.py +0 -17
  439. classiq/applications_model_constructors/combinatorial_optimization_model_constructor.py +0 -178
  440. classiq/applications_model_constructors/grover_model_constructor.py +0 -227
  441. classiq/applications_model_constructors/libraries/ampltitude_estimation_library.py +0 -11
  442. classiq/applications_model_constructors/libraries/qmci_library.py +0 -109
  443. classiq/builtin_functions/__init__.py +0 -43
  444. classiq/builtin_functions/amplitude_loading.py +0 -3
  445. classiq/builtin_functions/binary_ops.py +0 -1
  446. classiq/builtin_functions/exponentiation.py +0 -5
  447. classiq/builtin_functions/qpe.py +0 -4
  448. classiq/builtin_functions/qsvm.py +0 -7
  449. classiq/builtin_functions/range_types.py +0 -5
  450. classiq/builtin_functions/standard_gates.py +0 -1
  451. classiq/builtin_functions/state_preparation.py +0 -6
  452. classiq/builtin_functions/suzuki_trotter.py +0 -3
  453. classiq/exceptions.py +0 -131
  454. classiq/interface/executor/aws_execution_cost.py +0 -72
  455. classiq/interface/executor/error_mitigation.py +0 -6
  456. classiq/interface/generator/credit_risk_example/linear_gci.py +0 -115
  457. classiq/interface/generator/credit_risk_example/weighted_adder.py +0 -59
  458. classiq/interface/generator/expressions/enums/chemistry.py +0 -28
  459. classiq/interface/generator/expressions/enums/classical_enum.py +0 -5
  460. classiq/interface/generator/expressions/enums/ladder_operator.py +0 -16
  461. classiq/interface/generator/expressions/enums/optimizers.py +0 -9
  462. classiq/interface/generator/expressions/enums/pauli.py +0 -8
  463. classiq/interface/generator/expressions/enums/qsvm_feature_map_entanglement.py +0 -9
  464. classiq/interface/generator/expressions/qmod_qnum_proxy.py +0 -22
  465. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/__init__.py +0 -18
  466. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/atomic_quantum_functions.py +0 -641
  467. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/exponentiation_functions.py +0 -89
  468. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/std_lib_functions.py +0 -862
  469. classiq/interface/generator/functions/core_lib_declarations/quantum_operators.py +0 -169
  470. classiq/interface/generator/functions/foreign_function_definition.py +0 -106
  471. classiq/interface/generator/functions/function_implementation.py +0 -103
  472. classiq/interface/generator/functions/native_function_definition.py +0 -153
  473. classiq/interface/generator/functions/quantum_function_declaration.py +0 -69
  474. classiq/interface/generator/functions/register.py +0 -42
  475. classiq/interface/generator/functions/register_mapping_data.py +0 -102
  476. classiq/interface/generator/inequality_mixer.py +0 -51
  477. classiq/interface/generator/model/classical_main_validator.py +0 -106
  478. classiq/interface/generator/range_mixer.py +0 -56
  479. classiq/interface/generator/state_propagator.py +0 -63
  480. classiq/interface/generator/types/builtin_struct_declarations/__init__.py +0 -2
  481. classiq/interface/generator/types/builtin_struct_declarations/pauli_struct_declarations.py +0 -22
  482. classiq/interface/generator/types/builtin_struct_declarations/qaoa_declarations.py +0 -23
  483. classiq/interface/generator/types/combinatorial_problem.py +0 -26
  484. classiq/interface/ide/show.py +0 -34
  485. classiq/interface/model/common_model_types.py +0 -23
  486. classiq/interface/model/numeric_reinterpretation.py +0 -25
  487. classiq/interface/model/operator_synthesis_data.py +0 -48
  488. classiq/interface/model/quantum_expressions/control_state.py +0 -38
  489. classiq/interface/model/quantum_if_operation.py +0 -95
  490. classiq/interface/model/resolvers/function_call_resolver.py +0 -43
  491. classiq/interface/model/validations/handle_validation_base.py +0 -55
  492. classiq/interface/model/validations/handles_validator.py +0 -154
  493. classiq/interface/model/validations/port_to_wire_name_generator.py +0 -12
  494. classiq/model/__init__.py +0 -14
  495. classiq/model/composite_function_generator.py +0 -33
  496. classiq/model/function_handler.py +0 -466
  497. classiq/model/function_handler.pyi +0 -152
  498. classiq/model/logic_flow.py +0 -149
  499. classiq/model/logic_flow_change_handler.py +0 -71
  500. classiq/model/model.py +0 -246
  501. classiq/qmod/builtins/functions.py +0 -896
  502. classiq/qmod/qmod_struct.py +0 -37
  503. classiq/quantum_functions/__init__.py +0 -17
  504. classiq/quantum_functions/annotation_parser.py +0 -207
  505. classiq/quantum_functions/decorators.py +0 -22
  506. classiq/quantum_functions/function_library.py +0 -181
  507. classiq/quantum_functions/function_parser.py +0 -74
  508. classiq/quantum_functions/quantum_function.py +0 -236
  509. classiq-0.37.1.dist-info/RECORD +0 -418
  510. /classiq/{applications_model_constructors/libraries → applications/combinatorial_helpers}/__init__.py +0 -0
  511. /classiq/{interface/generator/credit_risk_example → applications/combinatorial_helpers/arithmetic}/__init__.py +0 -0
  512. /classiq/{interface/generator/functions/core_lib_declarations → applications/combinatorial_helpers/pauli_helpers}/__init__.py +0 -0
  513. /classiq/{interface/generator/functions/core_lib_declarations/quantum_functions/chemistry_functions.py → applications/combinatorial_helpers/py.typed} +0 -0
  514. /classiq/{interface/model/resolvers → applications/combinatorial_helpers/solvers}/__init__.py +0 -0
  515. /classiq/{interface/model/validations → applications/combinatorial_helpers/transformations}/__init__.py +0 -0
  516. /classiq/{_internals → interface}/enum_utils.py +0 -0
@@ -1,8 +1,10 @@
1
- from typing import List, Literal, Union
1
+ from typing import Literal, Union
2
2
 
3
3
  import pydantic
4
+ from pydantic import ConfigDict
4
5
 
5
6
  from classiq.interface.chemistry.elements import ELEMENTS
7
+ from classiq.interface.exceptions import ClassiqValueError
6
8
  from classiq.interface.helpers.custom_pydantic_types import AtomType
7
9
  from classiq.interface.helpers.hashable_pydantic_base_model import (
8
10
  HashablePydanticBaseModel,
@@ -17,9 +19,9 @@ class Atom(HashablePydanticBaseModel):
17
19
 
18
20
 
19
21
  class Molecule(HashablePydanticBaseModel):
20
- atoms: List[Atom] = pydantic.Field(
22
+ atoms: list[Atom] = pydantic.Field(
21
23
  description="A list of atoms each containing the atoms symbol and its (x,y,z) location",
22
- min_items=1,
24
+ min_length=1,
23
25
  )
24
26
  spin: pydantic.NonNegativeInt = pydantic.Field(
25
27
  default=1, description="spin of the molecule"
@@ -29,37 +31,41 @@ class Molecule(HashablePydanticBaseModel):
29
31
  )
30
32
 
31
33
  @property
32
- def atoms_type(self) -> List[AtomType]:
34
+ def atoms_type(self) -> list[AtomType]:
33
35
  return [(atom.symbol, [atom.x, atom.y, atom.z]) for atom in self.atoms]
34
36
 
35
- @pydantic.validator("atoms", each_item=True, pre=True)
36
- def _validate_atoms(cls, atom: Union[AtomType, Atom]) -> Atom:
37
+ @classmethod
38
+ def _validate_atom(cls, atom: Union[AtomType, Atom]) -> Atom:
37
39
  if isinstance(atom, (list, tuple)):
38
40
  return cls._validate_old_atoms_type(atom)
39
41
  return atom
40
42
 
43
+ @pydantic.field_validator("atoms", mode="before")
44
+ @classmethod
45
+ def _validate_atoms(cls, atoms: list[Union[AtomType, Atom]]) -> list[Atom]:
46
+ return [cls._validate_atom(atom) for atom in atoms]
47
+
41
48
  @staticmethod
42
49
  def _validate_old_atoms_type(atom: AtomType) -> Atom:
43
50
  if len(atom) != 2:
44
- raise ValueError(
51
+ raise ClassiqValueError(
45
52
  "each atom should be a list of two entries: 1) name pf the elemnt (str) 2) list of its (x,y,z) location"
46
53
  )
47
- if type(atom[0]) is not str:
48
- raise ValueError(
54
+ if not isinstance(atom[0], str):
55
+ raise ClassiqValueError(
49
56
  f"atom name should be a string. unknown element: {atom[0]}."
50
57
  )
51
58
  if len(atom[1]) != 3:
52
- raise ValueError(
59
+ raise ClassiqValueError(
53
60
  f"location of the atom is of length three, representing the (x,y,z) coordinates of the atom, error value: {atom[1]}"
54
61
  )
55
62
  for idx in atom[1]:
56
- if type(idx) is not float and type(idx) is not int:
57
- raise ValueError(
63
+ if not isinstance(idx, (float, int)):
64
+ raise ClassiqValueError(
58
65
  f"coordinates of the atom should be of type float. error value: {idx}"
59
66
  )
60
67
  symbol, coordinate = atom
61
68
 
62
69
  return Atom(symbol=symbol, x=coordinate[0], y=coordinate[1], z=coordinate[2])
63
70
 
64
- class Config:
65
- frozen = True
71
+ model_config = ConfigDict(frozen=True)
@@ -1,18 +1,26 @@
1
+ from collections.abc import Collection
1
2
  from functools import reduce
2
- from typing import Any, Collection, Dict, List, Optional, Tuple, Union, cast
3
+ from typing import (
4
+ Any,
5
+ Optional,
6
+ Union,
7
+ cast,
8
+ )
3
9
 
4
10
  import numpy as np
5
11
  import pydantic
6
12
  import sympy
7
13
  from more_itertools import all_equal
14
+ from pydantic import ConfigDict
8
15
 
9
- from classiq.interface.generator.expressions.enums.pauli import Pauli
16
+ from classiq.interface.exceptions import ClassiqValueError
10
17
  from classiq.interface.generator.function_params import validate_expression_str
11
18
  from classiq.interface.generator.parameters import (
12
19
  ParameterComplexType,
13
20
  ParameterType,
14
21
  PydanticParameterComplexType,
15
22
  )
23
+ from classiq.interface.generator.types.builtin_enum_declarations import Pauli
16
24
  from classiq.interface.helpers.custom_pydantic_types import (
17
25
  PydanticPauliList,
18
26
  PydanticPauliMonomial,
@@ -23,8 +31,6 @@ from classiq.interface.helpers.hashable_pydantic_base_model import (
23
31
  )
24
32
  from classiq.interface.helpers.versioned_model import VersionedModel
25
33
 
26
- from classiq.exceptions import ClassiqValueError
27
-
28
34
 
29
35
  class PauliOperator(HashablePydanticBaseModel, VersionedModel):
30
36
  """
@@ -34,8 +40,8 @@ class PauliOperator(HashablePydanticBaseModel, VersionedModel):
34
40
  pauli_list: PydanticPauliList = pydantic.Field(
35
41
  description="A list of tuples each containing a pauli string comprised of I,X,Y,Z characters and a complex coefficient; for example [('IZ', 0.1), ('XY', 0.2)].",
36
42
  )
37
- is_hermitian: bool = pydantic.Field(default=False)
38
43
  has_complex_coefficients: bool = pydantic.Field(default=True)
44
+ is_hermitian: bool = pydantic.Field(default=False)
39
45
 
40
46
  def show(self) -> str:
41
47
  if self.is_hermitian:
@@ -47,16 +53,19 @@ class PauliOperator(HashablePydanticBaseModel, VersionedModel):
47
53
  f"+({summand[1]:+.3f}) * {summand[0]}" for summand in self.pauli_list
48
54
  )
49
55
 
50
- @pydantic.validator("pauli_list", each_item=True, pre=True)
56
+ @pydantic.field_validator("pauli_list", mode="before")
57
+ @classmethod
51
58
  def _validate_pauli_monomials(
52
- cls, monomial: Tuple[PydanticPauliMonomialStr, ParameterComplexType]
53
- ) -> Tuple[PydanticPauliMonomialStr, ParameterComplexType]:
54
- _PauliMonomialLengthValidator( # type: ignore[call-arg]
55
- monomial=monomial
56
- ) # Validate the length of the monomial.
57
- coeff = cls._validate_monomial_coefficient(monomial[1])
58
- parsed_monomial = _PauliMonomialParser(string=monomial[0], coeff=coeff) # type: ignore[call-arg]
59
- return (parsed_monomial.string, parsed_monomial.coeff)
59
+ cls, pauli_list: PydanticPauliList
60
+ ) -> PydanticPauliList:
61
+ validated_pauli_list = []
62
+ for monomial in pauli_list:
63
+ # Validate the length
64
+ _PauliMonomialLengthValidator(monomial=monomial) # type: ignore[call-arg]
65
+ coeff = cls._validate_monomial_coefficient(monomial[1])
66
+ parsed_monomial = _PauliMonomialParser(string=monomial[0], coeff=coeff)
67
+ validated_pauli_list.append((parsed_monomial.string, parsed_monomial.coeff))
68
+ return validated_pauli_list
60
69
 
61
70
  @staticmethod
62
71
  def _validate_monomial_coefficient(
@@ -68,16 +77,38 @@ class PauliOperator(HashablePydanticBaseModel, VersionedModel):
68
77
  coeff = str(coeff)
69
78
  return coeff
70
79
 
71
- @pydantic.validator("pauli_list")
80
+ @pydantic.field_validator("pauli_list", mode="after")
81
+ @classmethod
72
82
  def _validate_pauli_list(cls, pauli_list: PydanticPauliList) -> PydanticPauliList:
73
83
  if not all_equal(len(summand[0]) for summand in pauli_list):
74
- raise ValueError("Pauli strings have incompatible lengths.")
84
+ raise ClassiqValueError("Pauli strings have incompatible lengths.")
75
85
  return pauli_list
76
86
 
77
- @pydantic.root_validator
78
- def _validate_hermitianity(cls, values: Dict[str, Any]) -> Dict[str, Any]:
87
+ @staticmethod
88
+ def check_if_hermitian(pauli_list: PydanticPauliList) -> bool:
89
+ if all(isinstance(summand[1], (float, int, complex)) for summand in pauli_list):
90
+ if all(np.isclose(summand[1].imag, 0) for summand in pauli_list): # type: ignore[union-attr]
91
+ return True
92
+
93
+ for pauli_string, coeff in pauli_list:
94
+ reverse_string = pauli_string[::-1]
95
+ reverse_found = False
96
+ for other_string, other_coeff in pauli_list:
97
+ if other_string == reverse_string and np.isclose(
98
+ coeff, other_coeff.conjugate() # type: ignore[union-attr]
99
+ ):
100
+ reverse_found = True
101
+ break
102
+ if not reverse_found:
103
+ return False
104
+ return True
105
+ return False
106
+
107
+ @pydantic.model_validator(mode="before")
108
+ @classmethod
109
+ def _validate_hermitianity(cls, values: dict[str, Any]) -> dict[str, Any]:
79
110
  pauli_list = values.get("pauli_list", [])
80
- if all(isinstance(summand[1], complex) for summand in pauli_list):
111
+ if PauliOperator.check_if_hermitian(pauli_list):
81
112
  values["is_hermitian"] = all(
82
113
  np.isclose(complex(summand[1]).real, summand[1])
83
114
  for summand in pauli_list
@@ -85,7 +116,7 @@ class PauliOperator(HashablePydanticBaseModel, VersionedModel):
85
116
  if values.get("is_hermitian", False):
86
117
  values["has_complex_coefficients"] = False
87
118
  values["pauli_list"] = [
88
- (summand[0], complex(summand[1].real)) for summand in pauli_list
119
+ (summand[0], complex(summand[1]).real) for summand in pauli_list
89
120
  ]
90
121
  else:
91
122
  values["has_complex_coefficients"] = not all(
@@ -120,7 +151,7 @@ class PauliOperator(HashablePydanticBaseModel, VersionedModel):
120
151
  )
121
152
 
122
153
  @staticmethod
123
- def _is_sub_pauli_commutative(qubit_pauli_string: Union[List[str], str]) -> bool:
154
+ def _is_sub_pauli_commutative(qubit_pauli_string: Union[list[str], str]) -> bool:
124
155
  unique_paulis = set(qubit_pauli_string) - {"I"}
125
156
  return len(unique_paulis) <= 1
126
157
 
@@ -128,8 +159,12 @@ class PauliOperator(HashablePydanticBaseModel, VersionedModel):
128
159
  def num_qubits(self) -> int:
129
160
  return len(self.pauli_list[0][0])
130
161
 
162
+ @property
163
+ def all_coefficients_numeric(self) -> bool:
164
+ return all(isinstance(summand[1], complex) for summand in self.pauli_list)
165
+
131
166
  def to_matrix(self) -> np.ndarray:
132
- if not all(isinstance(summand[1], complex) for summand in self.pauli_list):
167
+ if not self.all_coefficients_numeric:
133
168
  raise ClassiqValueError(
134
169
  "Supporting only Hamiltonian with numeric coefficients."
135
170
  )
@@ -149,7 +184,7 @@ class PauliOperator(HashablePydanticBaseModel, VersionedModel):
149
184
  (self._extend_pauli_string(pauli_string, num_extra_qubits), coeff)
150
185
  for (pauli_string, coeff) in self.pauli_list
151
186
  ]
152
- return self.copy(update={"pauli_list": new_pauli_list}, deep=True)
187
+ return self.model_copy(update={"pauli_list": new_pauli_list}, deep=True)
153
188
 
154
189
  @staticmethod
155
190
  def _reorder_pauli_string(
@@ -172,16 +207,18 @@ class PauliOperator(HashablePydanticBaseModel, VersionedModel):
172
207
  num_extra_qubits: int,
173
208
  ) -> None:
174
209
  if num_extra_qubits < 0:
175
- raise ValueError("Number of extra qubits cannot be negative")
210
+ raise ClassiqValueError("Number of extra qubits cannot be negative")
176
211
 
177
212
  if len(order) != num_qubits:
178
- raise ValueError("The qubits order doesn't match the Pauli operator")
213
+ raise ClassiqValueError("The qubits order doesn't match the Pauli operator")
179
214
 
180
215
  if len(order) != len(set(order)):
181
- raise ValueError("The qubits order is not one-to-one")
216
+ raise ClassiqValueError("The qubits order is not one-to-one")
182
217
 
183
218
  if not all(pos < num_qubits + num_extra_qubits for pos in order):
184
- raise ValueError("The qubits order contains qubits which do no exist")
219
+ raise ClassiqValueError(
220
+ "The qubits order contains qubits which do no exist"
221
+ )
185
222
 
186
223
  @classmethod
187
224
  def reorder(
@@ -197,217 +234,19 @@ class PauliOperator(HashablePydanticBaseModel, VersionedModel):
197
234
  (cls._reorder_pauli_string(pauli_string, order, new_num_qubits), coeff)
198
235
  for pauli_string, coeff in operator.pauli_list
199
236
  ]
200
- return cls(pauli_list=new_pauli_list)
237
+ return cls(pauli_list=new_pauli_list, is_hermitian=operator.is_hermitian)
201
238
 
202
239
  @classmethod
203
240
  def from_unzipped_lists(
204
241
  cls,
205
- operators: List[List[Pauli]],
206
- coefficients: Optional[List[complex]] = None,
242
+ operators: list[list["Pauli"]],
243
+ coefficients: Optional[list[complex]] = None,
207
244
  ) -> "PauliOperator":
208
245
  if coefficients is None:
209
246
  coefficients = [1] * len(operators)
210
247
 
211
248
  if len(operators) != len(coefficients):
212
- raise ValueError(
213
- f"The number of coefficients ({len(coefficients)}) must be equal to the number of pauli operators ({len(operators)})"
214
- )
215
-
216
- return cls(
217
- pauli_list=[
218
- (pauli_integers_to_str(op), coeff)
219
- for op, coeff in zip(operators, coefficients)
220
- ]
221
- )
222
-
223
- class Config:
224
- frozen = True
225
-
226
-
227
- class PauliOperatorV1(HashablePydanticBaseModel):
228
- """
229
- Specification of a Pauli sum operator.
230
- """
231
-
232
- pauli_list: PydanticPauliList = pydantic.Field(
233
- description="A list of tuples each containing a pauli string comprised of I,X,Y,Z characters and a complex coefficient; for example [('IZ', 0.1), ('XY', 0.2)].",
234
- )
235
- is_hermitian: bool = pydantic.Field(default=False)
236
- has_complex_coefficients: bool = pydantic.Field(default=True)
237
-
238
- def show(self) -> str:
239
- if self.is_hermitian:
240
- # If the operator is hermitian then the coefficients must be numeric
241
- return "\n".join(
242
- f"{summand[1].real:+.3f} * {summand[0]}" for summand in self.pauli_list # type: ignore[union-attr]
243
- )
244
- return "\n".join(
245
- f"+({summand[1]:+.3f}) * {summand[0]}" for summand in self.pauli_list
246
- )
247
-
248
- @pydantic.validator("pauli_list", each_item=True, pre=True)
249
- def _validate_pauli_monomials(
250
- cls, monomial: Tuple[PydanticPauliMonomialStr, ParameterComplexType]
251
- ) -> Tuple[PydanticPauliMonomialStr, ParameterComplexType]:
252
- _PauliMonomialLengthValidator( # type: ignore[call-arg]
253
- monomial=monomial
254
- ) # Validate the length of the monomial.
255
- coeff = cls._validate_monomial_coefficient(monomial[1])
256
- parsed_monomial = _PauliMonomialParser(string=monomial[0], coeff=coeff) # type: ignore[call-arg]
257
- return (parsed_monomial.string, parsed_monomial.coeff)
258
-
259
- @staticmethod
260
- def _validate_monomial_coefficient(
261
- coeff: Union[sympy.Expr, ParameterComplexType]
262
- ) -> ParameterComplexType:
263
- if isinstance(coeff, str):
264
- validate_expression_str(coeff)
265
- elif isinstance(coeff, sympy.Expr):
266
- coeff = str(coeff)
267
- return coeff
268
-
269
- @pydantic.validator("pauli_list")
270
- def _validate_pauli_list(cls, pauli_list: PydanticPauliList) -> PydanticPauliList:
271
- if not all_equal(len(summand[0]) for summand in pauli_list):
272
- raise ValueError("Pauli strings have incompatible lengths.")
273
- return pauli_list
274
-
275
- @pydantic.root_validator
276
- def _validate_hermitianity(cls, values: Dict[str, Any]) -> Dict[str, Any]:
277
- pauli_list = values.get("pauli_list", [])
278
- if all(isinstance(summand[1], complex) for summand in pauli_list):
279
- values["is_hermitian"] = all(
280
- np.isclose(complex(summand[1]).real, summand[1])
281
- for summand in pauli_list
282
- )
283
- if values.get("is_hermitian", False):
284
- values["has_complex_coefficients"] = False
285
- values["pauli_list"] = [
286
- (summand[0], complex(summand[1].real)) for summand in pauli_list
287
- ]
288
- else:
289
- values["has_complex_coefficients"] = not all(
290
- np.isclose(complex(summand[1]).real, summand[1])
291
- for summand in pauli_list
292
- if isinstance(summand[1], complex)
293
- )
294
- return values
295
-
296
- def __mul__(self, coefficient: complex) -> "PauliOperatorV1":
297
- multiplied_ising = [
298
- (monomial[0], self._multiply_monomial_coefficient(monomial[1], coefficient))
299
- for monomial in self.pauli_list
300
- ]
301
- return self.__class__(pauli_list=multiplied_ising)
302
-
303
- @staticmethod
304
- def _multiply_monomial_coefficient(
305
- monomial_coefficient: ParameterComplexType, coefficient: complex
306
- ) -> ParameterComplexType:
307
- if isinstance(monomial_coefficient, ParameterType):
308
- return str(sympy.sympify(monomial_coefficient) * coefficient)
309
- return monomial_coefficient * coefficient
310
-
311
- @property
312
- def is_commutative(self) -> bool:
313
- return all(
314
- self._is_sub_pauli_commutative(
315
- [summand[0][qubit_num] for summand in self.pauli_list]
316
- )
317
- for qubit_num in range(self.num_qubits)
318
- )
319
-
320
- @staticmethod
321
- def _is_sub_pauli_commutative(qubit_pauli_string: Union[List[str], str]) -> bool:
322
- unique_paulis = set(qubit_pauli_string) - {"I"}
323
- return len(unique_paulis) <= 1
324
-
325
- @property
326
- def num_qubits(self) -> int:
327
- return len(self.pauli_list[0][0])
328
-
329
- def to_matrix(self) -> np.ndarray:
330
- if not all(isinstance(summand[1], complex) for summand in self.pauli_list):
331
249
  raise ClassiqValueError(
332
- "Supporting only Hamiltonian with numeric coefficients."
333
- )
334
- return sum(
335
- cast(complex, summand[1]) * to_pauli_matrix(summand[0])
336
- for summand in self.pauli_list
337
- ) # type: ignore[return-value]
338
-
339
- @staticmethod
340
- def _extend_pauli_string(
341
- pauli_string: PydanticPauliMonomialStr, num_extra_qubits: int
342
- ) -> PydanticPauliMonomialStr:
343
- return "I" * num_extra_qubits + pauli_string
344
-
345
- def extend(self, num_extra_qubits: int) -> "PauliOperatorV1":
346
- new_pauli_list = [
347
- (self._extend_pauli_string(pauli_string, num_extra_qubits), coeff)
348
- for (pauli_string, coeff) in self.pauli_list
349
- ]
350
- return self.copy(update={"pauli_list": new_pauli_list}, deep=True)
351
-
352
- @staticmethod
353
- def _reorder_pauli_string(
354
- pauli_string: PydanticPauliMonomialStr,
355
- order: Collection[int],
356
- new_num_qubits: int,
357
- ) -> PydanticPauliMonomialStr:
358
- reversed_pauli_string = pauli_string[::-1]
359
- reversed_new_pauli_string = ["I"] * new_num_qubits
360
-
361
- for logical_pos, actual_pos in enumerate(order):
362
- reversed_new_pauli_string[actual_pos] = reversed_pauli_string[logical_pos]
363
-
364
- return "".join(reversed(reversed_new_pauli_string))
365
-
366
- @staticmethod
367
- def _validate_reorder(
368
- order: Collection[int],
369
- num_qubits: int,
370
- num_extra_qubits: int,
371
- ) -> None:
372
- if num_extra_qubits < 0:
373
- raise ValueError("Number of extra qubits cannot be negative")
374
-
375
- if len(order) != num_qubits:
376
- raise ValueError("The qubits order doesn't match the Pauli operator")
377
-
378
- if len(order) != len(set(order)):
379
- raise ValueError("The qubits order is not one-to-one")
380
-
381
- if not all(pos < num_qubits + num_extra_qubits for pos in order):
382
- raise ValueError("The qubits order contains qubits which do no exist")
383
-
384
- @classmethod
385
- def reorder(
386
- cls,
387
- operator: "PauliOperatorV1",
388
- order: Collection[int],
389
- num_extra_qubits: int = 0,
390
- ) -> "PauliOperatorV1":
391
- cls._validate_reorder(order, operator.num_qubits, num_extra_qubits)
392
-
393
- new_num_qubits = operator.num_qubits + num_extra_qubits
394
- new_pauli_list = [
395
- (cls._reorder_pauli_string(pauli_string, order, new_num_qubits), coeff)
396
- for pauli_string, coeff in operator.pauli_list
397
- ]
398
- return cls(pauli_list=new_pauli_list)
399
-
400
- @classmethod
401
- def from_unzipped_lists(
402
- cls,
403
- operators: List[List[Pauli]],
404
- coefficients: Optional[List[complex]] = None,
405
- ) -> "PauliOperatorV1":
406
- if coefficients is None:
407
- coefficients = [1] * len(operators)
408
-
409
- if len(operators) != len(coefficients):
410
- raise ValueError(
411
250
  f"The number of coefficients ({len(coefficients)}) must be equal to the number of pauli operators ({len(operators)})"
412
251
  )
413
252
 
@@ -418,8 +257,7 @@ class PauliOperatorV1(HashablePydanticBaseModel):
418
257
  ]
419
258
  )
420
259
 
421
- class Config:
422
- frozen = True
260
+ model_config = ConfigDict(frozen=True)
423
261
 
424
262
 
425
263
  # This class validates the length of a monomial.
@@ -428,8 +266,7 @@ class _PauliMonomialLengthValidator:
428
266
  monomial: PydanticPauliMonomial
429
267
 
430
268
 
431
- @pydantic.dataclasses.dataclass
432
- class _PauliMonomialParser:
269
+ class _PauliMonomialParser(pydantic.BaseModel):
433
270
  string: PydanticPauliMonomialStr
434
271
  coeff: PydanticParameterComplexType
435
272
 
@@ -448,7 +285,7 @@ def to_pauli_matrix(pauli_op: PydanticPauliMonomialStr) -> np.ndarray:
448
285
 
449
286
  def validate_operator_is_hermitian(pauli_operator: PauliOperator) -> PauliOperator:
450
287
  if not pauli_operator.is_hermitian:
451
- raise ValueError("Coefficients of the Hamiltonian must be real numbers")
288
+ raise ClassiqValueError("Coefficients of the Hamiltonian must be real numbers")
452
289
  return pauli_operator
453
290
 
454
291
 
@@ -456,13 +293,15 @@ def validate_operator_has_no_complex_coefficients(
456
293
  pauli_operator: PauliOperator,
457
294
  ) -> PauliOperator:
458
295
  if pauli_operator.has_complex_coefficients:
459
- raise ValueError("Coefficients of the Hamiltonian mustn't be complex numbers")
296
+ raise ClassiqValueError(
297
+ "Coefficients of the Hamiltonian mustn't be complex numbers"
298
+ )
460
299
  return pauli_operator
461
300
 
462
301
 
463
- def pauli_integers_to_str(paulis: List[Pauli]) -> str:
302
+ def pauli_integers_to_str(paulis: list[Pauli]) -> str:
464
303
  return "".join([Pauli(pauli).name for pauli in paulis])
465
304
 
466
305
 
467
306
  class PauliOperators(VersionedModel):
468
- operators: List[PauliOperator]
307
+ operators: list[PauliOperator]
@@ -1,4 +1,4 @@
1
- from classiq._internals.enum_utils import StrEnum
1
+ from classiq.interface.enum_utils import StrEnum
2
2
 
3
3
 
4
4
  class EncodingType(StrEnum):
@@ -1,17 +1,15 @@
1
- from typing import List
2
-
3
1
  import numpy as np
4
2
  import pyomo.core as pyo
5
3
 
6
4
 
7
- def ascending_sequence(coeffs: List[int], bound: int) -> pyo.ConcreteModel:
5
+ def ascending_sequence(coeffs: list[int], bound: int) -> pyo.ConcreteModel:
8
6
  model = pyo.ConcreteModel()
9
7
  model.x = pyo.Var(
10
8
  range(len(coeffs)), domain=pyo.NonNegativeIntegers, bounds=(0, bound)
11
9
  )
12
10
 
13
11
  @model.Constraint(range(len(coeffs) - 1))
14
- def monotone_rule(model, idx):
12
+ def monotone_rule(model: pyo.ConcreteModel, idx: int) -> pyo.ExpressionBase:
15
13
  return model.x[idx] <= model.x[idx + 1]
16
14
 
17
15
  model.cost = pyo.Objective(
@@ -19,7 +19,7 @@ def greater_than_ilp(
19
19
  )
20
20
 
21
21
  @model.Constraint(range(num_constraints))
22
- def monotone_rule(model, idx):
22
+ def monotone_rule(model: pyo.ConcreteModel, idx: int) -> pyo.ExpressionBase:
23
23
  return a[idx, :] @ list(model.x.values()) >= float(b[idx])
24
24
 
25
25
  # model objective: max(c * x)
@@ -1,5 +1,6 @@
1
1
  import numpy as np
2
2
  import pyomo.core as pyo
3
+ import pyomo.core.expr.numeric_expr as pyo_expr
3
4
 
4
5
 
5
6
  def ilp(a: np.ndarray, b: np.ndarray, c: np.ndarray, bound: int) -> pyo.ConcreteModel:
@@ -17,7 +18,7 @@ def ilp(a: np.ndarray, b: np.ndarray, c: np.ndarray, bound: int) -> pyo.Concrete
17
18
  )
18
19
 
19
20
  @model.Constraint(range(num_constraints))
20
- def monotone_rule(model, idx):
21
+ def monotone_rule(model: pyo.ConcreteModel, idx: int) -> pyo_expr.ExpressionBase:
21
22
  return a[idx, :] @ list(model.x.values()) <= float(b[idx])
22
23
 
23
24
  # model objective: max(c * x)
@@ -1,16 +1,14 @@
1
- from typing import List
2
-
3
1
  import numpy as np
4
2
  import pyomo.core as pyo
5
3
 
6
4
 
7
5
  def integer_portfolio_optimization(
8
- covariances: np.ndarray, returns: np.ndarray, upper_bounds: List[int]
6
+ covariances: np.ndarray, returns: np.ndarray, upper_bounds: list[int]
9
7
  ) -> pyo.ConcreteModel:
10
8
  model = pyo.ConcreteModel()
11
9
  num_assets = len(returns)
12
10
 
13
- def bounds(_, i):
11
+ def bounds(model: pyo.ConcreteModel, i: int) -> tuple[int, int]:
14
12
  return 0, upper_bounds[i]
15
13
 
16
14
  model.x = pyo.Var(range(num_assets), domain=pyo.NonNegativeIntegers, bounds=bounds)
@@ -1,13 +1,13 @@
1
- from typing import List, Optional
1
+ from typing import Optional
2
2
 
3
3
  import numpy as np
4
4
  import pyomo.core as pyo
5
5
 
6
6
 
7
7
  def knapsack(
8
- values: List[int],
8
+ values: list[int],
9
9
  upper_bound: int,
10
- weights: Optional[List[int]] = None,
10
+ weights: Optional[list[int]] = None,
11
11
  max_weight: Optional[int] = None,
12
12
  ) -> pyo.ConcreteModel:
13
13
  model = pyo.ConcreteModel()
@@ -1,5 +1,6 @@
1
1
  import networkx as nx
2
2
  import pyomo.core as pyo
3
+ import pyomo.core.expr.numeric_expr as pyo_expr
3
4
 
4
5
 
5
6
  def mds(graph: nx.Graph) -> pyo.ConcreteModel:
@@ -7,7 +8,7 @@ def mds(graph: nx.Graph) -> pyo.ConcreteModel:
7
8
  model.x = pyo.Var(graph.nodes, domain=pyo.Binary)
8
9
 
9
10
  @model.Constraint(graph.nodes)
10
- def dominating_rule(model, idx):
11
+ def dominating_rule(model: pyo.ConcreteModel, idx: int) -> pyo_expr.ExpressionBase:
11
12
  sum_of_neighbors = sum(model.x[neighbor] for neighbor in graph.neighbors(idx))
12
13
  return model.x[idx] + sum_of_neighbors >= 1
13
14
 
@@ -1,12 +1,12 @@
1
1
  import math
2
- from typing import Dict, Tuple
3
2
 
4
3
  import networkx as nx
5
4
  import pyomo.core as pyo
5
+ import pyomo.core.expr.numeric_expr as pyo_expr
6
6
 
7
7
  Node = int
8
- Edge = Tuple[Node, Node]
9
- Pubo = Dict[Tuple[Edge, ...], float]
8
+ Edge = tuple[Node, Node]
9
+ Pubo = dict[tuple[Edge, ...], float]
10
10
 
11
11
 
12
12
  def build_mht_pyomo_model(
@@ -22,7 +22,9 @@ def build_mht_pyomo_model(
22
22
  if has_constraints:
23
23
 
24
24
  @model.Constraint(model.Nodes)
25
- def out_edges_rule(model, idx):
25
+ def out_edges_rule(
26
+ model: pyo.ConcreteModel, idx: int
27
+ ) -> pyo_expr.ExpressionBase:
26
28
  out_nodes = [
27
29
  node_id for node_id in model.Nodes if [idx, node_id] in model.Arcs
28
30
  ]
@@ -32,7 +34,9 @@ def build_mht_pyomo_model(
32
34
  return pyo.Constraint.Feasible
33
35
 
34
36
  @model.Constraint(model.Nodes)
35
- def in_edges_rule(model, idx):
37
+ def in_edges_rule(
38
+ model: pyo.ConcreteModel, idx: int
39
+ ) -> pyo_expr.ExpressionBase:
36
40
  in_nodes = [
37
41
  node_id for node_id in model.Nodes if [node_id, idx] in model.Arcs
38
42
  ]
@@ -41,7 +45,7 @@ def build_mht_pyomo_model(
41
45
  else:
42
46
  return pyo.Constraint.Feasible
43
47
 
44
- def obj_expression(model):
48
+ def obj_expression(model: pyo.ConcreteModel) -> pyo_expr.ExpressionBase:
45
49
  return sum(
46
50
  round(pubo_energy, _decimals)
47
51
  * math.prod(model.x[edge] for edge in pubo_edges)