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,28 +1,30 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
3
|
from pathlib import Path
|
4
|
-
from typing import Any,
|
4
|
+
from typing import Any, Optional, Union
|
5
5
|
|
6
6
|
import pydantic
|
7
|
-
from pydantic import BaseModel
|
7
|
+
from pydantic import BaseModel, ConfigDict
|
8
|
+
from pydantic_core.core_schema import ValidationInfo
|
8
9
|
|
9
|
-
from classiq.interface.backend.ionq import
|
10
|
+
from classiq.interface.backend.ionq.ionq_quantum_program import IonqQuantumCircuit
|
10
11
|
from classiq.interface.backend.pydantic_backend import PydanticArgumentNameType
|
12
|
+
from classiq.interface.exceptions import ClassiqValueError
|
11
13
|
from classiq.interface.executor.quantum_instruction_set import QuantumInstructionSet
|
12
14
|
from classiq.interface.executor.register_initialization import RegisterInitialization
|
13
15
|
from classiq.interface.generator.synthesis_metadata.synthesis_execution_data import (
|
14
16
|
ExecutionData,
|
15
17
|
)
|
16
18
|
|
17
|
-
Arguments =
|
18
|
-
MultipleArguments =
|
19
|
-
CodeType =
|
20
|
-
RegistersInitialization =
|
21
|
-
Qubits =
|
22
|
-
OutputQubitsMap =
|
19
|
+
Arguments = dict[PydanticArgumentNameType, Any]
|
20
|
+
MultipleArguments = tuple[Arguments, ...]
|
21
|
+
CodeType = str
|
22
|
+
RegistersInitialization = dict[str, RegisterInitialization]
|
23
|
+
Qubits = tuple[int, ...]
|
24
|
+
OutputQubitsMap = dict[str, Qubits]
|
23
25
|
|
24
26
|
|
25
|
-
class
|
27
|
+
class QuantumBaseCode(BaseModel):
|
26
28
|
syntax: QuantumInstructionSet = pydantic.Field(
|
27
29
|
default=QuantumInstructionSet.QASM, description="The syntax of the program."
|
28
30
|
)
|
@@ -30,18 +32,23 @@ class QuantumBaseProgram(BaseModel):
|
|
30
32
|
..., description="The textual representation of the program"
|
31
33
|
)
|
32
34
|
|
33
|
-
@pydantic.
|
34
|
-
|
35
|
-
|
36
|
-
|
35
|
+
@pydantic.field_validator("code")
|
36
|
+
@classmethod
|
37
|
+
def load_quantum_program(
|
38
|
+
cls, code: Union[CodeType, IonqQuantumCircuit], values: ValidationInfo
|
39
|
+
) -> CodeType:
|
40
|
+
syntax = values.data.get("syntax")
|
41
|
+
if isinstance(code, IonqQuantumCircuit):
|
42
|
+
if syntax != QuantumInstructionSet.IONQ:
|
43
|
+
raise ClassiqValueError(
|
44
|
+
f"Invalid code type {type(code)} for syntax: {syntax}"
|
45
|
+
)
|
46
|
+
return code.model_dump_json()
|
37
47
|
|
38
|
-
syntax = values.get("syntax")
|
39
|
-
if syntax == QuantumInstructionSet.IONQ:
|
40
|
-
return ionq_quantum_program.IonqQuantumCircuit.from_string(code)
|
41
48
|
return code
|
42
49
|
|
43
50
|
|
44
|
-
class
|
51
|
+
class QuantumCode(QuantumBaseCode):
|
45
52
|
arguments: MultipleArguments = pydantic.Field(
|
46
53
|
default=(),
|
47
54
|
description="The parameters dictionary for a parametrized quantum program.",
|
@@ -51,43 +58,46 @@ class QuantumProgram(QuantumBaseProgram):
|
|
51
58
|
description="The map of outputs to their qubits in the circuit.",
|
52
59
|
)
|
53
60
|
registers_initialization: Optional[RegistersInitialization] = pydantic.Field(
|
54
|
-
|
61
|
+
default=None,
|
55
62
|
description="Initial conditions for the different registers in the circuit.",
|
56
63
|
)
|
57
64
|
synthesis_execution_data: Optional[ExecutionData] = pydantic.Field(default=None)
|
58
65
|
synthesis_execution_arguments: Arguments = pydantic.Field(default_factory=dict)
|
66
|
+
model_config = ConfigDict(validate_assignment=True)
|
59
67
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
@pydantic.validator("arguments")
|
68
|
+
@pydantic.field_validator("arguments", mode="before")
|
69
|
+
@classmethod
|
64
70
|
def validate_arguments(
|
65
|
-
cls, arguments: MultipleArguments,
|
71
|
+
cls, arguments: MultipleArguments, info: ValidationInfo
|
66
72
|
) -> MultipleArguments:
|
67
|
-
if arguments and
|
73
|
+
if arguments and info.data.get("syntax") not in (
|
68
74
|
QuantumInstructionSet.QSHARP,
|
69
75
|
QuantumInstructionSet.QASM,
|
70
76
|
):
|
71
|
-
raise
|
77
|
+
raise ClassiqValueError("Only QASM or Q# programs support arguments")
|
72
78
|
|
73
|
-
if
|
74
|
-
|
79
|
+
if (
|
80
|
+
info.data.get("syntax") == QuantumInstructionSet.QSHARP
|
81
|
+
and len(arguments) > 1
|
82
|
+
):
|
83
|
+
raise ClassiqValueError(
|
75
84
|
f"Q# programs supports only one group of arguments. {len(arguments)} given"
|
76
85
|
)
|
77
86
|
|
78
87
|
return arguments
|
79
88
|
|
80
|
-
@pydantic.
|
89
|
+
@pydantic.field_validator("synthesis_execution_data")
|
90
|
+
@classmethod
|
81
91
|
def validate_synthesis_execution_data(
|
82
92
|
cls,
|
83
93
|
synthesis_execution_data: Optional[ExecutionData],
|
84
|
-
values:
|
94
|
+
values: ValidationInfo,
|
85
95
|
) -> Optional[ExecutionData]:
|
86
96
|
if (
|
87
97
|
synthesis_execution_data is not None
|
88
|
-
and values.get("syntax") is not QuantumInstructionSet.QASM
|
98
|
+
and values.data.get("syntax") is not QuantumInstructionSet.QASM
|
89
99
|
):
|
90
|
-
raise
|
100
|
+
raise ClassiqValueError("Only QASM supports the requested configuration")
|
91
101
|
|
92
102
|
return synthesis_execution_data
|
93
103
|
|
@@ -96,9 +106,9 @@ class QuantumProgram(QuantumBaseProgram):
|
|
96
106
|
file_path: Union[str, Path],
|
97
107
|
syntax: Optional[Union[str, QuantumInstructionSet]] = None,
|
98
108
|
arguments: MultipleArguments = (),
|
99
|
-
) ->
|
109
|
+
) -> QuantumCode:
|
100
110
|
path = Path(file_path)
|
101
111
|
code = path.read_text()
|
102
112
|
if syntax is None:
|
103
113
|
syntax = QuantumInstructionSet.from_suffix(path.suffix.lstrip("."))
|
104
|
-
return
|
114
|
+
return QuantumCode(syntax=syntax, code=code, arguments=arguments)
|
@@ -1,4 +1,5 @@
|
|
1
|
-
from classiq.
|
1
|
+
from classiq.interface.enum_utils import StrEnum
|
2
|
+
from classiq.interface.exceptions import ClassiqValueError
|
2
3
|
|
3
4
|
|
4
5
|
class QuantumInstructionSet(StrEnum):
|
@@ -14,4 +15,4 @@ class QuantumInstructionSet(StrEnum):
|
|
14
15
|
return QuantumInstructionSet.QSHARP
|
15
16
|
if suffix == "ionq":
|
16
17
|
return QuantumInstructionSet.IONQ
|
17
|
-
raise
|
18
|
+
raise ClassiqValueError("Illegal suffix")
|
@@ -1,11 +1,9 @@
|
|
1
|
-
from typing import Any, Dict, List
|
2
|
-
|
3
1
|
import pydantic
|
2
|
+
from typing_extensions import Self
|
4
3
|
|
4
|
+
from classiq.interface.exceptions import ClassiqStateInitializationError
|
5
5
|
from classiq.interface.generator.arith import number_utils
|
6
6
|
|
7
|
-
from classiq.exceptions import ClassiqStateInitializationError
|
8
|
-
|
9
7
|
_NON_INTEGER_INITIALIZATION_ERROR_MSG: str = (
|
10
8
|
"Only natural numbers are supported as initial conditions"
|
11
9
|
)
|
@@ -13,29 +11,26 @@ _NON_INTEGER_INITIALIZATION_ERROR_MSG: str = (
|
|
13
11
|
|
14
12
|
class RegisterInitialization(pydantic.BaseModel):
|
15
13
|
name: str
|
16
|
-
qubits:
|
14
|
+
qubits: list[int]
|
17
15
|
initial_condition: pydantic.NonNegativeInt
|
18
16
|
|
19
|
-
@pydantic.
|
17
|
+
@pydantic.field_validator("initial_condition", mode="before")
|
18
|
+
@classmethod
|
20
19
|
def _validate_initial_condition(cls, value: int) -> int:
|
21
20
|
if not isinstance(value, int) or value < 0:
|
22
21
|
raise ClassiqStateInitializationError(_NON_INTEGER_INITIALIZATION_ERROR_MSG)
|
23
22
|
return value
|
24
23
|
|
25
|
-
@pydantic.
|
26
|
-
def _validate_register_initialization(
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
initial_condition: int = values.get("initial_condition", 0)
|
31
|
-
name: str = values.get("name", "")
|
24
|
+
@pydantic.model_validator(mode="after")
|
25
|
+
def _validate_register_initialization(self) -> Self:
|
26
|
+
qubits: list[int] = self.qubits or []
|
27
|
+
initial_condition: int = self.initial_condition or 0
|
28
|
+
name: str = self.name or ""
|
32
29
|
|
33
|
-
initial_condition_length = number_utils.size(
|
34
|
-
initial_condition, machine_precision=number_utils.MAX_FRACTION_PLACES
|
35
|
-
)
|
30
|
+
initial_condition_length = number_utils.size(initial_condition)
|
36
31
|
register_length = len(qubits)
|
37
32
|
if initial_condition_length > register_length:
|
38
33
|
raise ClassiqStateInitializationError(
|
39
34
|
f"Register {name} has {register_length} qubits, which is not enough to represent the number {initial_condition}."
|
40
35
|
)
|
41
|
-
return
|
36
|
+
return self
|
@@ -1,51 +1,64 @@
|
|
1
1
|
import functools
|
2
2
|
import operator
|
3
3
|
from collections import defaultdict
|
4
|
+
from collections.abc import Iterator, Mapping
|
4
5
|
from typing import (
|
6
|
+
TYPE_CHECKING,
|
5
7
|
Any,
|
6
8
|
DefaultDict,
|
7
|
-
Dict,
|
8
|
-
Iterator,
|
9
|
-
List,
|
10
|
-
Mapping,
|
11
9
|
Optional,
|
12
|
-
Tuple,
|
13
10
|
Union,
|
14
11
|
)
|
15
12
|
|
16
13
|
import pydantic
|
17
14
|
from pydantic import BaseModel
|
18
|
-
from typing_extensions import TypeAlias
|
15
|
+
from typing_extensions import Self, TypeAlias
|
19
16
|
|
20
|
-
from classiq.interface.
|
17
|
+
from classiq.interface.exceptions import ClassiqError
|
18
|
+
from classiq.interface.executor.quantum_code import OutputQubitsMap, Qubits
|
21
19
|
from classiq.interface.generator.arith import number_utils
|
22
20
|
from classiq.interface.generator.complex_type import Complex
|
23
21
|
from classiq.interface.generator.functions.classical_type import QmodPyObject
|
24
22
|
from classiq.interface.helpers.custom_pydantic_types import PydanticNonNegIntTuple
|
23
|
+
from classiq.interface.helpers.datastructures import get_sdk_compatible_python_object
|
25
24
|
from classiq.interface.helpers.versioned_model import VersionedModel
|
26
25
|
|
27
|
-
from classiq.exceptions import ClassiqError
|
28
|
-
|
29
26
|
_ILLEGAL_QUBIT_ERROR_MSG: str = "Illegal qubit index requested"
|
30
27
|
_REPEATED_QUBIT_ERROR_MSG: str = "Requested a qubit more than once"
|
31
28
|
_UNAVAILABLE_OUTPUT_ERROR_MSG: str = "Requested output doesn't exist in the circuit"
|
32
29
|
|
33
30
|
State: TypeAlias = str
|
34
31
|
Name: TypeAlias = str
|
35
|
-
RegisterValue: TypeAlias = Union[float, int]
|
32
|
+
RegisterValue: TypeAlias = Union[float, int, list, dict]
|
36
33
|
MeasuredShots: TypeAlias = pydantic.NonNegativeInt
|
37
34
|
ParsedState: TypeAlias = Mapping[Name, RegisterValue]
|
38
35
|
ParsedStates: TypeAlias = Mapping[State, ParsedState]
|
39
|
-
Counts: TypeAlias =
|
40
|
-
StateVector: TypeAlias = Optional[
|
36
|
+
Counts: TypeAlias = dict[State, MeasuredShots]
|
37
|
+
StateVector: TypeAlias = Optional[dict[str, Complex]]
|
38
|
+
|
39
|
+
if TYPE_CHECKING:
|
40
|
+
DotAccessParsedState = Mapping[Name, Any]
|
41
|
+
else:
|
42
|
+
DotAccessParsedState = ParsedState
|
41
43
|
|
42
44
|
|
43
45
|
class SampledState(BaseModel):
|
44
|
-
state:
|
46
|
+
state: DotAccessParsedState
|
45
47
|
shots: MeasuredShots
|
46
48
|
|
49
|
+
def __repr__(self) -> str:
|
50
|
+
return f"{self.state}: {self.shots}"
|
51
|
+
|
52
|
+
@pydantic.field_validator("state", mode="after")
|
53
|
+
@classmethod
|
54
|
+
def _make_state_sdk_compatible(cls, state: ParsedState) -> DotAccessParsedState:
|
55
|
+
return {
|
56
|
+
name: get_sdk_compatible_python_object(value)
|
57
|
+
for name, value in state.items()
|
58
|
+
}
|
59
|
+
|
47
60
|
|
48
|
-
ParsedCounts: TypeAlias =
|
61
|
+
ParsedCounts: TypeAlias = list[SampledState]
|
49
62
|
|
50
63
|
|
51
64
|
class SimulatedState(BaseModel):
|
@@ -57,7 +70,8 @@ class SimulatedState(BaseModel):
|
|
57
70
|
return self.state[item]
|
58
71
|
|
59
72
|
|
60
|
-
|
73
|
+
SimulatedState.model_rebuild()
|
74
|
+
ParsedStateVector: TypeAlias = list[SimulatedState]
|
61
75
|
|
62
76
|
|
63
77
|
class VaRResult(BaseModel):
|
@@ -66,10 +80,10 @@ class VaRResult(BaseModel):
|
|
66
80
|
|
67
81
|
|
68
82
|
class GroverSimulationResults(VersionedModel):
|
69
|
-
result:
|
83
|
+
result: dict[str, Any]
|
70
84
|
|
71
85
|
|
72
|
-
def _validate_qubit_indices(counts: Counts, indices:
|
86
|
+
def _validate_qubit_indices(counts: Counts, indices: tuple[int, ...]) -> None:
|
73
87
|
if not indices:
|
74
88
|
raise ClassiqError(_ILLEGAL_QUBIT_ERROR_MSG)
|
75
89
|
|
@@ -80,7 +94,7 @@ def _validate_qubit_indices(counts: Counts, indices: Tuple[int, ...]) -> None:
|
|
80
94
|
raise ClassiqError(_REPEATED_QUBIT_ERROR_MSG)
|
81
95
|
|
82
96
|
|
83
|
-
def _slice_str(s: str, indices:
|
97
|
+
def _slice_str(s: str, indices: tuple[int, ...]) -> str:
|
84
98
|
return "".join(s[i] for i in indices)
|
85
99
|
|
86
100
|
|
@@ -97,8 +111,47 @@ def get_sampled_state(
|
|
97
111
|
return None
|
98
112
|
|
99
113
|
|
114
|
+
def reduce_parsed_states(
|
115
|
+
parsed_states: ParsedStates, outputs: tuple[Name, ...]
|
116
|
+
) -> ParsedStates:
|
117
|
+
return {
|
118
|
+
state: {
|
119
|
+
output: value for output, value in parsed_state.items() if output in outputs
|
120
|
+
}
|
121
|
+
for state, parsed_state in parsed_states.items()
|
122
|
+
}
|
123
|
+
|
124
|
+
|
125
|
+
def get_parsed_counts(counts: Counts, parsed_states: ParsedStates) -> ParsedCounts:
|
126
|
+
parsed_counts: ParsedCounts = []
|
127
|
+
for bitstring, count in counts.items():
|
128
|
+
parsed_state = parsed_states[bitstring]
|
129
|
+
if sampled_state := get_sampled_state(parsed_counts, parsed_state):
|
130
|
+
sampled_state.shots += count
|
131
|
+
else:
|
132
|
+
parsed_counts.append(SampledState(state=parsed_state, shots=count))
|
133
|
+
return sorted(parsed_counts, key=lambda k: k.shots, reverse=True)
|
134
|
+
|
135
|
+
|
136
|
+
def prepare_parsed_state_vector(
|
137
|
+
state_vector: StateVector, parsed_state_vector_states: ParsedStates
|
138
|
+
) -> Optional[ParsedStateVector]:
|
139
|
+
if not state_vector:
|
140
|
+
return None
|
141
|
+
|
142
|
+
parsed_state_vector = [
|
143
|
+
SimulatedState(
|
144
|
+
state=parsed_state_vector_states[bitstring],
|
145
|
+
bitstring=bitstring,
|
146
|
+
amplitude=complex(amplitude_str),
|
147
|
+
)
|
148
|
+
for bitstring, amplitude_str in state_vector.items()
|
149
|
+
]
|
150
|
+
return sorted(parsed_state_vector, key=lambda k: abs(k.amplitude), reverse=True)
|
151
|
+
|
152
|
+
|
100
153
|
class ExecutionDetails(BaseModel, QmodPyObject):
|
101
|
-
vendor_format_result:
|
154
|
+
vendor_format_result: dict[str, Any] = pydantic.Field(
|
102
155
|
..., description="Result in proprietary vendor format"
|
103
156
|
)
|
104
157
|
counts: Counts = pydantic.Field(
|
@@ -108,11 +161,14 @@ class ExecutionDetails(BaseModel, QmodPyObject):
|
|
108
161
|
True,
|
109
162
|
description="Is the qubit order of counts field such that the LSB is right?",
|
110
163
|
)
|
164
|
+
probabilities: dict[State, pydantic.NonNegativeFloat] = pydantic.Field(
|
165
|
+
default_factory=dict, description="Probabilities of each state"
|
166
|
+
)
|
111
167
|
parsed_states: ParsedStates = pydantic.Field(
|
112
168
|
default_factory=dict,
|
113
169
|
description="A mapping between the raw states of counts (bitstrings) to their parsed states (registers' values)",
|
114
170
|
)
|
115
|
-
histogram: Optional[
|
171
|
+
histogram: Optional[dict[State, pydantic.NonNegativeFloat]] = pydantic.Field(
|
116
172
|
None,
|
117
173
|
description="Histogram of probability per state (an alternative to counts)",
|
118
174
|
)
|
@@ -124,7 +180,7 @@ class ExecutionDetails(BaseModel, QmodPyObject):
|
|
124
180
|
default=None,
|
125
181
|
description="The state vector when executed on a simulator, with LSB right qubit order",
|
126
182
|
)
|
127
|
-
parsed_state_vector_states: ParsedStates = pydantic.Field(
|
183
|
+
parsed_state_vector_states: Optional[ParsedStates] = pydantic.Field(
|
128
184
|
default=None,
|
129
185
|
description="A mapping between the raw states of the state vector (bitstrings) to their parsed states (registers' values)",
|
130
186
|
)
|
@@ -136,47 +192,35 @@ class ExecutionDetails(BaseModel, QmodPyObject):
|
|
136
192
|
default=None, description="The total number of shots the circuit was executed"
|
137
193
|
)
|
138
194
|
|
139
|
-
@pydantic.
|
195
|
+
@pydantic.field_validator("counts", mode="after")
|
196
|
+
@classmethod
|
140
197
|
def _clean_spaces_from_counts_keys(cls, v: Counts) -> Counts:
|
141
198
|
if not v or " " not in list(v.keys())[0]:
|
142
199
|
return v
|
143
200
|
return {state.replace(" ", ""): v[state] for state in v}
|
144
201
|
|
145
|
-
@pydantic.
|
146
|
-
def _validate_num_shots(
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
return
|
202
|
+
@pydantic.model_validator(mode="after")
|
203
|
+
def _validate_num_shots(self) -> Self:
|
204
|
+
if isinstance(self, ExecutionDetails):
|
205
|
+
if self.num_shots is not None:
|
206
|
+
return self
|
207
|
+
counts = self.counts
|
208
|
+
if not counts:
|
209
|
+
return self
|
210
|
+
self.num_shots = sum(shots for _, shots in counts.items())
|
211
|
+
return self
|
155
212
|
|
156
213
|
@property
|
157
214
|
def parsed_counts(self) -> ParsedCounts:
|
158
|
-
|
159
|
-
for bitstring, count in self.counts.items():
|
160
|
-
parsed_state = self.parsed_states[bitstring]
|
161
|
-
if sampled_state := get_sampled_state(parsed_counts, parsed_state):
|
162
|
-
sampled_state.shots += count
|
163
|
-
else:
|
164
|
-
parsed_counts.append(SampledState(state=parsed_state, shots=count))
|
165
|
-
return sorted(parsed_counts, key=lambda k: k.shots, reverse=True)
|
215
|
+
return get_parsed_counts(self.counts, self.parsed_states)
|
166
216
|
|
167
217
|
@property
|
168
218
|
def parsed_state_vector(self) -> Optional[ParsedStateVector]:
|
169
|
-
if
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
bitstring=bitstring,
|
175
|
-
amplitude=complex(amplitude_str),
|
176
|
-
)
|
177
|
-
for bitstring, amplitude_str in self.state_vector.items()
|
178
|
-
]
|
179
|
-
return sorted(parsed_state_vector, key=lambda k: abs(k.amplitude), reverse=True)
|
219
|
+
if TYPE_CHECKING:
|
220
|
+
assert self.parsed_state_vector_states is not None
|
221
|
+
return prepare_parsed_state_vector(
|
222
|
+
self.state_vector, self.parsed_state_vector_states
|
223
|
+
)
|
180
224
|
|
181
225
|
def flip_execution_counts_bitstring(self) -> None:
|
182
226
|
"""Backends should return result count bitstring in right to left form"""
|
@@ -207,15 +251,15 @@ class ExecutionDetails(BaseModel, QmodPyObject):
|
|
207
251
|
return self.counts_of_qubits(*self.output_qubits_map[output_name])
|
208
252
|
|
209
253
|
def counts_of_multiple_outputs(
|
210
|
-
self, output_names:
|
211
|
-
) ->
|
254
|
+
self, output_names: tuple[Name, ...]
|
255
|
+
) -> dict[tuple[State, ...], pydantic.NonNegativeInt]:
|
212
256
|
if any(name not in self.output_qubits_map for name in output_names):
|
213
257
|
raise ClassiqError(_UNAVAILABLE_OUTPUT_ERROR_MSG)
|
214
258
|
|
215
|
-
output_regs:
|
259
|
+
output_regs: tuple[Qubits, ...] = tuple(
|
216
260
|
self.output_qubits_map[name] for name in output_names
|
217
261
|
)
|
218
|
-
reduced_counts: DefaultDict[
|
262
|
+
reduced_counts: DefaultDict[tuple[State, ...], int] = defaultdict(int)
|
219
263
|
for state_str, state_count in self.counts_by_qubit_order(
|
220
264
|
lsb_right=False
|
221
265
|
).items():
|
@@ -223,8 +267,19 @@ class ExecutionDetails(BaseModel, QmodPyObject):
|
|
223
267
|
reduced_counts[reduced_strs] += state_count
|
224
268
|
return dict(reduced_counts)
|
225
269
|
|
226
|
-
def
|
227
|
-
|
270
|
+
def parsed_counts_of_outputs(
|
271
|
+
self, output_names: Union[Name, tuple[Name, ...]]
|
272
|
+
) -> ParsedCounts:
|
273
|
+
if isinstance(output_names, Name):
|
274
|
+
output_names = (output_names,)
|
275
|
+
if any(name not in self.output_qubits_map for name in output_names):
|
276
|
+
raise ClassiqError(_UNAVAILABLE_OUTPUT_ERROR_MSG)
|
277
|
+
|
278
|
+
reduced_parsed_states = reduce_parsed_states(self.parsed_states, output_names)
|
279
|
+
return get_parsed_counts(self.counts, reduced_parsed_states)
|
280
|
+
|
281
|
+
def register_output_from_qubits(self, qubits: tuple[int, ...]) -> dict[float, int]:
|
282
|
+
register_output: dict[float, int] = {}
|
228
283
|
value_from_str_bin = functools.partial(
|
229
284
|
self._get_register_value_from_binary_string_results, register_qubits=qubits
|
230
285
|
)
|
@@ -232,13 +287,15 @@ class ExecutionDetails(BaseModel, QmodPyObject):
|
|
232
287
|
lsb_right=False
|
233
288
|
).items():
|
234
289
|
value = value_from_str_bin(binary_string=results_binary_key)
|
290
|
+
if TYPE_CHECKING:
|
291
|
+
assert isinstance(value, float)
|
235
292
|
register_output[value] = register_output.get(value, 0) + counts
|
236
293
|
|
237
294
|
return register_output
|
238
295
|
|
239
296
|
@staticmethod
|
240
297
|
def _get_register_value_from_binary_string_results(
|
241
|
-
binary_string: str, register_qubits:
|
298
|
+
binary_string: str, register_qubits: list[int]
|
242
299
|
) -> RegisterValue:
|
243
300
|
register_binary_string = "".join(
|
244
301
|
operator.itemgetter(*register_qubits)(binary_string)
|
@@ -247,33 +304,34 @@ class ExecutionDetails(BaseModel, QmodPyObject):
|
|
247
304
|
|
248
305
|
|
249
306
|
class MultipleExecutionDetails(VersionedModel):
|
250
|
-
details:
|
307
|
+
details: list[ExecutionDetails]
|
251
308
|
|
252
309
|
def __getitem__(self, index: int) -> ExecutionDetails:
|
253
310
|
return self.details[index]
|
254
311
|
|
255
312
|
|
256
|
-
class EstimationMetadata(BaseModel, extra=
|
313
|
+
class EstimationMetadata(BaseModel, extra="allow"):
|
257
314
|
shots: Optional[pydantic.NonNegativeInt] = None
|
258
315
|
remapped_qubits: bool = False
|
259
|
-
input_qubit_map: Optional[
|
316
|
+
input_qubit_map: Optional[list[PydanticNonNegIntTuple]] = None
|
260
317
|
|
261
318
|
|
262
319
|
class EstimationResult(BaseModel, QmodPyObject):
|
263
320
|
value: Complex = pydantic.Field(..., description="Estimation for the operator")
|
264
|
-
variance: Complex = pydantic.Field(..., description="Variance of the estimation")
|
265
321
|
metadata: EstimationMetadata = pydantic.Field(
|
266
322
|
..., description="Metadata for the estimation"
|
267
323
|
)
|
268
324
|
|
269
325
|
|
270
326
|
class EstimationResults(VersionedModel):
|
271
|
-
results:
|
327
|
+
results: list[EstimationResult]
|
272
328
|
|
273
329
|
def __len__(self) -> int:
|
274
330
|
return len(self.results)
|
275
331
|
|
276
|
-
def __iter__(self) -> Iterator[EstimationResult]: # type: ignore
|
332
|
+
def __iter__(self) -> Iterator[EstimationResult]: # type: ignore[override]
|
333
|
+
# TODO This is a bug waiting to happen. We change the meaning of
|
334
|
+
# __iter__ in a derived class.
|
277
335
|
return iter(self.results)
|
278
336
|
|
279
337
|
def __getitem__(self, index: int) -> EstimationResult:
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import base64
|
2
2
|
import io
|
3
3
|
from datetime import datetime
|
4
|
-
from typing import
|
4
|
+
from typing import Optional
|
5
5
|
|
6
6
|
import pydantic
|
7
7
|
from PIL import Image
|
@@ -12,14 +12,14 @@ from classiq.interface.generator.complex_type import Complex
|
|
12
12
|
from classiq.interface.generator.functions.classical_type import QmodPyObject
|
13
13
|
from classiq.interface.helpers.custom_pydantic_types import PydanticProbabilityFloat
|
14
14
|
|
15
|
-
Solution =
|
15
|
+
Solution = tuple[int, ...]
|
16
16
|
|
17
17
|
|
18
18
|
class SolverResult(BaseModel):
|
19
19
|
energy: float
|
20
20
|
# TODO: add time units (like seconds)
|
21
|
-
time: Optional[float]
|
22
|
-
solution: Optional[Solution]
|
21
|
+
time: Optional[float] = None
|
22
|
+
solution: Optional[Solution] = None
|
23
23
|
|
24
24
|
|
25
25
|
class SolutionData(BaseModel):
|
@@ -34,13 +34,13 @@ class VQEIntermediateData(BaseModel):
|
|
34
34
|
iteration_number: pydantic.PositiveInt = pydantic.Field(
|
35
35
|
description="The iteration's number (evaluation count)"
|
36
36
|
)
|
37
|
-
parameters:
|
37
|
+
parameters: list[float] = pydantic.Field(
|
38
38
|
description="The optimizer parameters for the variational form"
|
39
39
|
)
|
40
40
|
mean_all_solutions: Optional[float] = pydantic.Field(
|
41
41
|
default=None, description="The mean score of all solutions in this iteration"
|
42
42
|
)
|
43
|
-
solutions:
|
43
|
+
solutions: list[SolutionData] = pydantic.Field(
|
44
44
|
description="Solutions found in this iteration, their score and"
|
45
45
|
"number of repetitions"
|
46
46
|
)
|
@@ -50,11 +50,11 @@ class VQEIntermediateData(BaseModel):
|
|
50
50
|
|
51
51
|
|
52
52
|
class VQESolverResult(SolverResult, QmodPyObject):
|
53
|
-
eigenstate:
|
54
|
-
reduced_probabilities: Optional[
|
53
|
+
eigenstate: dict[str, Complex]
|
54
|
+
reduced_probabilities: Optional[dict[str, float]] = None
|
55
55
|
optimized_circuit_sample_results: ExecutionDetails
|
56
|
-
intermediate_results:
|
57
|
-
optimal_parameters:
|
56
|
+
intermediate_results: list[VQEIntermediateData]
|
57
|
+
optimal_parameters: dict[str, float]
|
58
58
|
convergence_graph_str: str
|
59
59
|
num_solutions: Optional[int] = None
|
60
60
|
num_shots: int
|
@@ -63,7 +63,7 @@ class VQESolverResult(SolverResult, QmodPyObject):
|
|
63
63
|
self.convergence_graph.show()
|
64
64
|
|
65
65
|
@property
|
66
|
-
def convergence_graph(self):
|
66
|
+
def convergence_graph(self) -> Image.Image:
|
67
67
|
return Image.open(io.BytesIO(base64.b64decode(self.convergence_graph_str)))
|
68
68
|
|
69
69
|
@property
|