classiq 0.38.0__py3-none-any.whl → 0.65.4__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.4.dist-info}/METADATA +16 -9
  414. classiq-0.65.4.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.4.dist-info}/WHEEL +0 -0
@@ -1,7 +1,7 @@
1
1
  from sympy import Eq, Expr, GreaterThan, LessThan, Rational, Symbol, solve
2
2
  from sympy.core.relational import Relational
3
3
 
4
- from classiq.exceptions import ClassiqCombOptNoSolutionError
4
+ from classiq.interface.exceptions import ClassiqCombOptNoSolutionError
5
5
 
6
6
 
7
7
  def isolate(expression: Expr, var: Symbol) -> Expr:
@@ -1,35 +1,42 @@
1
1
  import itertools
2
- from typing import List, Union
2
+ from functools import partial
3
+ from typing import Callable, Union
3
4
 
4
5
  import numpy as np
5
6
  import pyomo.environ as pyo
6
7
 
7
8
  from classiq.interface.combinatorial_optimization.sense import is_maximization
8
9
  from classiq.interface.combinatorial_optimization.solver_types import QSolver
10
+ from classiq.interface.exceptions import ClassiqValueError
9
11
  from classiq.interface.executor.vqe_result import VQESolverResult
10
12
  from classiq.interface.generator.functions.qmod_python_interface import QmodPyStruct
11
13
 
12
- from classiq.applications_model_constructors.combinatorial_helpers.optimization_model import (
14
+ from classiq.applications.combinatorial_helpers.optimization_model import (
13
15
  OptimizationModel,
14
16
  )
15
- from classiq.applications_model_constructors.combinatorial_helpers.pauli_helpers.pauli_sparsing import (
17
+ from classiq.applications.combinatorial_helpers.pauli_helpers.pauli_sparsing import (
16
18
  SparsePauliOp,
17
19
  )
18
- from classiq.applications_model_constructors.combinatorial_helpers.pauli_helpers.pauli_utils import (
20
+ from classiq.applications.combinatorial_helpers.pauli_helpers.pauli_utils import (
19
21
  pauli_operator_to_hamiltonian,
20
22
  )
21
- from classiq.applications_model_constructors.combinatorial_helpers.pyomo_utils import (
23
+ from classiq.applications.combinatorial_helpers.pyomo_utils import (
24
+ add_var_domain_constraints,
22
25
  convert_pyomo_to_global_presentation,
26
+ evaluate_objective,
27
+ pyomo_to_qmod_qstruct,
23
28
  )
29
+ from classiq.qmod.builtins.structs import PauliTerm
30
+ from classiq.qmod.qmod_variable import QStruct
24
31
 
25
32
 
26
33
  def compute_qaoa_initial_point(
27
- hamiltonian: List[QmodPyStruct],
34
+ hamiltonian: list[PauliTerm],
28
35
  repetitions: int,
29
- ) -> List[float]:
30
- coeffs_ising = [pauli_term["coefficient"] for pauli_term in hamiltonian[1:]]
36
+ ) -> list[float]:
37
+ coeffs_ising = [pauli_term.coefficient for pauli_term in hamiltonian[1:]]
31
38
  # the first coeff is the II...I term
32
- coeffs_abs = np.abs(coeffs_ising)
39
+ coeffs_abs = np.abs(coeffs_ising) # type: ignore[arg-type]
33
40
  coeffs_largest = np.sort(coeffs_abs)[len(coeffs_ising) // 2 :]
34
41
  operator_norm = np.mean(coeffs_largest)
35
42
  time_step = 1 / (2 * operator_norm) # adapted such that for MAXCUT time_step = 1
@@ -41,26 +48,55 @@ def compute_qaoa_initial_point(
41
48
 
42
49
  def pyo_model_to_hamiltonian(
43
50
  pyo_model: pyo.ConcreteModel, penalty_energy: float
44
- ) -> List[QmodPyStruct]:
51
+ ) -> list[PauliTerm]:
45
52
  pauli_list = OptimizationModel(
46
53
  pyo_model, penalty_energy=penalty_energy, qsolver=QSolver.QAOAPenalty
47
54
  ).ising.pauli_list
48
55
  return pauli_operator_to_hamiltonian(pauli_list)
49
56
 
50
57
 
51
- def _str_to_list_int(str_ints: str) -> List[int]:
58
+ def pyo_model_to_qmod_problem(
59
+ pyo_model: pyo.ConcreteModel, penalty_energy: float
60
+ ) -> tuple[type[QStruct], Callable]:
61
+ with add_var_domain_constraints(pyo_model):
62
+ optimization_model = OptimizationModel(
63
+ pyo_model, penalty_energy=penalty_energy, qsolver=QSolver.QAOAPenalty
64
+ )
65
+ _validate_var_domains(optimization_model)
66
+ qmod_struct = pyomo_to_qmod_qstruct(
67
+ "QAOAVars", optimization_model.vars_not_encoded
68
+ )
69
+ cost_func = partial(
70
+ evaluate_objective, *optimization_model.objective_not_encoded_sympy
71
+ )
72
+ return qmod_struct, cost_func
73
+
74
+
75
+ def _validate_var_domains(model: OptimizationModel) -> None:
76
+ for var in model.vars_not_encoded:
77
+ if (
78
+ isinstance(var.bounds, tuple)
79
+ and len(var.bounds) == 2
80
+ and var.bounds[0] != 0
81
+ ):
82
+ raise ClassiqValueError(
83
+ f"Bounds of variable {var.local_name} must start at 0, got {var.bounds}"
84
+ )
85
+
86
+
87
+ def _str_to_list_int(str_ints: str) -> list[int]:
52
88
  return list(map(int, list(str_ints)))
53
89
 
54
90
 
55
91
  def _decode_vector_str(
56
92
  optimization_model: OptimizationModel, vector_str: str
57
- ) -> List[int]:
93
+ ) -> list[int]:
58
94
  return optimization_model.decode(
59
95
  _str_to_list_int(vector_str[::-1])
60
96
  ) # reverse qubit order
61
97
 
62
98
 
63
- def _evaluate_operator(operator: SparsePauliOp, state: Union[List[int], str]) -> float:
99
+ def _evaluate_operator(operator: SparsePauliOp, state: Union[list[int], str]) -> float:
64
100
  if isinstance(state, list):
65
101
  state = "".join([str(x) for x in state])
66
102
 
@@ -103,7 +139,7 @@ def _eigenstate_to_solution(
103
139
  def _get_combi_solution_histogram(
104
140
  optimization_model: OptimizationModel,
105
141
  vqe_result: VQESolverResult,
106
- ) -> List[QmodPyStruct]:
142
+ ) -> list[QmodPyStruct]:
107
143
  if vqe_result.reduced_probabilities is None:
108
144
  raise ValueError(
109
145
  "reduced_probabilities is optional only for backwards compatibility, but it should always be present here"
@@ -120,7 +156,7 @@ def get_optimization_solution_from_pyo(
120
156
  pyo_model: pyo.ConcreteModel,
121
157
  vqe_result: VQESolverResult,
122
158
  penalty_energy: float,
123
- ) -> List[QmodPyStruct]:
159
+ ) -> list[QmodPyStruct]:
124
160
  converted_pyo_model = convert_pyomo_to_global_presentation(pyo_model)
125
161
  optimization_model = OptimizationModel(
126
162
  converted_pyo_model, penalty_energy=penalty_energy, qsolver=QSolver.QAOAPenalty
@@ -1,35 +1,35 @@
1
1
  import itertools
2
2
  from dataclasses import dataclass, field
3
- from typing import Dict, List, Optional, Union
3
+ from typing import Optional, Union
4
4
 
5
5
  import pyomo.environ as pyo
6
6
  from pyomo.core.base import _GeneralVarData
7
7
  from pyomo.core.expr.visitor import clone_expression, identify_variables
8
8
 
9
9
  from classiq.interface.combinatorial_optimization.encoding_types import EncodingType
10
+ from classiq.interface.exceptions import ClassiqCombOptError
10
11
 
11
- from classiq.applications_model_constructors.combinatorial_helpers import pyomo_utils
12
- from classiq.exceptions import ClassiqCombOptError
12
+ from classiq.applications.combinatorial_helpers import pyomo_utils
13
13
 
14
14
 
15
15
  @dataclass
16
16
  class VarExpressionMapping:
17
17
  var: _GeneralVarData
18
18
  expr: pyo.Expression
19
- encodings_vars: List[_GeneralVarData] = field(default_factory=list)
19
+ encodings_vars: list[_GeneralVarData] = field(default_factory=list)
20
20
 
21
21
 
22
22
  class EncodingMapping:
23
23
  def __init__(self, encoding_type: EncodingType) -> None:
24
- self._data: List[VarExpressionMapping] = []
24
+ self._data: list[VarExpressionMapping] = []
25
25
  self.encoding_type = encoding_type
26
26
 
27
27
  @property
28
- def original_vars(self) -> List[_GeneralVarData]:
28
+ def original_vars(self) -> list[_GeneralVarData]:
29
29
  return [pair.var for pair in self._data]
30
30
 
31
31
  @property
32
- def encodings_vars(self) -> List[_GeneralVarData]:
32
+ def encodings_vars(self) -> list[_GeneralVarData]:
33
33
  return list(
34
34
  itertools.chain.from_iterable(
35
35
  var_mapping.encodings_vars for var_mapping in self._data
@@ -37,7 +37,7 @@ class EncodingMapping:
37
37
  )
38
38
 
39
39
  @property
40
- def substitution_dict(self) -> Dict[int, pyo.Expression]:
40
+ def substitution_dict(self) -> dict[int, pyo.Expression]:
41
41
  return {id(mapping.var): mapping.expr for mapping in self._data}
42
42
 
43
43
  def __len__(self) -> int:
@@ -47,7 +47,7 @@ class EncodingMapping:
47
47
  self,
48
48
  original_var: _GeneralVarData,
49
49
  encoding_expr: pyo.Expression,
50
- encodings_vars: Union[List[_GeneralVarData], None] = None,
50
+ encodings_vars: Union[list[_GeneralVarData], None] = None,
51
51
  ) -> None:
52
52
  if encodings_vars is None:
53
53
  encodings_vars = list(identify_variables(encoding_expr))
@@ -59,7 +59,7 @@ class EncodingMapping:
59
59
  )
60
60
  )
61
61
 
62
- def _check_unique_encoding_vars(self, variables: List[_GeneralVarData]) -> None:
62
+ def _check_unique_encoding_vars(self, variables: list[_GeneralVarData]) -> None:
63
63
  assert all(
64
64
  not pyomo_utils.contains(var, self.encodings_vars) for var in variables
65
65
  )
@@ -72,7 +72,7 @@ class EncodingMapping:
72
72
  return var_expr_mapping
73
73
  raise ClassiqCombOptError("No variable expression mapping found.")
74
74
 
75
- def get_encoding_vars(self, original_var: _GeneralVarData) -> List[_GeneralVarData]:
75
+ def get_encoding_vars(self, original_var: _GeneralVarData) -> list[_GeneralVarData]:
76
76
  return self.get_var_expr_mapping(original_var).encodings_vars
77
77
 
78
78
  def get_original_var(
@@ -83,7 +83,7 @@ class EncodingMapping:
83
83
  return original_var
84
84
  return None
85
85
 
86
- def decode(self, solution: List[int]) -> List[int]:
86
+ def decode(self, solution: list[int]) -> list[int]:
87
87
  idx = 0
88
88
  decoded_solution = []
89
89
  for var_mapping in self._data:
@@ -1,6 +1,6 @@
1
1
  import math
2
2
  from itertools import filterfalse
3
- from typing import Any, Dict, Union, cast
3
+ from typing import Any, Union, cast
4
4
 
5
5
  import numpy as np
6
6
  import pyomo.environ as pyo
@@ -14,8 +14,9 @@ from pyomo.core.expr.numeric_expr import (
14
14
  )
15
15
  from sympy import Expr
16
16
 
17
- from classiq.applications_model_constructors.combinatorial_helpers import pyomo_utils
18
- from classiq.exceptions import ClassiqCombOptNoSolutionError
17
+ from classiq.interface.exceptions import ClassiqCombOptNoSolutionError
18
+
19
+ from classiq.applications.combinatorial_helpers import pyomo_utils
19
20
 
20
21
  _INTEGER_TYPES = [pyo.NonNegativeIntegers, pyo.Integers, pyo.PositiveIntegers]
21
22
 
@@ -38,6 +39,7 @@ def is_var_span_power_of_2(var: _GeneralVarData) -> bool:
38
39
 
39
40
  ENCODED_SUFFIX = "_encoded"
40
41
  ONE_HOT_SUFFIX = "_one_hot"
42
+ CONSTRAINT_SUFFIX = "_constraint"
41
43
 
42
44
 
43
45
  def is_obj_encoded(var: _ComponentBase) -> bool:
@@ -69,7 +71,7 @@ def recursively_remove_monomial_expr(obj: Any) -> None:
69
71
 
70
72
 
71
73
  def encode_expr(
72
- expr: pyo.Expression, substitution_dict: Dict[int, pyo.Expression]
74
+ expr: pyo.Expression, substitution_dict: dict[int, pyo.Expression]
73
75
  ) -> pyo.Expression:
74
76
  encoded_expr = clone_expression(expr=expr, substitute=substitution_dict)
75
77
  recursively_remove_monomial_expr(encoded_expr)
@@ -77,7 +79,7 @@ def encode_expr(
77
79
 
78
80
 
79
81
  def encode_constraints(
80
- model: pyo.ConcreteModel, substitution_dict: Dict[int, pyo.Expression]
82
+ model: pyo.ConcreteModel, substitution_dict: dict[int, pyo.Expression]
81
83
  ) -> None:
82
84
  all_constraints = pyomo_utils.extract(model, _GeneralConstraintData)
83
85
  constraints = filterfalse(is_obj_encoded, all_constraints)
@@ -106,7 +108,7 @@ def deal_with_trivial_boolean_constraint(
106
108
 
107
109
 
108
110
  def encode_objective(
109
- model: pyo.ConcreteModel, substitution_dict: Dict[int, pyo.Expression]
111
+ model: pyo.ConcreteModel, substitution_dict: dict[int, pyo.Expression]
110
112
  ) -> None:
111
113
  objective = next(model.component_objects(pyo.Objective))
112
114
 
@@ -1,15 +1,11 @@
1
1
  from __future__ import annotations
2
2
 
3
- from typing import Dict, List, Tuple
4
-
5
3
  from pyomo.core.base import _GeneralVarData
6
4
 
7
5
  from classiq.interface.generator.function_params import IOName
8
6
 
9
- from classiq.applications_model_constructors.combinatorial_helpers import encoding_utils
10
- from classiq.applications_model_constructors.combinatorial_helpers.encoding_mapping import (
11
- EncodingMapping,
12
- )
7
+ from classiq.applications.combinatorial_helpers import encoding_utils
8
+ from classiq.applications.combinatorial_helpers.encoding_mapping import EncodingMapping
13
9
 
14
10
  AUXILIARY_NAME = "auxiliary"
15
11
 
@@ -23,13 +19,13 @@ class InternalQuantumReg:
23
19
  class MemoryMapping:
24
20
  def __init__(
25
21
  self,
26
- variables: List[_GeneralVarData],
22
+ variables: list[_GeneralVarData],
27
23
  vars_encoding_mapping: EncodingMapping | None = None,
28
24
  ) -> None:
29
- self.substitution_dict: Dict[int, InternalQuantumReg] = dict()
30
- self.qubit_allocation: Dict[IOName, Tuple[int, int]] = dict()
25
+ self.substitution_dict: dict[int, InternalQuantumReg] = dict()
26
+ self.qubit_allocation: dict[IOName, tuple[int, int]] = dict()
31
27
  self.vars_encoding_mapping: EncodingMapping | None = vars_encoding_mapping
32
- self.vars: List[_GeneralVarData] = variables
28
+ self.vars: list[_GeneralVarData] = variables
33
29
  self._allocate_memory()
34
30
 
35
31
  def __len__(self) -> int:
@@ -57,7 +53,7 @@ class MemoryMapping:
57
53
  )
58
54
 
59
55
  @property
60
- def qregs(self) -> List[InternalQuantumReg]:
56
+ def qregs(self) -> list[InternalQuantumReg]:
61
57
  return list(self.substitution_dict.values())
62
58
 
63
59
  @property
@@ -1,43 +1,46 @@
1
1
  import copy
2
+ from functools import cached_property
2
3
  from itertools import filterfalse
3
- from typing import List, Optional, Union
4
+ from typing import Optional, Union
4
5
 
5
6
  import pyomo.environ as pyo
6
7
  from pyomo.core import ConcreteModel
7
8
  from pyomo.core.base import _GeneralVarData
8
9
  from pyomo.core.base.constraint import _GeneralConstraintData
10
+ from pyomo.core.expr.sympy_tools import sympyify_expression
9
11
  from pyomo.environ import Expression
10
12
 
11
13
  from classiq.interface.chemistry.operator import PauliOperator
12
14
  from classiq.interface.combinatorial_optimization import sense
13
15
  from classiq.interface.combinatorial_optimization.encoding_types import EncodingType
14
16
  from classiq.interface.combinatorial_optimization.solver_types import QSolver
17
+ from classiq.interface.exceptions import ClassiqCombOptError
15
18
 
16
- from classiq.applications_model_constructors.combinatorial_helpers import (
19
+ from classiq.applications.combinatorial_helpers import (
17
20
  encoding_utils,
18
21
  memory,
19
22
  pyomo_utils,
20
23
  )
21
- from classiq.applications_model_constructors.combinatorial_helpers.encoding_mapping import (
22
- EncodingMapping,
24
+ from classiq.applications.combinatorial_helpers.encoding_mapping import EncodingMapping
25
+ from classiq.applications.combinatorial_helpers.memory import InternalQuantumReg
26
+ from classiq.applications.combinatorial_helpers.pyomo_utils import (
27
+ get_field_name,
28
+ index_as_tuple,
29
+ is_index_var,
23
30
  )
24
- from classiq.applications_model_constructors.combinatorial_helpers.memory import (
25
- InternalQuantumReg,
26
- )
27
- from classiq.applications_model_constructors.combinatorial_helpers.transformations import (
31
+ from classiq.applications.combinatorial_helpers.transformations import (
28
32
  encoding,
29
33
  ising_converter,
30
34
  penalty,
31
35
  slack_variables,
32
36
  )
33
- from classiq.applications_model_constructors.combinatorial_helpers.transformations.fixed_variables import (
37
+ from classiq.applications.combinatorial_helpers.transformations.fixed_variables import (
34
38
  add_fixed_variables_to_solution,
35
39
  remove_fixed_variables,
36
40
  )
37
- from classiq.applications_model_constructors.combinatorial_helpers.transformations.penalty_support import (
41
+ from classiq.applications.combinatorial_helpers.transformations.penalty_support import (
38
42
  is_model_penalty_supported,
39
43
  )
40
- from classiq.exceptions import ClassiqCombOptError
41
44
 
42
45
 
43
46
  class OptimizationModel:
@@ -49,22 +52,23 @@ class OptimizationModel:
49
52
  encoding_type: Optional[EncodingType] = None,
50
53
  ) -> None:
51
54
  assert model.nobjectives() == 1, "model must have a single objective"
52
- self._model_original = copy.deepcopy(model)
53
- self._assigned_model = remove_fixed_variables(model)
55
+ model_copy = copy.deepcopy(model)
56
+ self._model_original = model
57
+ self._assigned_model = remove_fixed_variables(model_copy)
54
58
  self.qsolver = qsolver
55
59
  self._encoding_type = encoding_type
56
60
 
57
- self.is_encoded = encoding_utils.is_model_encodable(model)
61
+ self.is_encoded = encoding_utils.is_model_encodable(model_copy)
58
62
  if self.is_encoded:
59
63
  if self._encoding_type is None:
60
64
  self._encoding_type = EncodingType.BINARY
61
65
  self._model_encoder = encoding.ModelEncoder(
62
- model, qsolver, self._encoding_type
66
+ model_copy, qsolver, self._encoding_type
63
67
  )
64
68
  self._model = self._model_encoder.encoded_model
65
69
  self._vars_encoding_mapping = self._model_encoder.vars_encoding_mapping
66
70
  else:
67
- self._model = model
71
+ self._model = model_copy
68
72
  # TODO How to handle encoding_type == None
69
73
  self._vars_encoding_mapping = EncodingMapping(self._encoding_type) # type: ignore[arg-type]
70
74
 
@@ -74,24 +78,28 @@ class OptimizationModel:
74
78
  self.vars_not_encoded, self._vars_encoding_mapping
75
79
  )
76
80
 
77
- self.is_maximization = sense.is_maximization(model)
78
- self.objective = next(self._model.component_objects(pyo.Objective))
79
-
81
+ self.is_maximization = sense.is_maximization(model_copy)
80
82
  self.penalty_energy = penalty_energy
81
- self._add_penalty_term()
82
83
 
83
- self.ising: PauliOperator = self._to_ising()
84
+ self.objective = next(self._model.component_objects(pyo.Objective))
85
+ if self.qsolver == QSolver.QAOAPenalty:
86
+ self.objective.expr += self._get_penalty_term(self.constraints)
87
+ if self.is_encoded:
88
+ self.objective.expr = self._model_encoder.encode_expr(
89
+ self.objective.expr
90
+ )
91
+ self._initialize_objective_not_encoded(model_copy)
84
92
 
85
93
  @property
86
- def vars(self) -> List[_GeneralVarData]:
94
+ def vars(self) -> list[_GeneralVarData]:
87
95
  return pyomo_utils.extract(self._model, _GeneralVarData)
88
96
 
89
97
  @property
90
- def vars_not_encoded(self) -> List[_GeneralVarData]:
98
+ def vars_not_encoded(self) -> list[_GeneralVarData]:
91
99
  return list(filterfalse(encoding_utils.is_obj_encoded, self.vars))
92
100
 
93
101
  @property
94
- def _ising_vars(self) -> List[_GeneralVarData]:
102
+ def _ising_vars(self) -> list[_GeneralVarData]:
95
103
  if self.is_encoded:
96
104
  return [
97
105
  var
@@ -103,12 +111,12 @@ class OptimizationModel:
103
111
  return self.vars
104
112
 
105
113
  @property
106
- def constraints(self) -> List[_GeneralConstraintData]:
114
+ def constraints(self) -> list[_GeneralConstraintData]:
107
115
  all_constraints = pyomo_utils.extract(self._model, _GeneralConstraintData)
108
116
  return list(filterfalse(encoding_utils.is_obj_encoded, all_constraints))
109
117
 
110
118
  @property
111
- def qregs(self) -> List[InternalQuantumReg]:
119
+ def qregs(self) -> list[InternalQuantumReg]:
112
120
  return self.memory_mapping.qregs
113
121
 
114
122
  @property
@@ -119,19 +127,14 @@ class OptimizationModel:
119
127
  def sign(self) -> int:
120
128
  return -1 if self.is_maximization else 1
121
129
 
122
- def _add_penalty_term(self) -> None:
123
- if self.qsolver == QSolver.QAOAPenalty:
124
- self.objective.expr += self._get_penalty_term()
125
-
126
- def _get_penalty_term(self) -> Union[int, Expression]:
127
- normalized_penalty_term = penalty.get_penalty_expression(self.constraints)
128
- penalty_term = self.penalty_energy * normalized_penalty_term * self.sign
129
-
130
- if self.is_encoded:
131
- penalty_term = self._model_encoder.encode_expr(penalty_term)
132
- return penalty_term
130
+ def _get_penalty_term(
131
+ self, constraints: list[_GeneralConstraintData]
132
+ ) -> Union[int, Expression]:
133
+ normalized_penalty_term = penalty.get_penalty_expression(constraints)
134
+ return self.penalty_energy * normalized_penalty_term * self.sign
133
135
 
134
- def _to_ising(self) -> PauliOperator:
136
+ @cached_property
137
+ def ising(self) -> PauliOperator:
135
138
  return (
136
139
  ising_converter.convert_pyomo_to_hamiltonian(
137
140
  self.objective.expr, self._ising_vars, self.qregs
@@ -139,11 +142,11 @@ class OptimizationModel:
139
142
  * self.sign
140
143
  )
141
144
 
142
- def _remove_slack_variables_from_solution(self, solution: List[int]) -> List[int]:
145
+ def _remove_slack_variables_from_solution(self, solution: list[int]) -> list[int]:
143
146
  variables = pyomo_utils.extract(self._model_original, pyo.Var)
144
147
  return solution[: len(variables)]
145
148
 
146
- def decode(self, solution: List[int]) -> List[int]:
149
+ def decode(self, solution: list[int]) -> list[int]:
147
150
  if self.is_encoded:
148
151
  solution = self._vars_encoding_mapping.decode(solution)
149
152
 
@@ -164,3 +167,27 @@ class OptimizationModel:
164
167
  self._model
165
168
  ):
166
169
  return slack_variables.slack_vars_convert(self._model)
170
+
171
+ def _initialize_objective_not_encoded(self, model_copy: pyo.ConcreteModel) -> None:
172
+ objective_not_encoded = next(model_copy.component_objects(pyo.Objective))
173
+ objective_map, objective_expr = sympyify_expression(objective_not_encoded)
174
+ objective_expr *= self.sign
175
+ if self.qsolver == QSolver.QAOAPenalty:
176
+ penalty = self._get_penalty_term(self.constraints)
177
+ penalty_map, penalty_expr = sympyify_expression(penalty)
178
+ objective_expr += penalty_expr * self.sign
179
+ objective_map.sympy2pyomo |= penalty_map.sympy2pyomo
180
+ for key, value in penalty_map.pyomo2sympy.items():
181
+ objective_map.pyomo2sympy[key] = value
182
+ sympy_mapping = {
183
+ sympy_var: (
184
+ get_field_name(pyomo_var)
185
+ if not is_index_var(pyomo_var)
186
+ else (
187
+ get_field_name(pyomo_var.parent_component()),
188
+ index_as_tuple(pyomo_var.index()),
189
+ )
190
+ )
191
+ for pyomo_var, sympy_var in objective_map.pyomo2sympy.items()
192
+ }
193
+ self.objective_not_encoded_sympy = sympy_mapping, objective_expr
@@ -0,0 +1,46 @@
1
+ from classiq.interface.exceptions import ClassiqNonNumericCoefficientInPauliError
2
+ from classiq.interface.generator.functions.qmod_python_interface import QmodPyStruct
3
+ from classiq.interface.helpers.custom_pydantic_types import PydanticPauliList
4
+
5
+ from classiq.qmod.builtins.enums import Pauli
6
+ from classiq.qmod.builtins.structs import PauliTerm
7
+
8
+
9
+ def pauli_operator_to_hamiltonian(pauli_list: PydanticPauliList) -> list[PauliTerm]:
10
+ pauli_terms: list[PauliTerm] = []
11
+ for pauli_term in pauli_list:
12
+ if not isinstance(pauli_term[1], complex) or pauli_term[1].imag != 0:
13
+ raise ClassiqNonNumericCoefficientInPauliError(
14
+ "Coefficient is not a number."
15
+ )
16
+ term = PauliTerm(
17
+ [Pauli[p] for p in pauli_term[0]], # type: ignore[arg-type]
18
+ pauli_term[1].real, # type: ignore[arg-type]
19
+ )
20
+ pauli_terms.append(term)
21
+
22
+ return pauli_terms
23
+
24
+
25
+ def pauli_enum_to_str(pauli: Pauli) -> str:
26
+ return {
27
+ Pauli.I: "Pauli.I",
28
+ Pauli.X: "Pauli.X",
29
+ Pauli.Y: "Pauli.Y",
30
+ Pauli.Z: "Pauli.Z",
31
+ }[pauli]
32
+
33
+
34
+ def _pauli_terms_to_qmod(hamiltonian: list[PauliTerm]) -> str:
35
+ qmod_strings = []
36
+ for term in hamiltonian:
37
+ pauli_str = ", ".join([pauli_enum_to_str(p) for p in term.pauli]) # type: ignore[attr-defined]
38
+ qmod_strings.append(
39
+ f"struct_literal(PauliTerm, pauli=[{pauli_str}], coefficient={term.coefficient})"
40
+ )
41
+
42
+ return ", ".join(qmod_strings)
43
+
44
+
45
+ def _pauli_dict_to_pauli_terms(hamiltonian: list[QmodPyStruct]) -> list[PauliTerm]:
46
+ return [PauliTerm(**struct) for struct in hamiltonian]