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