classiq 0.37.1__py3-none-any.whl → 0.39.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (280) hide show
  1. classiq/__init__.py +23 -24
  2. classiq/_analyzer_extras/_ipywidgets_async_extension.py +1 -1
  3. classiq/_analyzer_extras/interactive_hardware.py +3 -3
  4. classiq/_internals/api_wrapper.py +37 -17
  5. classiq/_internals/async_utils.py +1 -74
  6. classiq/_internals/authentication/device.py +9 -4
  7. classiq/_internals/authentication/password_manager.py +25 -10
  8. classiq/_internals/authentication/token_manager.py +2 -2
  9. classiq/_internals/client.py +24 -6
  10. classiq/_internals/jobs.py +10 -7
  11. classiq/analyzer/analyzer.py +29 -29
  12. classiq/analyzer/analyzer_utilities.py +5 -5
  13. classiq/analyzer/rb.py +4 -5
  14. classiq/analyzer/show_interactive_hack.py +6 -6
  15. classiq/applications/__init__.py +1 -8
  16. classiq/applications/chemistry/__init__.py +6 -0
  17. classiq/{applications_model_constructors → applications/chemistry}/chemistry_model_constructor.py +9 -16
  18. classiq/applications/combinatorial_helpers/allowed_constraints.py +20 -0
  19. classiq/applications/combinatorial_helpers/arithmetic/arithmetic_expression.py +35 -0
  20. classiq/applications/combinatorial_helpers/arithmetic/isolation.py +42 -0
  21. classiq/applications/combinatorial_helpers/combinatorial_problem_utils.py +150 -0
  22. classiq/applications/combinatorial_helpers/encoding_mapping.py +107 -0
  23. classiq/applications/combinatorial_helpers/encoding_utils.py +122 -0
  24. classiq/applications/combinatorial_helpers/memory.py +77 -0
  25. classiq/applications/combinatorial_helpers/optimization_model.py +162 -0
  26. classiq/applications/combinatorial_helpers/pauli_helpers/pauli_sparsing.py +31 -0
  27. classiq/applications/combinatorial_helpers/pauli_helpers/pauli_utils.py +75 -0
  28. classiq/applications/combinatorial_helpers/py.typed +0 -0
  29. classiq/applications/combinatorial_helpers/pyomo_utils.py +245 -0
  30. classiq/applications/combinatorial_helpers/solvers/__init__.py +0 -0
  31. classiq/applications/combinatorial_helpers/sympy_utils.py +22 -0
  32. classiq/applications/combinatorial_helpers/transformations/__init__.py +0 -0
  33. classiq/applications/combinatorial_helpers/transformations/encoding.py +187 -0
  34. classiq/applications/combinatorial_helpers/transformations/fixed_variables.py +142 -0
  35. classiq/applications/combinatorial_helpers/transformations/ising_converter.py +122 -0
  36. classiq/applications/combinatorial_helpers/transformations/penalty.py +32 -0
  37. classiq/applications/combinatorial_helpers/transformations/penalty_support.py +37 -0
  38. classiq/applications/combinatorial_helpers/transformations/sign_seperation.py +75 -0
  39. classiq/applications/combinatorial_helpers/transformations/slack_variables.py +88 -0
  40. classiq/applications/combinatorial_optimization/__init__.py +13 -2
  41. classiq/applications/combinatorial_optimization/combinatorial_optimization_model_constructor.py +134 -0
  42. classiq/applications/finance/__init__.py +3 -2
  43. classiq/{applications_model_constructors → applications/finance}/finance_model_constructor.py +27 -30
  44. classiq/applications/grover/__init__.py +11 -0
  45. classiq/{applications_model_constructors → applications/grover}/grover_model_constructor.py +20 -91
  46. classiq/applications/libraries/__init__.py +0 -0
  47. classiq/applications/libraries/qmci_library.py +35 -0
  48. classiq/applications/qnn/circuit_utils.py +2 -2
  49. classiq/applications/qnn/gradients/quantum_gradient.py +2 -2
  50. classiq/applications/qnn/types.py +2 -2
  51. classiq/applications/qsvm/__init__.py +5 -1
  52. classiq/applications/qsvm/qsvm.py +4 -7
  53. classiq/applications/qsvm/qsvm_data_generation.py +2 -5
  54. classiq/exceptions.py +43 -1
  55. classiq/execution/all_hardware_devices.py +13 -0
  56. classiq/executor.py +12 -10
  57. classiq/interface/_version.py +1 -1
  58. classiq/interface/analyzer/analysis_params.py +6 -3
  59. classiq/interface/analyzer/result.py +12 -8
  60. classiq/interface/applications/qsvm.py +17 -3
  61. classiq/interface/ast_node.py +23 -0
  62. classiq/interface/backend/backend_preferences.py +4 -2
  63. classiq/interface/backend/pydantic_backend.py +3 -1
  64. classiq/interface/backend/quantum_backend_providers.py +1 -0
  65. classiq/interface/chemistry/fermionic_operator.py +15 -13
  66. classiq/interface/chemistry/ground_state_problem.py +18 -3
  67. classiq/interface/chemistry/molecule.py +8 -6
  68. classiq/interface/chemistry/operator.py +20 -14
  69. classiq/interface/combinatorial_optimization/examples/ascending_sequence.py +1 -1
  70. classiq/interface/combinatorial_optimization/examples/greater_than_ilp.py +1 -1
  71. classiq/interface/combinatorial_optimization/examples/ilp.py +2 -1
  72. classiq/interface/combinatorial_optimization/examples/integer_portfolio_optimization.py +2 -2
  73. classiq/interface/combinatorial_optimization/examples/mds.py +2 -1
  74. classiq/interface/combinatorial_optimization/examples/mht.py +8 -3
  75. classiq/interface/combinatorial_optimization/examples/mis.py +4 -1
  76. classiq/interface/combinatorial_optimization/examples/mvc.py +2 -1
  77. classiq/interface/combinatorial_optimization/examples/set_cover.py +2 -1
  78. classiq/interface/combinatorial_optimization/examples/tsp.py +4 -3
  79. classiq/interface/combinatorial_optimization/examples/tsp_digraph.py +6 -2
  80. classiq/interface/combinatorial_optimization/mht_qaoa_input.py +9 -3
  81. classiq/interface/executor/aws_execution_cost.py +4 -3
  82. classiq/interface/executor/estimation.py +2 -2
  83. classiq/interface/executor/execution_preferences.py +5 -34
  84. classiq/interface/executor/execution_request.py +15 -48
  85. classiq/interface/executor/optimizer_preferences.py +22 -13
  86. classiq/interface/executor/{quantum_program.py → quantum_code.py} +21 -15
  87. classiq/interface/executor/quantum_instruction_set.py +2 -1
  88. classiq/interface/executor/register_initialization.py +1 -3
  89. classiq/interface/executor/result.py +41 -10
  90. classiq/interface/executor/vqe_result.py +2 -2
  91. classiq/interface/finance/function_input.py +17 -4
  92. classiq/interface/finance/gaussian_model_input.py +3 -1
  93. classiq/interface/finance/log_normal_model_input.py +3 -1
  94. classiq/interface/finance/model_input.py +2 -0
  95. classiq/interface/generator/amplitude_loading.py +6 -3
  96. classiq/interface/generator/application_apis/__init__.py +1 -0
  97. classiq/interface/generator/application_apis/arithmetic_declarations.py +14 -0
  98. classiq/interface/generator/arith/argument_utils.py +14 -4
  99. classiq/interface/generator/arith/arithmetic.py +3 -1
  100. classiq/interface/generator/arith/arithmetic_arg_type_validator.py +12 -13
  101. classiq/interface/generator/arith/arithmetic_expression_abc.py +4 -1
  102. classiq/interface/generator/arith/arithmetic_expression_parser.py +8 -2
  103. classiq/interface/generator/arith/arithmetic_expression_validator.py +16 -2
  104. classiq/interface/generator/arith/arithmetic_operations.py +5 -10
  105. classiq/interface/generator/arith/ast_node_rewrite.py +1 -1
  106. classiq/interface/generator/arith/binary_ops.py +202 -54
  107. classiq/interface/generator/arith/extremum_operations.py +5 -3
  108. classiq/interface/generator/arith/logical_ops.py +4 -2
  109. classiq/interface/generator/arith/machine_precision.py +3 -0
  110. classiq/interface/generator/arith/number_utils.py +34 -44
  111. classiq/interface/generator/arith/register_user_input.py +21 -1
  112. classiq/interface/generator/arith/unary_ops.py +16 -25
  113. classiq/interface/generator/builtin_api_builder.py +0 -5
  114. classiq/interface/generator/chemistry_function_params.py +4 -4
  115. classiq/interface/generator/commuting_pauli_exponentiation.py +3 -1
  116. classiq/interface/generator/compiler_keywords.py +4 -0
  117. classiq/interface/generator/complex_type.py +3 -10
  118. classiq/interface/generator/constant.py +2 -3
  119. classiq/interface/generator/control_state.py +5 -3
  120. classiq/interface/generator/credit_risk_example/linear_gci.py +10 -3
  121. classiq/interface/generator/credit_risk_example/weighted_adder.py +14 -4
  122. classiq/interface/generator/expressions/atomic_expression_functions.py +5 -3
  123. classiq/interface/generator/expressions/evaluated_expression.py +18 -4
  124. classiq/interface/generator/expressions/expression.py +3 -5
  125. classiq/interface/generator/expressions/qmod_qscalar_proxy.py +33 -0
  126. classiq/interface/generator/expressions/sympy_supported_expressions.py +2 -1
  127. classiq/interface/generator/finance.py +1 -1
  128. classiq/interface/generator/function_params.py +7 -6
  129. classiq/interface/generator/functions/__init__.py +2 -2
  130. classiq/interface/generator/functions/builtins/__init__.py +15 -0
  131. classiq/interface/generator/functions/builtins/core_library/__init__.py +14 -0
  132. classiq/interface/generator/functions/builtins/core_library/chemistry_functions.py +0 -0
  133. classiq/interface/generator/functions/builtins/internal_operators.py +62 -0
  134. classiq/interface/generator/functions/{core_lib_declarations/quantum_functions/std_lib_functions.py → builtins/open_lib_functions.py} +612 -219
  135. classiq/interface/generator/functions/builtins/quantum_operators.py +37 -0
  136. classiq/interface/generator/functions/classical_type.py +2 -4
  137. classiq/interface/generator/functions/foreign_function_definition.py +12 -4
  138. classiq/interface/generator/functions/function_declaration.py +2 -2
  139. classiq/interface/generator/functions/function_implementation.py +8 -4
  140. classiq/interface/generator/functions/native_function_definition.py +4 -2
  141. classiq/interface/generator/functions/register.py +4 -2
  142. classiq/interface/generator/functions/register_mapping_data.py +14 -10
  143. classiq/interface/generator/generated_circuit_data.py +2 -2
  144. classiq/interface/generator/grover_operator.py +5 -3
  145. classiq/interface/generator/hamiltonian_evolution/suzuki_trotter.py +5 -1
  146. classiq/interface/generator/hardware/hardware_data.py +6 -4
  147. classiq/interface/generator/hardware_efficient_ansatz.py +25 -8
  148. classiq/interface/generator/hartree_fock.py +13 -3
  149. classiq/interface/generator/linear_pauli_rotations.py +3 -1
  150. classiq/interface/generator/mcu.py +5 -3
  151. classiq/interface/generator/mcx.py +7 -5
  152. classiq/interface/generator/model/classical_main_validator.py +1 -1
  153. classiq/interface/generator/model/constraints.py +2 -1
  154. classiq/interface/generator/model/model.py +12 -20
  155. classiq/interface/generator/model/preferences/preferences.py +4 -3
  156. classiq/interface/generator/oracles/custom_oracle.py +4 -2
  157. classiq/interface/generator/oracles/oracle_abc.py +2 -2
  158. classiq/interface/generator/qpe.py +6 -4
  159. classiq/interface/generator/qsvm.py +5 -8
  160. classiq/interface/generator/quantum_function_call.py +21 -16
  161. classiq/interface/generator/{generated_circuit.py → quantum_program.py} +10 -14
  162. classiq/interface/generator/range_types.py +3 -1
  163. classiq/interface/generator/slice_parsing_utils.py +8 -3
  164. classiq/interface/generator/standard_gates/controlled_standard_gates.py +4 -2
  165. classiq/interface/generator/state_preparation/metrics.py +2 -1
  166. classiq/interface/generator/state_preparation/state_preparation.py +7 -5
  167. classiq/interface/generator/state_propagator.py +16 -5
  168. classiq/interface/generator/types/builtin_struct_declarations/__init__.py +0 -1
  169. classiq/interface/generator/types/struct_declaration.py +10 -7
  170. classiq/interface/generator/ucc.py +6 -4
  171. classiq/interface/generator/unitary_gate.py +7 -3
  172. classiq/interface/generator/validations/flow_graph.py +6 -4
  173. classiq/interface/generator/validations/validator_functions.py +6 -4
  174. classiq/interface/hardware.py +2 -2
  175. classiq/interface/helpers/custom_encoders.py +3 -0
  176. classiq/interface/helpers/pydantic_model_helpers.py +0 -6
  177. classiq/interface/helpers/validation_helpers.py +1 -1
  178. classiq/interface/helpers/versioned_model.py +4 -1
  179. classiq/interface/ide/show.py +2 -2
  180. classiq/interface/jobs.py +72 -3
  181. classiq/interface/model/bind_operation.py +18 -11
  182. classiq/interface/model/call_synthesis_data.py +68 -0
  183. classiq/interface/model/classical_if.py +13 -0
  184. classiq/interface/model/classical_parameter_declaration.py +2 -3
  185. classiq/interface/model/control.py +16 -0
  186. classiq/interface/model/handle_binding.py +3 -2
  187. classiq/interface/model/inplace_binary_operation.py +2 -2
  188. classiq/interface/model/invert.py +10 -0
  189. classiq/interface/model/model.py +29 -22
  190. classiq/interface/model/native_function_definition.py +3 -5
  191. classiq/interface/model/power.py +12 -0
  192. classiq/interface/model/quantum_expressions/amplitude_loading_operation.py +9 -4
  193. classiq/interface/model/quantum_expressions/control_state.py +2 -2
  194. classiq/interface/model/quantum_function_call.py +33 -142
  195. classiq/interface/model/quantum_function_declaration.py +8 -0
  196. classiq/interface/model/quantum_if_operation.py +4 -5
  197. classiq/interface/model/quantum_lambda_function.py +58 -0
  198. classiq/{quantum_register.py → interface/model/quantum_register.py} +17 -9
  199. classiq/interface/model/quantum_statement.py +3 -2
  200. classiq/interface/model/quantum_type.py +58 -59
  201. classiq/interface/model/quantum_variable_declaration.py +3 -3
  202. classiq/interface/model/repeat.py +13 -0
  203. classiq/interface/model/resolvers/function_call_resolver.py +26 -0
  204. classiq/interface/model/statement_block.py +49 -0
  205. classiq/interface/model/validations/handles_validator.py +16 -18
  206. classiq/interface/model/within_apply_operation.py +11 -0
  207. classiq/interface/pyomo_extension/pyomo_sympy_bimap.py +4 -1
  208. classiq/interface/server/routes.py +5 -4
  209. classiq/qmod/__init__.py +13 -6
  210. classiq/qmod/builtins/classical_execution_primitives.py +27 -36
  211. classiq/qmod/builtins/classical_functions.py +22 -12
  212. classiq/qmod/builtins/functions.py +272 -328
  213. classiq/qmod/builtins/operations.py +171 -35
  214. classiq/qmod/builtins/structs.py +15 -15
  215. classiq/qmod/cfunc.py +42 -0
  216. classiq/qmod/classical_function.py +6 -14
  217. classiq/qmod/declaration_inferrer.py +12 -21
  218. classiq/qmod/expression_query.py +23 -0
  219. classiq/qmod/model_state_container.py +2 -0
  220. classiq/qmod/native/__init__.py +0 -0
  221. classiq/qmod/native/expression_to_qmod.py +189 -0
  222. classiq/qmod/native/pretty_printer.py +340 -0
  223. classiq/qmod/qfunc.py +27 -0
  224. classiq/qmod/qmod_constant.py +100 -0
  225. classiq/qmod/qmod_parameter.py +36 -13
  226. classiq/qmod/qmod_struct.py +3 -3
  227. classiq/qmod/qmod_variable.py +148 -31
  228. classiq/qmod/quantum_callable.py +1 -0
  229. classiq/qmod/quantum_expandable.py +18 -19
  230. classiq/qmod/quantum_function.py +41 -8
  231. classiq/qmod/symbolic.py +48 -5
  232. classiq/qmod/symbolic_expr.py +9 -0
  233. classiq/qmod/utilities.py +13 -0
  234. classiq/qmod/write_qmod.py +39 -0
  235. {classiq-0.37.1.dist-info → classiq-0.39.0.dist-info}/METADATA +2 -1
  236. {classiq-0.37.1.dist-info → classiq-0.39.0.dist-info}/RECORD +244 -225
  237. {classiq-0.37.1.dist-info → classiq-0.39.0.dist-info}/WHEEL +1 -1
  238. classiq/applications/benchmarking/__init__.py +0 -9
  239. classiq/applications/benchmarking/mirror_benchmarking.py +0 -67
  240. classiq/applications/numpy_utils.py +0 -37
  241. classiq/applications_model_constructors/__init__.py +0 -17
  242. classiq/applications_model_constructors/combinatorial_optimization_model_constructor.py +0 -178
  243. classiq/applications_model_constructors/libraries/qmci_library.py +0 -109
  244. classiq/builtin_functions/__init__.py +0 -43
  245. classiq/builtin_functions/amplitude_loading.py +0 -3
  246. classiq/builtin_functions/binary_ops.py +0 -1
  247. classiq/builtin_functions/exponentiation.py +0 -5
  248. classiq/builtin_functions/qpe.py +0 -4
  249. classiq/builtin_functions/qsvm.py +0 -7
  250. classiq/builtin_functions/range_types.py +0 -5
  251. classiq/builtin_functions/standard_gates.py +0 -1
  252. classiq/builtin_functions/state_preparation.py +0 -6
  253. classiq/builtin_functions/suzuki_trotter.py +0 -3
  254. classiq/interface/generator/expressions/qmod_qnum_proxy.py +0 -22
  255. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/__init__.py +0 -18
  256. classiq/interface/generator/functions/core_lib_declarations/quantum_operators.py +0 -169
  257. classiq/interface/generator/types/builtin_struct_declarations/qaoa_declarations.py +0 -23
  258. classiq/interface/generator/types/combinatorial_problem.py +0 -26
  259. classiq/interface/model/numeric_reinterpretation.py +0 -25
  260. classiq/interface/model/operator_synthesis_data.py +0 -48
  261. classiq/model/__init__.py +0 -14
  262. classiq/model/composite_function_generator.py +0 -33
  263. classiq/model/function_handler.py +0 -466
  264. classiq/model/function_handler.pyi +0 -152
  265. classiq/model/logic_flow.py +0 -149
  266. classiq/model/logic_flow_change_handler.py +0 -71
  267. classiq/model/model.py +0 -246
  268. classiq/quantum_functions/__init__.py +0 -17
  269. classiq/quantum_functions/annotation_parser.py +0 -207
  270. classiq/quantum_functions/decorators.py +0 -22
  271. classiq/quantum_functions/function_library.py +0 -181
  272. classiq/quantum_functions/function_parser.py +0 -74
  273. classiq/quantum_functions/quantum_function.py +0 -236
  274. /classiq/{applications_model_constructors/libraries → applications/combinatorial_helpers}/__init__.py +0 -0
  275. /classiq/{interface/generator/functions/core_lib_declarations → applications/combinatorial_helpers/arithmetic}/__init__.py +0 -0
  276. /classiq/{interface/generator/functions/core_lib_declarations/quantum_functions/chemistry_functions.py → applications/combinatorial_helpers/pauli_helpers/__init__.py} +0 -0
  277. /classiq/{applications_model_constructors → applications}/libraries/ampltitude_estimation_library.py +0 -0
  278. /classiq/{applications_model_constructors → applications/qsvm}/qsvm_model_constructor.py +0 -0
  279. /classiq/interface/generator/functions/{core_lib_declarations/quantum_functions → builtins/core_library}/atomic_quantum_functions.py +0 -0
  280. /classiq/interface/generator/functions/{core_lib_declarations/quantum_functions → builtins/core_library}/exponentiation_functions.py +0 -0
@@ -56,6 +56,7 @@ class AzureQuantumBackendNames(StrEnum):
56
56
  RIGETTI_ASPEN3 = "rigetti.qpu.aspen-m-3"
57
57
  RIGETTI_SIMULATOR = "rigetti.sim.qvm"
58
58
  RIGETTI_ANKAA2 = "rigetti.qpu.ankaa-2"
59
+ RIGETTI_ANKAA9 = "rigetti.qpu.ankaa-9q-1"
59
60
  QCI_MACHINE1 = "qci.machine1"
60
61
  QCI_NOISY_SIMULATOR = "qci.simulator.noisy"
61
62
  QCI_SIMULATOR = "qci.simulator"
@@ -10,6 +10,8 @@ from classiq.interface.helpers.hashable_pydantic_base_model import (
10
10
  HashablePydanticBaseModel,
11
11
  )
12
12
 
13
+ from classiq.exceptions import ClassiqValueError
14
+
13
15
  LadderOperator = Tuple[str, int]
14
16
  FermionicOperatorTuple = Tuple["FermionicOperator", float]
15
17
 
@@ -46,19 +48,19 @@ class FermionicOperator(HashablePydanticBaseModel):
46
48
  try: # type: ignore[unreachable] # it is reachable...
47
49
  op = tuple(op)
48
50
  except Exception as exc:
49
- raise ValueError("Ladder operator should be a tuple.") from exc
51
+ raise ClassiqValueError("Ladder operator should be a tuple.") from exc
50
52
  if len(op) != 2:
51
- raise ValueError(
53
+ raise ClassiqValueError(
52
54
  "Ladder operator tuple should be of length two; for example (1, '+')."
53
55
  )
54
56
 
55
57
  if op[0] not in ("+", "-"):
56
- raise ValueError(
58
+ raise ClassiqValueError(
57
59
  "The first term in a ladder operator tuple indicates if its a raising ('+')"
58
60
  f" or lowering ('-') operator. Allowed input is: '+' or '-', received {op[0]}"
59
61
  )
60
62
  if not isinstance(op[1], int):
61
- raise ValueError(
63
+ raise ClassiqValueError(
62
64
  "The second term in a ladder operator tuple indicates its index and should be of type int"
63
65
  )
64
66
 
@@ -71,7 +73,7 @@ class FermionicOperator(HashablePydanticBaseModel):
71
73
  def __mul__(self, coeff: Union[float, int]) -> SummedFermionicOperator:
72
74
  if isinstance(coeff, (float, int)):
73
75
  return SummedFermionicOperator(op_list=[(self, float(coeff))])
74
- raise ValueError(
76
+ raise ClassiqValueError(
75
77
  "The coefficient multiplying Fermionic Operator should be of type float"
76
78
  )
77
79
 
@@ -84,7 +86,7 @@ class FermionicOperator(HashablePydanticBaseModel):
84
86
  return SummedFermionicOperator(op_list=[(self, 1.0)] + other.op_list)
85
87
  elif isinstance(other, FermionicOperator):
86
88
  return SummedFermionicOperator(op_list=[(self, 1.0)] + [(other, 1.0)])
87
- raise ValueError(
89
+ raise ClassiqValueError(
88
90
  "FermionicOperator can be summed together only with type FermionicOperator or SummedFermionicOperator"
89
91
  )
90
92
 
@@ -135,21 +137,21 @@ class SummedFermionicOperator(HashablePydanticBaseModel):
135
137
  try: # type: ignore[unreachable] # it is reachable...
136
138
  op = tuple(op)
137
139
  except Exception as exc:
138
- raise ValueError("Operator should be a tuple.") from exc
140
+ raise ClassiqValueError("Operator should be a tuple.") from exc
139
141
  if len(op) != 2:
140
- raise ValueError("Operator tuple should be of length two.")
142
+ raise ClassiqValueError("Operator tuple should be of length two.")
141
143
 
142
144
  # is it FermionicOperator - if not, convert to FermionicOperator
143
- if type(op[0]) is not FermionicOperator:
145
+ if not isinstance(op[0], FermionicOperator):
144
146
  try:
145
147
  op = (FermionicOperator(**op[0]), op[1])
146
148
  except Exception as exc:
147
- raise ValueError(
149
+ raise ClassiqValueError(
148
150
  "The first term in the operator tuple should be an instance of the FermionicOperator class"
149
151
  ) from exc
150
152
 
151
- if type(op[1]) is not float:
152
- raise ValueError(
153
+ if not isinstance(op[1], float):
154
+ raise ClassiqValueError(
153
155
  "The second term in the operator tuple indicates its coefficient and should be of type float"
154
156
  )
155
157
 
@@ -166,7 +168,7 @@ class SummedFermionicOperator(HashablePydanticBaseModel):
166
168
  return SummedFermionicOperator(op_list=self.op_list + other.op_list)
167
169
  elif isinstance(other, FermionicOperator):
168
170
  return SummedFermionicOperator(op_list=self.op_list + [(other, 1.0)])
169
- raise ValueError(
171
+ raise ClassiqValueError(
170
172
  "FermionicOperator can be summed together only with type FermionicOperator or SummedFermionicOperator"
171
173
  )
172
174
 
@@ -1,6 +1,8 @@
1
- from typing import Any, Dict, List, Optional, Tuple, Union
1
+ from typing import Any, Dict, List, Literal, Optional, Tuple, Union
2
2
 
3
3
  import pydantic
4
+ from pydantic import Field
5
+ from typing_extensions import Annotated
4
6
 
5
7
  from classiq.interface.chemistry.fermionic_operator import SummedFermionicOperator
6
8
  from classiq.interface.chemistry.molecule import Molecule
@@ -9,6 +11,7 @@ from classiq.interface.helpers.hashable_pydantic_base_model import (
9
11
  )
10
12
 
11
13
  from classiq._internals.enum_utils import StrEnum
14
+ from classiq.exceptions import ClassiqValueError
12
15
 
13
16
  """
14
17
  The correct type hint is:
@@ -37,6 +40,8 @@ class FermionMapping(StrEnum):
37
40
 
38
41
 
39
42
  class GroundStateProblem(HashablePydanticBaseModel):
43
+ kind: str
44
+
40
45
  mapping: FermionMapping = pydantic.Field(
41
46
  default=FermionMapping.JORDAN_WIGNER,
42
47
  description="Fermionic mapping type",
@@ -53,7 +58,7 @@ class GroundStateProblem(HashablePydanticBaseModel):
53
58
  cls, z2_symmetries: bool, values: Dict[str, Any]
54
59
  ) -> bool:
55
60
  if z2_symmetries and values.get("mapping") == FermionMapping.FAST_BRAVYI_KITAEV:
56
- raise ValueError(
61
+ raise ClassiqValueError(
57
62
  "z2 symmetries reduction can not be used for fast_bravyi_kitaev mapping"
58
63
  )
59
64
  return z2_symmetries
@@ -63,6 +68,8 @@ class GroundStateProblem(HashablePydanticBaseModel):
63
68
 
64
69
 
65
70
  class MoleculeProblem(GroundStateProblem):
71
+ kind: Literal["molecule"] = pydantic.Field(default="molecule")
72
+
66
73
  molecule: Molecule
67
74
  basis: str = pydantic.Field(default="sto3g", description="Molecular basis set")
68
75
  freeze_core: bool = pydantic.Field(default=False)
@@ -72,6 +79,8 @@ class MoleculeProblem(GroundStateProblem):
72
79
 
73
80
 
74
81
  class HamiltonianProblem(GroundStateProblem):
82
+ kind: Literal["hamiltonian"] = pydantic.Field(default="hamiltonian")
83
+
75
84
  hamiltonian: SummedFermionicOperator = pydantic.Field(
76
85
  description="Hamiltonian as a fermionic operator"
77
86
  )
@@ -96,5 +105,11 @@ class HamiltonianProblem(GroundStateProblem):
96
105
 
97
106
 
98
107
  CHEMISTRY_PROBLEMS = (MoleculeProblem, HamiltonianProblem)
99
- CHEMISTRY_PROBLEMS_TYPE = Union[MoleculeProblem, HamiltonianProblem]
108
+ CHEMISTRY_PROBLEMS_TYPE = Annotated[
109
+ Union[MoleculeProblem, HamiltonianProblem],
110
+ Field(
111
+ discriminator="kind",
112
+ description="Ground state problem object describing the system.",
113
+ ),
114
+ ]
100
115
  CHEMISTRY_ANSATZ_NAMES = ["hw_efficient", "ucc", "hva"]
@@ -8,6 +8,8 @@ from classiq.interface.helpers.hashable_pydantic_base_model import (
8
8
  HashablePydanticBaseModel,
9
9
  )
10
10
 
11
+ from classiq.exceptions import ClassiqValueError
12
+
11
13
 
12
14
  class Atom(HashablePydanticBaseModel):
13
15
  symbol: Literal[tuple(ELEMENTS)] = pydantic.Field(description="The atom symbol") # type: ignore[valid-type]
@@ -41,20 +43,20 @@ class Molecule(HashablePydanticBaseModel):
41
43
  @staticmethod
42
44
  def _validate_old_atoms_type(atom: AtomType) -> Atom:
43
45
  if len(atom) != 2:
44
- raise ValueError(
46
+ raise ClassiqValueError(
45
47
  "each atom should be a list of two entries: 1) name pf the elemnt (str) 2) list of its (x,y,z) location"
46
48
  )
47
- if type(atom[0]) is not str:
48
- raise ValueError(
49
+ if not isinstance(atom[0], str):
50
+ raise ClassiqValueError(
49
51
  f"atom name should be a string. unknown element: {atom[0]}."
50
52
  )
51
53
  if len(atom[1]) != 3:
52
- raise ValueError(
54
+ raise ClassiqValueError(
53
55
  f"location of the atom is of length three, representing the (x,y,z) coordinates of the atom, error value: {atom[1]}"
54
56
  )
55
57
  for idx in atom[1]:
56
- if type(idx) is not float and type(idx) is not int:
57
- raise ValueError(
58
+ if not isinstance(idx, (float, int)):
59
+ raise ClassiqValueError(
58
60
  f"coordinates of the atom should be of type float. error value: {idx}"
59
61
  )
60
62
  symbol, coordinate = atom
@@ -71,7 +71,7 @@ class PauliOperator(HashablePydanticBaseModel, VersionedModel):
71
71
  @pydantic.validator("pauli_list")
72
72
  def _validate_pauli_list(cls, pauli_list: PydanticPauliList) -> PydanticPauliList:
73
73
  if not all_equal(len(summand[0]) for summand in pauli_list):
74
- raise ValueError("Pauli strings have incompatible lengths.")
74
+ raise ClassiqValueError("Pauli strings have incompatible lengths.")
75
75
  return pauli_list
76
76
 
77
77
  @pydantic.root_validator
@@ -172,16 +172,18 @@ class PauliOperator(HashablePydanticBaseModel, VersionedModel):
172
172
  num_extra_qubits: int,
173
173
  ) -> None:
174
174
  if num_extra_qubits < 0:
175
- raise ValueError("Number of extra qubits cannot be negative")
175
+ raise ClassiqValueError("Number of extra qubits cannot be negative")
176
176
 
177
177
  if len(order) != num_qubits:
178
- raise ValueError("The qubits order doesn't match the Pauli operator")
178
+ raise ClassiqValueError("The qubits order doesn't match the Pauli operator")
179
179
 
180
180
  if len(order) != len(set(order)):
181
- raise ValueError("The qubits order is not one-to-one")
181
+ raise ClassiqValueError("The qubits order is not one-to-one")
182
182
 
183
183
  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")
184
+ raise ClassiqValueError(
185
+ "The qubits order contains qubits which do no exist"
186
+ )
185
187
 
186
188
  @classmethod
187
189
  def reorder(
@@ -209,7 +211,7 @@ class PauliOperator(HashablePydanticBaseModel, VersionedModel):
209
211
  coefficients = [1] * len(operators)
210
212
 
211
213
  if len(operators) != len(coefficients):
212
- raise ValueError(
214
+ raise ClassiqValueError(
213
215
  f"The number of coefficients ({len(coefficients)}) must be equal to the number of pauli operators ({len(operators)})"
214
216
  )
215
217
 
@@ -269,7 +271,7 @@ class PauliOperatorV1(HashablePydanticBaseModel):
269
271
  @pydantic.validator("pauli_list")
270
272
  def _validate_pauli_list(cls, pauli_list: PydanticPauliList) -> PydanticPauliList:
271
273
  if not all_equal(len(summand[0]) for summand in pauli_list):
272
- raise ValueError("Pauli strings have incompatible lengths.")
274
+ raise ClassiqValueError("Pauli strings have incompatible lengths.")
273
275
  return pauli_list
274
276
 
275
277
  @pydantic.root_validator
@@ -370,16 +372,18 @@ class PauliOperatorV1(HashablePydanticBaseModel):
370
372
  num_extra_qubits: int,
371
373
  ) -> None:
372
374
  if num_extra_qubits < 0:
373
- raise ValueError("Number of extra qubits cannot be negative")
375
+ raise ClassiqValueError("Number of extra qubits cannot be negative")
374
376
 
375
377
  if len(order) != num_qubits:
376
- raise ValueError("The qubits order doesn't match the Pauli operator")
378
+ raise ClassiqValueError("The qubits order doesn't match the Pauli operator")
377
379
 
378
380
  if len(order) != len(set(order)):
379
- raise ValueError("The qubits order is not one-to-one")
381
+ raise ClassiqValueError("The qubits order is not one-to-one")
380
382
 
381
383
  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")
384
+ raise ClassiqValueError(
385
+ "The qubits order contains qubits which do no exist"
386
+ )
383
387
 
384
388
  @classmethod
385
389
  def reorder(
@@ -407,7 +411,7 @@ class PauliOperatorV1(HashablePydanticBaseModel):
407
411
  coefficients = [1] * len(operators)
408
412
 
409
413
  if len(operators) != len(coefficients):
410
- raise ValueError(
414
+ raise ClassiqValueError(
411
415
  f"The number of coefficients ({len(coefficients)}) must be equal to the number of pauli operators ({len(operators)})"
412
416
  )
413
417
 
@@ -448,7 +452,7 @@ def to_pauli_matrix(pauli_op: PydanticPauliMonomialStr) -> np.ndarray:
448
452
 
449
453
  def validate_operator_is_hermitian(pauli_operator: PauliOperator) -> PauliOperator:
450
454
  if not pauli_operator.is_hermitian:
451
- raise ValueError("Coefficients of the Hamiltonian must be real numbers")
455
+ raise ClassiqValueError("Coefficients of the Hamiltonian must be real numbers")
452
456
  return pauli_operator
453
457
 
454
458
 
@@ -456,7 +460,9 @@ def validate_operator_has_no_complex_coefficients(
456
460
  pauli_operator: PauliOperator,
457
461
  ) -> PauliOperator:
458
462
  if pauli_operator.has_complex_coefficients:
459
- raise ValueError("Coefficients of the Hamiltonian mustn't be complex numbers")
463
+ raise ClassiqValueError(
464
+ "Coefficients of the Hamiltonian mustn't be complex numbers"
465
+ )
460
466
  return pauli_operator
461
467
 
462
468
 
@@ -11,7 +11,7 @@ def ascending_sequence(coeffs: List[int], bound: int) -> pyo.ConcreteModel:
11
11
  )
12
12
 
13
13
  @model.Constraint(range(len(coeffs) - 1))
14
- def monotone_rule(model, idx):
14
+ def monotone_rule(model: pyo.ConcreteModel, idx: int) -> pyo.ExpressionBase:
15
15
  return model.x[idx] <= model.x[idx + 1]
16
16
 
17
17
  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,4 +1,4 @@
1
- from typing import List
1
+ from typing import List, Tuple
2
2
 
3
3
  import numpy as np
4
4
  import pyomo.core as pyo
@@ -10,7 +10,7 @@ def integer_portfolio_optimization(
10
10
  model = pyo.ConcreteModel()
11
11
  num_assets = len(returns)
12
12
 
13
- def bounds(_, i):
13
+ def bounds(model: pyo.ConcreteModel, i: int) -> Tuple[int, int]:
14
14
  return 0, upper_bounds[i]
15
15
 
16
16
  model.x = pyo.Var(range(num_assets), domain=pyo.NonNegativeIntegers, bounds=bounds)
@@ -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
 
@@ -3,6 +3,7 @@ from typing import Dict, Tuple
3
3
 
4
4
  import networkx as nx
5
5
  import pyomo.core as pyo
6
+ import pyomo.core.expr.numeric_expr as pyo_expr
6
7
 
7
8
  Node = int
8
9
  Edge = Tuple[Node, Node]
@@ -22,7 +23,9 @@ def build_mht_pyomo_model(
22
23
  if has_constraints:
23
24
 
24
25
  @model.Constraint(model.Nodes)
25
- def out_edges_rule(model, idx):
26
+ def out_edges_rule(
27
+ model: pyo.ConcreteModel, idx: int
28
+ ) -> pyo_expr.ExpressionBase:
26
29
  out_nodes = [
27
30
  node_id for node_id in model.Nodes if [idx, node_id] in model.Arcs
28
31
  ]
@@ -32,7 +35,9 @@ def build_mht_pyomo_model(
32
35
  return pyo.Constraint.Feasible
33
36
 
34
37
  @model.Constraint(model.Nodes)
35
- def in_edges_rule(model, idx):
38
+ def in_edges_rule(
39
+ model: pyo.ConcreteModel, idx: int
40
+ ) -> pyo_expr.ExpressionBase:
36
41
  in_nodes = [
37
42
  node_id for node_id in model.Nodes if [node_id, idx] in model.Arcs
38
43
  ]
@@ -41,7 +46,7 @@ def build_mht_pyomo_model(
41
46
  else:
42
47
  return pyo.Constraint.Feasible
43
48
 
44
- def obj_expression(model):
49
+ def obj_expression(model: pyo.ConcreteModel) -> pyo_expr.ExpressionBase:
45
50
  return sum(
46
51
  round(pubo_energy, _decimals)
47
52
  * math.prod(model.x[edge] for edge in pubo_edges)
@@ -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 mis(graph: nx.Graph) -> pyo.ConcreteModel:
@@ -7,7 +8,9 @@ def mis(graph: nx.Graph) -> pyo.ConcreteModel:
7
8
  model.x = pyo.Var(graph.nodes, domain=pyo.Binary)
8
9
 
9
10
  @model.Constraint(graph.edges)
10
- def independent_rule(model, node1, node2):
11
+ def independent_rule(
12
+ model: pyo.ConcreteModel, node1: int, node2: int
13
+ ) -> pyo_expr.ExpressionBase:
11
14
  return model.x[node1] + model.x[node2] <= 1
12
15
 
13
16
  model.cost = pyo.Objective(expr=sum(model.x.values()), sense=pyo.maximize)
@@ -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 mvc(graph: nx.Graph, k: int) -> pyo.ConcreteModel:
@@ -7,7 +8,7 @@ def mvc(graph: nx.Graph, k: int) -> pyo.ConcreteModel:
7
8
  model.x = pyo.Var(graph.nodes, domain=pyo.Binary)
8
9
  model.amount_constraint = pyo.Constraint(expr=sum(model.x.values()) == k)
9
10
 
10
- def obj_expression(model):
11
+ def obj_expression(model: pyo.ConcreteModel) -> pyo_expr.ExpressionBase:
11
12
  # number of edges not covered
12
13
  return sum((1 - model.x[i]) * (1 - model.x[j]) for i, j in graph.edges)
13
14
 
@@ -2,6 +2,7 @@ import itertools
2
2
  from typing import List
3
3
 
4
4
  import pyomo.core as pyo
5
+ import pyomo.core.expr.numeric_expr as pyo_expr
5
6
 
6
7
 
7
8
  def set_cover(sub_sets: List[List[int]]) -> pyo.ConcreteModel:
@@ -16,7 +17,7 @@ def set_cover(sub_sets: List[List[int]]) -> pyo.ConcreteModel:
16
17
  model.x = pyo.Var(range(num_sets), domain=pyo.Binary)
17
18
 
18
19
  @model.Constraint(entire_set)
19
- def independent_rule(model, num):
20
+ def independent_rule(model: pyo.ConcreteModel, num: int) -> pyo_expr.ExpressionBase:
20
21
  return sum(model.x[idx] for idx in range(num_sets) if num in sub_sets[idx]) >= 1
21
22
 
22
23
  model.cost = pyo.Objective(expr=sum(model.x.values()), sense=pyo.minimize)
@@ -2,6 +2,7 @@ import itertools
2
2
 
3
3
  import numpy as np
4
4
  import pyomo.core as pyo
5
+ import pyomo.core.expr.numeric_expr as pyo_expr
5
6
 
6
7
 
7
8
  def tsp(distance_matrix: np.ndarray) -> pyo.ConcreteModel:
@@ -22,16 +23,16 @@ def tsp(distance_matrix: np.ndarray) -> pyo.ConcreteModel:
22
23
  @model.Constraint(points)
23
24
  def each_step_visits_one_point_rule(
24
25
  model: pyo.ConcreteModel, ii: int
25
- ) -> pyo.ExpressionBase:
26
+ ) -> pyo_expr.ExpressionBase:
26
27
  return sum(model.x[ii, jj] for jj in range(num_points)) == 1
27
28
 
28
29
  @model.Constraint(points)
29
30
  def each_point_visited_once_rule(
30
31
  model: pyo.ConcreteModel, jj: int
31
- ) -> pyo.ExpressionBase:
32
+ ) -> pyo_expr.ExpressionBase:
32
33
  return sum(model.x[ii, jj] for ii in range(num_points)) == 1
33
34
 
34
- def is_travel_between_2_points(point1: int, point2: int) -> pyo.ExpressionBase:
35
+ def is_travel_between_2_points(point1: int, point2: int) -> pyo_expr.ExpressionBase:
35
36
  return sum(model.x[point1, kk] * model.x[point2, kk + 1] for kk in points[:-1])
36
37
 
37
38
  model.cost = pyo.Objective(
@@ -21,11 +21,15 @@ def tsp_digraph(
21
21
  ) # x[i, j] = 1 indicates that point i is visited at step j
22
22
 
23
23
  @model.Constraint(points)
24
- def each_step_visits_one_point_rule(model, ii):
24
+ def each_step_visits_one_point_rule(
25
+ model: pyo.ConcreteModel, ii: int
26
+ ) -> pyo.ExpressionBase:
25
27
  return sum(model.x[ii, jj] for jj in steps) == 1
26
28
 
27
29
  @model.Constraint(steps)
28
- def each_point_visited_once_rule(model, jj):
30
+ def each_point_visited_once_rule(
31
+ model: pyo.ConcreteModel, jj: int
32
+ ) -> pyo.ExpressionBase:
29
33
  return sum(model.x[ii, jj] for ii in points) == 1
30
34
 
31
35
  def is_travel_between_2_points(point1: int, point2: int) -> pyo.ExpressionBase:
@@ -5,6 +5,8 @@ import numpy as np
5
5
  import pydantic
6
6
  from pydantic import BaseModel
7
7
 
8
+ from classiq.exceptions import ClassiqValueError
9
+
8
10
  _TOLERANCE_DECIMALS = 6
9
11
 
10
12
 
@@ -52,7 +54,9 @@ class MhtQaoaInput(BaseModel):
52
54
  return True
53
55
 
54
56
  @pydantic.validator("plot_list")
55
- def round_plot_list_times_and_validate(cls, plot_list):
57
+ def round_plot_list_times_and_validate(
58
+ cls, plot_list: List[PlotData]
59
+ ) -> List[PlotData]:
56
60
  MhtQaoaInput._check_all_ids_are_distinct(plot_list)
57
61
  MhtQaoaInput._round_to_tolerance_decimals(plot_list)
58
62
 
@@ -63,7 +67,9 @@ class MhtQaoaInput(BaseModel):
63
67
  }
64
68
 
65
69
  if len(time_diff_set) != 1:
66
- raise ValueError("The time difference between each time stamp is not equal")
70
+ raise ClassiqValueError(
71
+ "The time difference between each time stamp is not equal"
72
+ )
67
73
 
68
74
  return plot_list
69
75
 
@@ -75,4 +81,4 @@ class MhtQaoaInput(BaseModel):
75
81
  @staticmethod
76
82
  def _check_all_ids_are_distinct(plot_list: List[PlotData]) -> None:
77
83
  if not more_itertools.all_unique(plot.plot_id for plot in plot_list):
78
- raise ValueError("Plot IDs should be unique.")
84
+ raise ClassiqValueError("Plot IDs should be unique.")
@@ -1,10 +1,11 @@
1
1
  from datetime import date
2
- from typing import List, Optional
2
+ from typing import Any, Dict, List, Optional
3
3
 
4
4
  import pydantic
5
5
  from pydantic import validator
6
6
 
7
7
  from classiq._internals.enum_utils import StrEnum
8
+ from classiq.exceptions import ClassiqValueError
8
9
 
9
10
 
10
11
  class Granularity(StrEnum):
@@ -37,9 +38,9 @@ class ExecutionCostForTimePeriod(pydantic.BaseModel):
37
38
  json_encoders = {date: lambda v: v.strftime("%Y-%m-%d")}
38
39
 
39
40
  @validator("end")
40
- def date_order(cls, v, values, **kwargs):
41
+ def date_order(cls, v: date, values: Dict[str, Any], **kwargs: Any) -> date:
41
42
  if "start" in values and v <= values["start"]:
42
- raise ValueError('"end" date should be after "start" date')
43
+ raise ClassiqValueError('"end" date should be after "start" date')
43
44
  return v
44
45
 
45
46
 
@@ -1,7 +1,7 @@
1
1
  import pydantic
2
2
 
3
3
  from classiq.interface.chemistry.operator import PauliOperators
4
- from classiq.interface.executor.quantum_program import QuantumProgram
4
+ from classiq.interface.executor.quantum_code import QuantumCode
5
5
 
6
6
 
7
7
  class OperatorsEstimation(pydantic.BaseModel):
@@ -10,5 +10,5 @@ class OperatorsEstimation(pydantic.BaseModel):
10
10
  by a quantum program.
11
11
  """
12
12
 
13
- quantum_program: QuantumProgram
13
+ quantum_program: QuantumCode
14
14
  operators: PauliOperators