classiq 0.38.0__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 +47 -32
- classiq/_analyzer_extras/_ipywidgets_async_extension.py +2 -1
- classiq/_internals/api_wrapper.py +235 -97
- classiq/_internals/async_utils.py +1 -3
- classiq/_internals/authentication/auth0.py +26 -10
- classiq/_internals/authentication/authentication.py +11 -0
- classiq/_internals/authentication/device.py +10 -5
- classiq/_internals/authentication/password_manager.py +18 -6
- classiq/_internals/authentication/token_manager.py +10 -5
- classiq/_internals/client.py +94 -33
- classiq/_internals/config.py +3 -4
- classiq/_internals/host_checker.py +38 -15
- classiq/_internals/jobs.py +60 -57
- classiq/_internals/type_validation.py +9 -9
- classiq/analyzer/__init__.py +1 -3
- classiq/analyzer/analyzer.py +24 -19
- classiq/analyzer/analyzer_utilities.py +10 -10
- classiq/analyzer/rb.py +15 -15
- classiq/analyzer/show_interactive_hack.py +27 -4
- 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 +165 -158
- classiq/applications/chemistry/ground_state_problem.py +1 -1
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/allowed_constraints.py +4 -1
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/arithmetic/arithmetic_expression.py +1 -1
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/arithmetic/isolation.py +1 -1
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/combinatorial_problem_utils.py +51 -15
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/encoding_mapping.py +12 -12
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/encoding_utils.py +8 -6
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/memory.py +7 -11
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/optimization_model.py +67 -40
- classiq/applications/combinatorial_helpers/pauli_helpers/pauli_utils.py +46 -0
- classiq/applications/combinatorial_helpers/pyomo_utils.py +447 -0
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/sympy_utils.py +2 -2
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/encoding.py +15 -20
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/fixed_variables.py +14 -15
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/ising_converter.py +11 -15
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/penalty.py +1 -2
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/penalty_support.py +3 -7
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/sign_seperation.py +2 -3
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/slack_variables.py +5 -8
- classiq/applications/combinatorial_optimization/__init__.py +20 -6
- classiq/applications/combinatorial_optimization/combinatorial_optimization_config.py +2 -2
- classiq/{applications_model_constructors → applications/combinatorial_optimization}/combinatorial_optimization_model_constructor.py +35 -33
- 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 +48 -42
- classiq/applications/grover/__init__.py +9 -0
- classiq/{applications_model_constructors → applications/grover}/grover_model_constructor.py +52 -51
- classiq/applications/hamiltonian/pauli_decomposition.py +113 -0
- classiq/applications/libraries/qmci_library.py +22 -0
- classiq/applications/qnn/__init__.py +2 -4
- classiq/applications/qnn/circuit_utils.py +6 -6
- 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 +1 -1
- 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 +5 -5
- classiq/applications/qsvm/__init__.py +6 -4
- classiq/applications/qsvm/qsvm.py +3 -6
- classiq/applications/qsvm/qsvm_data_generation.py +3 -3
- 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 +20 -115
- classiq/interface/_version.py +1 -1
- classiq/interface/analyzer/analysis_params.py +43 -13
- classiq/interface/analyzer/cytoscape_graph.py +15 -9
- classiq/interface/analyzer/result.py +28 -32
- classiq/interface/applications/qsvm.py +20 -29
- classiq/interface/ast_node.py +16 -0
- classiq/interface/backend/backend_preferences.py +390 -121
- classiq/interface/backend/ionq/ionq_quantum_program.py +15 -23
- classiq/interface/backend/pydantic_backend.py +25 -22
- classiq/interface/backend/quantum_backend_providers.py +69 -16
- classiq/interface/chemistry/fermionic_operator.py +30 -21
- classiq/interface/chemistry/ground_state_problem.py +28 -25
- classiq/interface/chemistry/molecule.py +14 -10
- classiq/interface/chemistry/operator.py +64 -231
- classiq/interface/combinatorial_optimization/encoding_types.py +1 -1
- classiq/interface/combinatorial_optimization/examples/ascending_sequence.py +1 -3
- 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/mht.py +10 -6
- classiq/interface/combinatorial_optimization/examples/portfolio_variations.py +2 -2
- classiq/interface/combinatorial_optimization/examples/set_cover.py +1 -2
- classiq/interface/combinatorial_optimization/mht_qaoa_input.py +8 -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/debug_info.py +86 -0
- classiq/{exceptions.py → interface/exceptions.py} +37 -9
- 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/execution_preferences.py +26 -114
- classiq/interface/executor/execution_request.py +24 -46
- classiq/interface/executor/execution_result.py +30 -8
- classiq/interface/executor/iqae_result.py +4 -6
- classiq/interface/executor/optimizer_preferences.py +17 -14
- classiq/interface/executor/quantum_code.py +28 -24
- classiq/interface/executor/quantum_instruction_set.py +2 -2
- classiq/interface/executor/register_initialization.py +11 -14
- classiq/interface/executor/result.py +83 -56
- classiq/interface/executor/vqe_result.py +10 -10
- classiq/interface/finance/function_input.py +35 -25
- classiq/interface/finance/gaussian_model_input.py +5 -5
- classiq/interface/finance/log_normal_model_input.py +4 -4
- classiq/interface/finance/model_input.py +4 -4
- classiq/interface/generator/adjacency.py +1 -3
- classiq/interface/generator/amplitude_loading.py +22 -12
- classiq/interface/generator/ansatz_library.py +5 -5
- classiq/interface/generator/application_apis/arithmetic_declarations.py +8 -5
- 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 +46 -5
- classiq/interface/generator/arith/arithmetic.py +35 -16
- classiq/interface/generator/arith/arithmetic_arg_type_validator.py +6 -7
- classiq/interface/generator/arith/arithmetic_expression_abc.py +66 -25
- classiq/interface/generator/arith/arithmetic_expression_parser.py +11 -11
- classiq/interface/generator/arith/arithmetic_expression_validator.py +47 -43
- classiq/interface/generator/arith/arithmetic_operations.py +14 -6
- 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 +3 -2
- classiq/interface/generator/arith/binary_ops.py +218 -130
- classiq/interface/generator/arith/endianness.py +1 -1
- classiq/interface/generator/arith/extremum_operations.py +96 -25
- classiq/interface/generator/arith/logical_ops.py +14 -12
- classiq/interface/generator/arith/number_utils.py +12 -6
- classiq/interface/generator/arith/register_user_input.py +60 -37
- classiq/interface/generator/arith/unary_ops.py +49 -29
- 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 +3 -3
- 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 +7 -7
- classiq/interface/generator/compiler_keywords.py +5 -1
- classiq/interface/generator/complex_type.py +13 -18
- classiq/interface/generator/constant.py +3 -4
- classiq/interface/generator/control_state.py +34 -29
- 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 +21 -5
- 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 +5 -5
- classiq/interface/generator/expressions/expression.py +26 -14
- 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 +34 -8
- 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 +19 -11
- classiq/interface/generator/finance.py +2 -2
- 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 +36 -64
- classiq/interface/generator/functions/__init__.py +0 -22
- 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 +153 -20
- classiq/interface/generator/grover_diffuser.py +32 -25
- classiq/interface/generator/grover_operator.py +34 -25
- 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 +9 -9
- classiq/interface/generator/hardware/hardware_data.py +72 -34
- classiq/interface/generator/hardware_efficient_ansatz.py +20 -16
- classiq/interface/generator/hartree_fock.py +13 -5
- classiq/interface/generator/identity.py +10 -6
- classiq/interface/generator/linear_pauli_rotations.py +32 -20
- classiq/interface/generator/mcmt_method.py +1 -1
- classiq/interface/generator/mcu.py +17 -15
- classiq/interface/generator/mcx.py +24 -17
- classiq/interface/generator/model/__init__.py +2 -5
- classiq/interface/generator/model/constraints.py +26 -8
- classiq/interface/generator/model/model.py +27 -190
- classiq/interface/generator/model/preferences/preferences.py +115 -41
- classiq/{quantum_register.py → interface/generator/model/quantum_register.py} +14 -17
- classiq/interface/generator/oracles/arithmetic_oracle.py +2 -4
- classiq/interface/generator/oracles/custom_oracle.py +15 -13
- classiq/interface/generator/oracles/oracle_abc.py +7 -7
- 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 +41 -30
- classiq/interface/generator/qsvm.py +9 -10
- classiq/interface/generator/quantum_function_call.py +88 -73
- classiq/interface/generator/quantum_program.py +41 -24
- classiq/interface/generator/range_types.py +11 -12
- classiq/interface/generator/register_role.py +18 -6
- classiq/interface/generator/slice_parsing_utils.py +5 -5
- classiq/interface/generator/standard_gates/controlled_standard_gates.py +30 -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 +4 -7
- classiq/interface/generator/state_preparation/state_preparation.py +25 -20
- 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 +7 -11
- classiq/interface/generator/ucc.py +5 -4
- classiq/interface/generator/unitary_gate.py +5 -5
- classiq/interface/generator/user_defined_function_params.py +4 -1
- classiq/interface/generator/validations/flow_graph.py +7 -7
- classiq/interface/generator/validations/validator_functions.py +4 -4
- classiq/interface/generator/visitor.py +23 -16
- classiq/interface/hardware.py +29 -8
- classiq/interface/helpers/classproperty.py +8 -0
- classiq/interface/helpers/custom_encoders.py +2 -2
- 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 -5
- classiq/interface/helpers/validation_helpers.py +3 -20
- classiq/interface/helpers/versioned_model.py +1 -4
- 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 +29 -69
- classiq/interface/model/allocate.py +16 -0
- classiq/interface/model/bind_operation.py +32 -9
- 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 +29 -24
- classiq/interface/model/invert.py +12 -0
- classiq/interface/model/model.py +69 -61
- classiq/interface/model/native_function_definition.py +17 -20
- 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 +30 -18
- 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 +141 -343
- classiq/interface/model/quantum_function_declaration.py +190 -157
- classiq/interface/model/quantum_lambda_function.py +33 -32
- classiq/interface/model/quantum_statement.py +71 -12
- classiq/interface/model/quantum_type.py +177 -40
- classiq/interface/model/quantum_variable_declaration.py +3 -25
- classiq/interface/model/repeat.py +15 -0
- classiq/interface/model/statement_block.py +40 -14
- classiq/interface/model/validation_handle.py +13 -6
- classiq/interface/model/variable_declaration_statement.py +3 -1
- classiq/interface/model/within_apply_operation.py +7 -5
- classiq/interface/server/global_versions.py +6 -7
- classiq/interface/server/routes.py +17 -21
- classiq/interface/source_reference.py +59 -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 +10 -10
- classiq/qmod/builtins/__init__.py +19 -2
- classiq/qmod/builtins/classical_execution_primitives.py +36 -14
- classiq/qmod/builtins/classical_functions.py +39 -43
- 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 +373 -40
- classiq/qmod/builtins/structs.py +103 -80
- classiq/qmod/cfunc.py +2 -2
- classiq/qmod/classical_function.py +4 -8
- classiq/qmod/cparam.py +64 -0
- classiq/qmod/create_model_function.py +56 -0
- classiq/qmod/declaration_inferrer.py +143 -101
- classiq/qmod/expression_query.py +20 -4
- classiq/qmod/generative.py +42 -0
- classiq/qmod/model_state_container.py +18 -6
- classiq/qmod/native/__init__.py +7 -0
- classiq/qmod/native/expression_to_qmod.py +16 -11
- classiq/qmod/native/pretty_printer.py +187 -97
- 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 +60 -8
- classiq/qmod/qmod_constant.py +93 -26
- classiq/qmod/qmod_parameter.py +68 -59
- classiq/qmod/qmod_variable.py +468 -155
- classiq/qmod/quantum_callable.py +17 -7
- classiq/qmod/quantum_expandable.py +269 -96
- classiq/qmod/quantum_function.py +196 -41
- 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 +147 -123
- classiq/qmod/symbolic_expr.py +27 -12
- classiq/qmod/symbolic_type.py +2 -5
- classiq/qmod/type_attribute_remover.py +32 -0
- classiq/qmod/utilities.py +98 -4
- classiq/qmod/write_qmod.py +17 -3
- classiq/synthesis.py +210 -22
- {classiq-0.38.0.dist-info → classiq-0.65.3.dist-info}/METADATA +16 -9
- classiq-0.65.3.dist-info/RECORD +521 -0
- classiq/_internals/_qfunc_ext.py +0 -6
- classiq/applications/benchmarking/__init__.py +0 -9
- classiq/applications/benchmarking/mirror_benchmarking.py +0 -70
- classiq/applications/numpy_utils.py +0 -37
- classiq/applications_model_constructors/__init__.py +0 -25
- classiq/applications_model_constructors/combinatorial_helpers/multiple_comp_basis_sp.py +0 -34
- classiq/applications_model_constructors/combinatorial_helpers/pauli_helpers/pauli_utils.py +0 -65
- classiq/applications_model_constructors/combinatorial_helpers/pyomo_utils.py +0 -243
- classiq/applications_model_constructors/libraries/ampltitude_estimation_library.py +0 -11
- classiq/applications_model_constructors/libraries/qmci_library.py +0 -107
- 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/interface/executor/aws_execution_cost.py +0 -73
- classiq/interface/executor/error_mitigation.py +0 -6
- classiq/interface/generator/credit_risk_example/linear_gci.py +0 -122
- classiq/interface/generator/credit_risk_example/weighted_adder.py +0 -69
- 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/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 -1229
- classiq/interface/generator/functions/core_lib_declarations/quantum_operators.py +0 -95
- classiq/interface/generator/functions/foreign_function_definition.py +0 -114
- classiq/interface/generator/functions/function_implementation.py +0 -107
- classiq/interface/generator/functions/native_function_definition.py +0 -155
- classiq/interface/generator/functions/quantum_function_declaration.py +0 -69
- classiq/interface/generator/functions/register.py +0 -44
- classiq/interface/generator/functions/register_mapping_data.py +0 -106
- 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 -74
- classiq/interface/generator/types/builtin_struct_declarations/__init__.py +0 -1
- classiq/interface/generator/types/builtin_struct_declarations/pauli_struct_declarations.py +0 -22
- classiq/interface/ide/show.py +0 -34
- classiq/interface/model/call_synthesis_data.py +0 -68
- classiq/interface/model/common_model_types.py +0 -23
- classiq/interface/model/quantum_expressions/control_state.py +0 -38
- classiq/interface/model/quantum_if_operation.py +0 -94
- 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 -156
- 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 -462
- classiq/model/logic_flow.py +0 -149
- classiq/model/logic_flow_change_handler.py +0 -71
- classiq/model/model.py +0 -229
- classiq/qmod/builtins/functions.py +0 -913
- classiq/qmod/qmod_struct.py +0 -37
- classiq/quantum_functions/__init__.py +0 -17
- classiq/quantum_functions/annotation_parser.py +0 -205
- 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.38.0.dist-info/RECORD +0 -454
- /classiq/{applications_model_constructors → applications}/combinatorial_helpers/__init__.py +0 -0
- /classiq/{applications_model_constructors → applications}/combinatorial_helpers/arithmetic/__init__.py +0 -0
- /classiq/{applications_model_constructors → applications}/combinatorial_helpers/pauli_helpers/__init__.py +0 -0
- /classiq/{applications_model_constructors → applications}/combinatorial_helpers/pauli_helpers/pauli_sparsing.py +0 -0
- /classiq/{applications_model_constructors → applications}/combinatorial_helpers/py.typed +0 -0
- /classiq/{applications_model_constructors/combinatorial_helpers/transformations → applications/combinatorial_helpers/solvers}/__init__.py +0 -0
- /classiq/{applications_model_constructors/libraries → applications/combinatorial_helpers/transformations}/__init__.py +0 -0
- /classiq/{interface/generator/credit_risk_example → applications/hamiltonian}/__init__.py +0 -0
- /classiq/{interface/generator/functions/core_lib_declarations → applications/libraries}/__init__.py +0 -0
- /classiq/interface/{model/resolvers → debug_info}/__init__.py +0 -0
- /classiq/{_internals → interface}/enum_utils.py +0 -0
- /classiq/interface/{model/validations → generator/functions/builtins}/__init__.py +0 -0
- /classiq/{interface/generator/functions/core_lib_declarations/quantum_functions/chemistry_functions.py → model_expansions/__init__.py} +0 -0
- {classiq-0.38.0.dist-info → classiq-0.65.3.dist-info}/WHEEL +0 -0
@@ -0,0 +1,214 @@
|
|
1
|
+
import ast
|
2
|
+
import copy
|
3
|
+
from typing import TYPE_CHECKING, Union
|
4
|
+
|
5
|
+
from classiq.interface.exceptions import ClassiqInternalExpansionError
|
6
|
+
|
7
|
+
from classiq.model_expansions.sympy_conversion.arithmetics import LogicalXor
|
8
|
+
|
9
|
+
|
10
|
+
class BooleanExpressionOptimizer(ast.NodeTransformer):
|
11
|
+
"""
|
12
|
+
This class assumes that all variables in the expression are single qubit.
|
13
|
+
It does the following:
|
14
|
+
It checks whether the expression can be transformed into a boolean expression with boolean
|
15
|
+
variables (i.e, single-qubit variables), and if so, does the transformation by converting bitwise
|
16
|
+
ops to their boolean analogs.
|
17
|
+
The condition is that the expression consists of bitwise operations and relational operations only,
|
18
|
+
and not operations like addition.
|
19
|
+
The transformation results in better circuits.
|
20
|
+
"""
|
21
|
+
|
22
|
+
def __init__(self) -> None:
|
23
|
+
self._is_convertible: bool = False
|
24
|
+
|
25
|
+
@property
|
26
|
+
def is_convertible(self) -> bool:
|
27
|
+
return self._is_convertible
|
28
|
+
|
29
|
+
def visit_Expr(self, node: ast.Expr) -> ast.Expr:
|
30
|
+
self._is_convertible = False
|
31
|
+
original_expr = copy.deepcopy(node)
|
32
|
+
self.generic_visit(node)
|
33
|
+
return node if self._is_convertible else original_expr
|
34
|
+
|
35
|
+
def visit_operator(self, node: ast.operator) -> ast.operator:
|
36
|
+
self._is_convertible = False
|
37
|
+
return node
|
38
|
+
|
39
|
+
def visit_BinOp(self, node: ast.BinOp) -> Union[ast.BinOp, ast.BoolOp]:
|
40
|
+
self.generic_visit(node)
|
41
|
+
self._is_convertible = self._is_bool(node)
|
42
|
+
if not self._is_convertible:
|
43
|
+
return node
|
44
|
+
|
45
|
+
return self.visit(self._convert_bin_op_to_bool_op(node))
|
46
|
+
|
47
|
+
def visit_UnaryOp(self, node: ast.UnaryOp) -> ast.AST:
|
48
|
+
self.generic_visit(node)
|
49
|
+
self._is_convertible = self._is_bool(node)
|
50
|
+
if not self._is_convertible:
|
51
|
+
return node
|
52
|
+
|
53
|
+
return ast.UnaryOp(op=ast.Not(), operand=node.operand)
|
54
|
+
|
55
|
+
def visit_Compare(self, node: ast.Compare) -> ast.AST:
|
56
|
+
if len(node.ops) != 1 or len(node.comparators) != 1:
|
57
|
+
raise ClassiqInternalExpansionError
|
58
|
+
|
59
|
+
self.generic_visit(node)
|
60
|
+
self._is_convertible = self._is_bool(node)
|
61
|
+
if not self._is_convertible:
|
62
|
+
return node
|
63
|
+
|
64
|
+
if not (
|
65
|
+
isinstance(node.left, ast.Constant)
|
66
|
+
or isinstance(node.comparators[0], ast.Constant)
|
67
|
+
):
|
68
|
+
return node
|
69
|
+
|
70
|
+
return self._simplify_trivial_equality(node)
|
71
|
+
|
72
|
+
def visit_Call(self, node: ast.Call) -> ast.Call:
|
73
|
+
self._is_convertible = (
|
74
|
+
isinstance(node.func, ast.Name) and node.func.id == LogicalXor.__name__
|
75
|
+
)
|
76
|
+
return node
|
77
|
+
|
78
|
+
def _is_bool(self, node: ast.AST) -> bool:
|
79
|
+
if isinstance(node, (ast.BoolOp, ast.Name)): # Name due to boolean vars
|
80
|
+
return True
|
81
|
+
if isinstance(node, ast.BinOp):
|
82
|
+
return (
|
83
|
+
self._is_bool(node.left)
|
84
|
+
and self._is_bool(node.right)
|
85
|
+
and isinstance(node.op, (ast.BitOr, ast.BitAnd, ast.BitXor))
|
86
|
+
)
|
87
|
+
if isinstance(node, ast.Constant):
|
88
|
+
return isinstance(node.value, int) and node.value in (0, 1)
|
89
|
+
if isinstance(node, ast.UnaryOp):
|
90
|
+
return isinstance(node.op, (ast.Invert, ast.Not)) and self._is_bool(
|
91
|
+
node.operand
|
92
|
+
)
|
93
|
+
if isinstance(node, ast.Compare):
|
94
|
+
return (
|
95
|
+
self._is_bool(node.left)
|
96
|
+
and self._is_bool(node.comparators[0])
|
97
|
+
and isinstance(node.ops[0], (ast.Eq, ast.NotEq))
|
98
|
+
)
|
99
|
+
if isinstance(node, ast.Call):
|
100
|
+
return (
|
101
|
+
isinstance(node.func, ast.Name) and node.func.id == LogicalXor.__name__
|
102
|
+
)
|
103
|
+
return False
|
104
|
+
|
105
|
+
def _convert_bin_op_to_bool_op(self, node: ast.BinOp) -> ast.AST:
|
106
|
+
if isinstance(node.op, ast.BitOr):
|
107
|
+
return ast.BoolOp(op=ast.Or(), values=[node.left, node.right])
|
108
|
+
if isinstance(node.op, ast.BitAnd):
|
109
|
+
return ast.BoolOp(op=ast.And(), values=[node.left, node.right])
|
110
|
+
if isinstance(node.op, ast.BitXor):
|
111
|
+
return self._simplify_xor(node)
|
112
|
+
raise ClassiqInternalExpansionError
|
113
|
+
|
114
|
+
@staticmethod
|
115
|
+
def _simplify_xor(node: ast.BinOp) -> ast.AST:
|
116
|
+
if not (
|
117
|
+
isinstance(node.left, ast.Constant) or isinstance(node.right, ast.Constant)
|
118
|
+
):
|
119
|
+
return ast.Call(
|
120
|
+
func=ast.Name(LogicalXor.__name__),
|
121
|
+
args=[node.left, node.right],
|
122
|
+
keywords=[],
|
123
|
+
)
|
124
|
+
|
125
|
+
if isinstance(node.left, ast.Constant):
|
126
|
+
constant = node.left.value
|
127
|
+
other = node.right
|
128
|
+
else:
|
129
|
+
if TYPE_CHECKING:
|
130
|
+
assert isinstance(node.right, ast.Constant)
|
131
|
+
try:
|
132
|
+
constant = node.right.value
|
133
|
+
except AttributeError as e:
|
134
|
+
raise e
|
135
|
+
other = node.left
|
136
|
+
|
137
|
+
return other if constant == 0 else ast.UnaryOp(op=ast.Not(), operand=other)
|
138
|
+
|
139
|
+
@staticmethod
|
140
|
+
def _simplify_trivial_equality(node: ast.Compare) -> ast.AST:
|
141
|
+
if isinstance(node.left, ast.Constant):
|
142
|
+
val = node.left.value
|
143
|
+
other = node.comparators[0]
|
144
|
+
else:
|
145
|
+
if TYPE_CHECKING:
|
146
|
+
assert isinstance(node.comparators[0], ast.Constant)
|
147
|
+
val = node.comparators[0].value
|
148
|
+
other = node.left
|
149
|
+
|
150
|
+
to_invert = (val == 0 and isinstance(node.ops[0], ast.Eq)) or (
|
151
|
+
val == 1 and isinstance(node.ops[0], ast.NotEq)
|
152
|
+
)
|
153
|
+
|
154
|
+
return ast.UnaryOp(op=ast.Not(), operand=other) if to_invert else other
|
155
|
+
|
156
|
+
|
157
|
+
class BooleanExpressionFuncLibAdapter(ast.NodeTransformer):
|
158
|
+
"""
|
159
|
+
The class assumes that the expression result is single-qubit.
|
160
|
+
|
161
|
+
Due to limitations on the inplace arithmetic in our function library, this visitor checks whether
|
162
|
+
the expression has one of the following forms:
|
163
|
+
a. A single, simple boolean assignment (res ^= x).
|
164
|
+
b. A bitwise-not operation on a boolean expression (res ^= ~(x > 5)).
|
165
|
+
The former will be transformed into res ^= (x == 1). The latter to (res ^= x > 5) and then the Interpreter
|
166
|
+
will append an X gate to the result variable.
|
167
|
+
To understand the necessity of this transformation, see the _OPERATIONS_ALLOWING_TARGET variable
|
168
|
+
which limits the possible inplace operations. Not is forbidden, and a simple assignment res ^= x
|
169
|
+
is converted into an addition res ^= x + 0, which is also forbidden.
|
170
|
+
|
171
|
+
"""
|
172
|
+
|
173
|
+
def __init__(self, is_boolean_optimized: bool) -> None:
|
174
|
+
self._to_invert: bool = False
|
175
|
+
self._is_boolean_optimized = is_boolean_optimized
|
176
|
+
|
177
|
+
@property
|
178
|
+
def to_invert(self) -> bool:
|
179
|
+
return self._to_invert
|
180
|
+
|
181
|
+
def visit_Expr(self, node: ast.Expr) -> ast.Expr:
|
182
|
+
self.generic_visit(node)
|
183
|
+
if isinstance(node.value, ast.Name):
|
184
|
+
node.value = ast.Compare(
|
185
|
+
left=node.value,
|
186
|
+
ops=[ast.Eq()],
|
187
|
+
comparators=[ast.Constant(value=1)],
|
188
|
+
)
|
189
|
+
if isinstance(node.value, ast.UnaryOp) and isinstance(
|
190
|
+
node.value.op, (ast.Not, ast.Invert)
|
191
|
+
):
|
192
|
+
self._to_invert = not self._to_invert
|
193
|
+
node.value = node.value.operand
|
194
|
+
return self.visit(node)
|
195
|
+
|
196
|
+
return node
|
197
|
+
|
198
|
+
def visit_UnaryOp(self, node: ast.UnaryOp) -> ast.UnaryOp:
|
199
|
+
"""Due to Sympy crap, we need to translate the Invert nodes to Not"""
|
200
|
+
if not (self._is_boolean_optimized and isinstance(node.op, ast.Invert)):
|
201
|
+
return node
|
202
|
+
self.generic_visit(node)
|
203
|
+
return ast.UnaryOp(op=ast.Not(), operand=node.operand)
|
204
|
+
|
205
|
+
def visit_BinOp(self, node: ast.BinOp) -> Union[ast.BinOp, ast.Call]:
|
206
|
+
"""Due to Sympy crap, we need to translate the Xor nodes to our LogicalXor"""
|
207
|
+
if not (self._is_boolean_optimized and isinstance(node.op, ast.BitXor)):
|
208
|
+
return node
|
209
|
+
self.generic_visit(node)
|
210
|
+
return ast.Call(
|
211
|
+
func=ast.Name(LogicalXor.__name__),
|
212
|
+
args=[node.left, node.right],
|
213
|
+
keywords=[],
|
214
|
+
)
|
@@ -0,0 +1,144 @@
|
|
1
|
+
import ast
|
2
|
+
from collections.abc import Iterator
|
3
|
+
from contextlib import contextmanager
|
4
|
+
from typing import Optional, Union
|
5
|
+
|
6
|
+
from classiq.interface.exceptions import (
|
7
|
+
ClassiqExpansionError,
|
8
|
+
ClassiqInternalExpansionError,
|
9
|
+
)
|
10
|
+
from classiq.interface.generator.arith.arithmetic_expression_validator import (
|
11
|
+
DEFAULT_SUPPORTED_FUNC_NAMES,
|
12
|
+
)
|
13
|
+
from classiq.interface.generator.expressions.expression import Expression
|
14
|
+
from classiq.interface.generator.expressions.sympy_supported_expressions import (
|
15
|
+
SYMPY_SUPPORTED_EXPRESSIONS,
|
16
|
+
)
|
17
|
+
from classiq.interface.model.handle_binding import (
|
18
|
+
FieldHandleBinding,
|
19
|
+
HandleBinding,
|
20
|
+
SlicedHandleBinding,
|
21
|
+
SubscriptHandleBinding,
|
22
|
+
)
|
23
|
+
|
24
|
+
|
25
|
+
class VarRefCollector(ast.NodeVisitor):
|
26
|
+
def __init__(
|
27
|
+
self, ignore_duplicated_handles: bool = False, unevaluated: bool = False
|
28
|
+
) -> None:
|
29
|
+
self._var_handles: dict[HandleBinding, bool] = {}
|
30
|
+
self._ignore_duplicated_handles = ignore_duplicated_handles
|
31
|
+
self._unevaluated = unevaluated
|
32
|
+
self._is_nested = False
|
33
|
+
|
34
|
+
@property
|
35
|
+
def var_handles(self) -> list[HandleBinding]:
|
36
|
+
return list(self._var_handles)
|
37
|
+
|
38
|
+
def visit(self, node: ast.AST) -> Union[
|
39
|
+
SubscriptHandleBinding,
|
40
|
+
SlicedHandleBinding,
|
41
|
+
FieldHandleBinding,
|
42
|
+
HandleBinding,
|
43
|
+
None,
|
44
|
+
]:
|
45
|
+
res = super().visit(node)
|
46
|
+
if not self._ignore_duplicated_handles and len(self._var_handles) != len(
|
47
|
+
{handle.name for handle in self._var_handles}
|
48
|
+
):
|
49
|
+
raise ClassiqExpansionError(
|
50
|
+
"Multiple non-identical variable references in an expression are not supported."
|
51
|
+
)
|
52
|
+
return res
|
53
|
+
|
54
|
+
def visit_Subscript(
|
55
|
+
self, node: ast.Subscript
|
56
|
+
) -> Union[SubscriptHandleBinding, SlicedHandleBinding, None]:
|
57
|
+
with self.set_nested():
|
58
|
+
base_handle = self.visit(node.value)
|
59
|
+
if base_handle is None:
|
60
|
+
return None
|
61
|
+
|
62
|
+
handle: Union[SubscriptHandleBinding, SlicedHandleBinding]
|
63
|
+
if isinstance(node.slice, ast.Slice):
|
64
|
+
if not self._unevaluated and (
|
65
|
+
not isinstance(node.slice.lower, ast.Num)
|
66
|
+
or not isinstance(node.slice.upper, ast.Num)
|
67
|
+
):
|
68
|
+
raise ClassiqInternalExpansionError("Unevaluated slice bounds.")
|
69
|
+
if node.slice.lower is None or node.slice.upper is None:
|
70
|
+
raise ClassiqExpansionError(
|
71
|
+
f"{str(base_handle)!r} slice must specify both lower and upper bounds"
|
72
|
+
)
|
73
|
+
handle = SlicedHandleBinding(
|
74
|
+
base_handle=base_handle,
|
75
|
+
start=Expression(expr=ast.unparse(node.slice.lower)),
|
76
|
+
end=Expression(expr=ast.unparse(node.slice.upper)),
|
77
|
+
)
|
78
|
+
elif not self._unevaluated and not isinstance(node.slice, ast.Num):
|
79
|
+
raise ClassiqInternalExpansionError("Unevaluated slice.")
|
80
|
+
else:
|
81
|
+
handle = SubscriptHandleBinding(
|
82
|
+
base_handle=base_handle,
|
83
|
+
index=Expression(expr=ast.unparse(node.slice)),
|
84
|
+
)
|
85
|
+
|
86
|
+
if not self._is_nested:
|
87
|
+
self._var_handles[handle] = True
|
88
|
+
return handle
|
89
|
+
|
90
|
+
def visit_Attribute(self, node: ast.Attribute) -> Optional[FieldHandleBinding]:
|
91
|
+
return self._get_field_handle(node.value, node.attr)
|
92
|
+
|
93
|
+
def visit_Call(self, node: ast.Call) -> Optional[FieldHandleBinding]:
|
94
|
+
if (
|
95
|
+
not isinstance(node.func, ast.Name)
|
96
|
+
or node.func.id != "get_field"
|
97
|
+
or len(node.args) != 2
|
98
|
+
or not isinstance(node.args[1], ast.Constant)
|
99
|
+
or not isinstance(node.args[1].value, str)
|
100
|
+
):
|
101
|
+
return self.generic_visit(node)
|
102
|
+
return self._get_field_handle(node.args[0], node.args[1].value)
|
103
|
+
|
104
|
+
def _get_field_handle(
|
105
|
+
self, subject: ast.expr, field: str
|
106
|
+
) -> Optional[FieldHandleBinding]:
|
107
|
+
with self.set_nested():
|
108
|
+
base_handle = self.visit(subject)
|
109
|
+
if base_handle is None:
|
110
|
+
return None
|
111
|
+
handle = FieldHandleBinding(
|
112
|
+
base_handle=base_handle,
|
113
|
+
field=field,
|
114
|
+
)
|
115
|
+
if not self._is_nested:
|
116
|
+
self._var_handles[handle] = True
|
117
|
+
return handle
|
118
|
+
|
119
|
+
def visit_Name(self, node: ast.Name) -> Optional[HandleBinding]:
|
120
|
+
if node.id in set(SYMPY_SUPPORTED_EXPRESSIONS) | set(
|
121
|
+
DEFAULT_SUPPORTED_FUNC_NAMES
|
122
|
+
):
|
123
|
+
return None
|
124
|
+
handle = HandleBinding(name=node.id)
|
125
|
+
if not self._is_nested:
|
126
|
+
self._var_handles[handle] = True
|
127
|
+
return handle
|
128
|
+
|
129
|
+
@contextmanager
|
130
|
+
def set_nested(self) -> Iterator[None]:
|
131
|
+
previous_is_nested = self._is_nested
|
132
|
+
self._is_nested = True
|
133
|
+
yield
|
134
|
+
self._is_nested = previous_is_nested
|
135
|
+
|
136
|
+
|
137
|
+
class VarRefTransformer(ast.NodeTransformer):
|
138
|
+
def __init__(self, var_mapping: dict[str, str]) -> None:
|
139
|
+
self.var_mapping = var_mapping
|
140
|
+
|
141
|
+
def visit_Name(self, node: ast.Name) -> ast.Name:
|
142
|
+
if node.id in self.var_mapping:
|
143
|
+
node.id = self.var_mapping[node.id]
|
144
|
+
return node
|
@@ -0,0 +1,130 @@
|
|
1
|
+
from .amplitude_estimation import *
|
2
|
+
from .discrete_sine_cosine_transform import *
|
3
|
+
from .discrete_sine_cosine_transform import _qct_d_operator, _qct_pi_operator
|
4
|
+
from .grover import *
|
5
|
+
from .hea import *
|
6
|
+
from .linear_pauli_rotation import *
|
7
|
+
from .linear_pauli_rotation import _single_pauli
|
8
|
+
from .modular_exponentiation import *
|
9
|
+
from .modular_exponentiation import _check_msb, _ctrl_x
|
10
|
+
from .qaoa_penalty import *
|
11
|
+
from .qft_functions import *
|
12
|
+
from .qpe import *
|
13
|
+
from .qsvt import *
|
14
|
+
from .state_preparation import *
|
15
|
+
from .state_preparation import _prepare_uniform_trimmed_state_step
|
16
|
+
from .swap_test import *
|
17
|
+
from .utility_functions import *
|
18
|
+
from .variational import *
|
19
|
+
|
20
|
+
OPEN_LIBRARY_FUNCTIONS = [
|
21
|
+
qpe_flexible,
|
22
|
+
qpe,
|
23
|
+
_single_pauli,
|
24
|
+
linear_pauli_rotations,
|
25
|
+
amplitude_estimation,
|
26
|
+
phase_oracle,
|
27
|
+
reflect_about_zero,
|
28
|
+
grover_diffuser,
|
29
|
+
grover_operator,
|
30
|
+
grover_search,
|
31
|
+
hadamard_transform,
|
32
|
+
apply_to_all,
|
33
|
+
qft_no_swap,
|
34
|
+
qft_space_add_const,
|
35
|
+
cc_modular_add,
|
36
|
+
c_modular_multiply,
|
37
|
+
multiswap,
|
38
|
+
inplace_c_modular_multiply,
|
39
|
+
modular_exp,
|
40
|
+
qsvt_step,
|
41
|
+
qsvt,
|
42
|
+
projector_controlled_double_phase,
|
43
|
+
projector_controlled_phase,
|
44
|
+
qsvt_inversion,
|
45
|
+
qsvt_lcu,
|
46
|
+
qsvt_lcu_step,
|
47
|
+
allocate_num,
|
48
|
+
qaoa_mixer_layer,
|
49
|
+
qaoa_cost_layer,
|
50
|
+
qaoa_layer,
|
51
|
+
qaoa_init,
|
52
|
+
qaoa_penalty,
|
53
|
+
full_hea,
|
54
|
+
swap_test,
|
55
|
+
prepare_uniform_trimmed_state,
|
56
|
+
prepare_uniform_interval_state,
|
57
|
+
prepare_ghz_state,
|
58
|
+
prepare_exponential_state,
|
59
|
+
prepare_bell_state,
|
60
|
+
inplace_prepare_int,
|
61
|
+
prepare_int,
|
62
|
+
switch,
|
63
|
+
qct_qst_type1,
|
64
|
+
qct_qst_type2,
|
65
|
+
qct_type2,
|
66
|
+
qst_type2,
|
67
|
+
modular_increment,
|
68
|
+
qft,
|
69
|
+
_ctrl_x,
|
70
|
+
_prepare_uniform_trimmed_state_step,
|
71
|
+
_qct_d_operator,
|
72
|
+
_qct_pi_operator,
|
73
|
+
_check_msb,
|
74
|
+
encode_in_angle,
|
75
|
+
encode_on_bloch,
|
76
|
+
]
|
77
|
+
|
78
|
+
__all__ = [
|
79
|
+
"_single_pauli",
|
80
|
+
"allocate_num",
|
81
|
+
"amplitude_estimation",
|
82
|
+
"apply_to_all",
|
83
|
+
"c_modular_multiply",
|
84
|
+
"cc_modular_add",
|
85
|
+
"encode_in_angle",
|
86
|
+
"encode_on_bloch",
|
87
|
+
"full_hea",
|
88
|
+
"grover_diffuser",
|
89
|
+
"grover_operator",
|
90
|
+
"grover_search",
|
91
|
+
"hadamard_transform",
|
92
|
+
"inplace_c_modular_multiply",
|
93
|
+
"inplace_prepare_int",
|
94
|
+
"linear_pauli_rotations",
|
95
|
+
"modular_exp",
|
96
|
+
"modular_increment",
|
97
|
+
"multiswap",
|
98
|
+
"phase_oracle",
|
99
|
+
"prepare_bell_state",
|
100
|
+
"prepare_exponential_state",
|
101
|
+
"prepare_ghz_state",
|
102
|
+
"prepare_int",
|
103
|
+
"prepare_uniform_interval_state",
|
104
|
+
"prepare_uniform_trimmed_state",
|
105
|
+
"projector_controlled_double_phase",
|
106
|
+
"projector_controlled_phase",
|
107
|
+
"qaoa_cost_layer",
|
108
|
+
"qaoa_init",
|
109
|
+
"qaoa_layer",
|
110
|
+
"qaoa_mixer_layer",
|
111
|
+
"qaoa_penalty",
|
112
|
+
"qct_qst_type1",
|
113
|
+
"qct_qst_type2",
|
114
|
+
"qct_type2",
|
115
|
+
"qft",
|
116
|
+
"qft_no_swap",
|
117
|
+
"qft_space_add_const",
|
118
|
+
"qpe",
|
119
|
+
"qpe_flexible",
|
120
|
+
"qst_type2",
|
121
|
+
"qsvt",
|
122
|
+
"qsvt_inversion",
|
123
|
+
"qsvt_lcu",
|
124
|
+
"qsvt_lcu_step",
|
125
|
+
"qsvt_step",
|
126
|
+
"reflect_about_zero",
|
127
|
+
"suzuki_trotter",
|
128
|
+
"swap_test",
|
129
|
+
"switch",
|
130
|
+
]
|
@@ -0,0 +1,30 @@
|
|
1
|
+
from classiq.open_library.functions.grover import grover_operator
|
2
|
+
from classiq.open_library.functions.qpe import qpe
|
3
|
+
from classiq.qmod.qfunc import qfunc
|
4
|
+
from classiq.qmod.qmod_variable import QArray, QBit, QNum
|
5
|
+
from classiq.qmod.quantum_callable import QCallable
|
6
|
+
|
7
|
+
|
8
|
+
@qfunc
|
9
|
+
def amplitude_estimation(
|
10
|
+
oracle: QCallable[QArray[QBit]],
|
11
|
+
space_transform: QCallable[QArray[QBit]],
|
12
|
+
phase: QNum,
|
13
|
+
packed_vars: QArray[QBit],
|
14
|
+
) -> None:
|
15
|
+
"""
|
16
|
+
[Qmod Classiq-library function]
|
17
|
+
|
18
|
+
Estimate the probability of a state being marked by the operand `oracle` as a "good state."
|
19
|
+
|
20
|
+
The algorithm prepares the state in the `packed_vars` register and estimates the probability of this state being marked by the oracle as a "good state."
|
21
|
+
This is done using the Quantum Phase Estimation (QPE) algorithm, where the unitary for QPE is the Grover operator, which is composed of the `oracle` and `space_transform` operators.
|
22
|
+
|
23
|
+
Args:
|
24
|
+
oracle: The oracle operator that marks the "good" state. This operator should flip the sign of the amplitude of the "good" state.
|
25
|
+
space_transform: The space transform operator (which is known also the state preparation operator), which is first applied to prepare the state before the QPE, and then used inside the Grover operator.
|
26
|
+
phase: Assuming this variable starts from the zero state -this variable output holds the $phase=\\theta$ result in the [0,1] domain, which relates to the estimated probability $a$ through $a=\\sin^2(\\pi \\theta)$.
|
27
|
+
packed_vars: The variable that holds the state to be estimated. Assumed to be in the zero state at the beginning of the algorithm.
|
28
|
+
"""
|
29
|
+
space_transform(packed_vars)
|
30
|
+
qpe(lambda: grover_operator(oracle, space_transform, packed_vars), phase)
|
@@ -0,0 +1,181 @@
|
|
1
|
+
from classiq.open_library.functions.qft_functions import qft
|
2
|
+
from classiq.open_library.functions.utility_functions import (
|
3
|
+
apply_to_all,
|
4
|
+
modular_increment,
|
5
|
+
)
|
6
|
+
from classiq.qmod.builtins.functions.standard_gates import PHASE, H, S, X, Z
|
7
|
+
from classiq.qmod.builtins.operations import (
|
8
|
+
allocate,
|
9
|
+
bind,
|
10
|
+
control,
|
11
|
+
invert,
|
12
|
+
repeat,
|
13
|
+
within_apply,
|
14
|
+
)
|
15
|
+
from classiq.qmod.qfunc import qfunc
|
16
|
+
from classiq.qmod.qmod_variable import QArray, QBit, QNum
|
17
|
+
from classiq.qmod.symbolic import pi
|
18
|
+
|
19
|
+
|
20
|
+
def _b_operator(q: QBit) -> None:
|
21
|
+
S(q)
|
22
|
+
H(q)
|
23
|
+
|
24
|
+
|
25
|
+
@qfunc
|
26
|
+
def _qct_d_operator(x: QNum, q: QBit) -> None:
|
27
|
+
_b_operator(q)
|
28
|
+
control(x == 0, lambda: invert(lambda: _b_operator(q)))
|
29
|
+
|
30
|
+
|
31
|
+
@qfunc
|
32
|
+
def _qct_pi_operator(x: QArray[QBit], q: QBit) -> None:
|
33
|
+
control(q == 1, lambda: apply_to_all(X, x))
|
34
|
+
control(q == 1, lambda: modular_increment(1, x))
|
35
|
+
|
36
|
+
|
37
|
+
def _t_operator(x: QArray) -> None:
|
38
|
+
_qct_d_operator(x[0 : x.len - 1], x[x.len - 1])
|
39
|
+
_qct_pi_operator(x[0 : x.len - 1], x[x.len - 1])
|
40
|
+
|
41
|
+
|
42
|
+
def _vn_operator(x: QArray[QBit], q: QBit) -> None:
|
43
|
+
H(q)
|
44
|
+
control(q == 1, lambda: apply_to_all(X, x))
|
45
|
+
|
46
|
+
|
47
|
+
def _d1_operator(x: QArray[QBit], q: QBit) -> None:
|
48
|
+
omega_exp = 2 * pi / (4 * 2**x.len)
|
49
|
+
|
50
|
+
# Li
|
51
|
+
control(q == 0, lambda: repeat(x.len, lambda k: PHASE(omega_exp * (2**k), x[k])))
|
52
|
+
# Ki
|
53
|
+
control(
|
54
|
+
q == 1,
|
55
|
+
lambda: repeat(
|
56
|
+
x.len,
|
57
|
+
lambda k: within_apply(
|
58
|
+
lambda: X(x[k]), lambda: PHASE(-omega_exp * (2**k), x[k])
|
59
|
+
),
|
60
|
+
),
|
61
|
+
)
|
62
|
+
PHASE(-omega_exp, q)
|
63
|
+
|
64
|
+
|
65
|
+
def _pi2_operator(x: QArray[QBit], q: QBit) -> None:
|
66
|
+
control(q == 1, lambda: modular_increment(1, x))
|
67
|
+
|
68
|
+
|
69
|
+
def _j_operator(q: QBit) -> None:
|
70
|
+
within_apply(lambda: Z(q), lambda: (S(q), H(q), S(q))) # type:ignore[arg-type]
|
71
|
+
|
72
|
+
|
73
|
+
def _b_t_operator(q: QBit) -> None:
|
74
|
+
H(q)
|
75
|
+
S(q)
|
76
|
+
|
77
|
+
|
78
|
+
def _d0dt_operator(x: QArray, q: QBit) -> None:
|
79
|
+
x_num: QNum = QNum("x_num", x.len, False, 0)
|
80
|
+
bind(x, x_num)
|
81
|
+
_b_t_operator(q)
|
82
|
+
control(x_num == 0, lambda: _j_operator(q))
|
83
|
+
bind(x_num, x)
|
84
|
+
|
85
|
+
|
86
|
+
def _un_dag_operator(x: QArray[QBit], q: QBit) -> None:
|
87
|
+
_d1_operator(x, q)
|
88
|
+
invert(lambda: _qct_pi_operator(x, q))
|
89
|
+
_d0dt_operator(x, q)
|
90
|
+
invert(lambda: _pi2_operator(x, q))
|
91
|
+
|
92
|
+
|
93
|
+
@qfunc
|
94
|
+
def qct_qst_type1(x: QArray[QBit]) -> None:
|
95
|
+
"""
|
96
|
+
[Qmod Classiq-library function]
|
97
|
+
|
98
|
+
Applies the quantum discrete cosine (DCT) and sine (DST)
|
99
|
+
transform of type 1 to the qubit array `x`.
|
100
|
+
Corresponds to the matrix (with $n\\equiv$`x.len`):
|
101
|
+
|
102
|
+
$$
|
103
|
+
\\left(
|
104
|
+
\begin{array}{ccc|c}
|
105
|
+
{} &{} &{} \\
|
106
|
+
{}&{\rm DCT}^{(1)}(2^{n-1}+1) & {}& 0\\
|
107
|
+
{} &{} &{} \\
|
108
|
+
\\hline
|
109
|
+
{} & 0 & {} & i{\rm DST}^{(1)}(2^{n-1}-1)
|
110
|
+
\\end{array}
|
111
|
+
\right)
|
112
|
+
$$
|
113
|
+
|
114
|
+
Args:
|
115
|
+
x: The qubit array to apply the transform to.
|
116
|
+
"""
|
117
|
+
within_apply(lambda: _t_operator(x), lambda: qft(x))
|
118
|
+
|
119
|
+
|
120
|
+
@qfunc
|
121
|
+
def qct_qst_type2(x: QArray[QBit], q: QBit) -> None:
|
122
|
+
"""
|
123
|
+
[Qmod Classiq-library function]
|
124
|
+
|
125
|
+
Applies the quantum discrete cosine (DCT) and sine (DST)
|
126
|
+
transform of type 2 to the qubit array `x` concatenated with `q`, with `q` being the MSB.
|
127
|
+
Corresponds to the matrix (with $n\\equiv$`x.len`+1):
|
128
|
+
|
129
|
+
$$
|
130
|
+
\\left(
|
131
|
+
\begin{array}{c|c}
|
132
|
+
{\rm DCT}^{(2)}(2^{n-1}) & 0\\
|
133
|
+
\\hline
|
134
|
+
0 & -{\rm DST}^{(2)}(2^{n-1})
|
135
|
+
\\end{array}
|
136
|
+
\right)
|
137
|
+
$$
|
138
|
+
|
139
|
+
Args:
|
140
|
+
x: The LSB part of the qubit array to apply the transform to.
|
141
|
+
q: The MSB of the qubit array to apply the transform to.
|
142
|
+
"""
|
143
|
+
extended_state: QArray = QArray("extended_state")
|
144
|
+
_vn_operator(x, q)
|
145
|
+
bind([x, q], extended_state)
|
146
|
+
qft(extended_state)
|
147
|
+
bind(extended_state, [x, q])
|
148
|
+
_un_dag_operator(x, q)
|
149
|
+
|
150
|
+
|
151
|
+
@qfunc
|
152
|
+
def qct_type2(x: QArray[QBit]) -> None:
|
153
|
+
"""
|
154
|
+
[Qmod Classiq-library function]
|
155
|
+
|
156
|
+
Applies the quantum discrete cosine (DCT)
|
157
|
+
transform of type 2, ${\rm DCT}^{(2)}$, to the qubit array `x`.
|
158
|
+
|
159
|
+
Args:
|
160
|
+
x: The qubit array to apply the transform to.
|
161
|
+
"""
|
162
|
+
q = QBit("q")
|
163
|
+
within_apply(lambda: allocate(1, q), lambda: qct_qst_type2(x, q))
|
164
|
+
|
165
|
+
|
166
|
+
@qfunc
|
167
|
+
def qst_type2(x: QArray[QBit]) -> None:
|
168
|
+
"""
|
169
|
+
[Qmod Classiq-library function]
|
170
|
+
|
171
|
+
Applies the quantum discrete sine (DST)
|
172
|
+
transform of type 2, ${\rm DST}^{(2)}$, to the qubit array `x`.
|
173
|
+
|
174
|
+
Args:
|
175
|
+
x: The qubit array to apply the transform to.
|
176
|
+
"""
|
177
|
+
q = QBit("q")
|
178
|
+
within_apply(
|
179
|
+
lambda: (allocate(1, q), X(q)), # type:ignore[arg-type]
|
180
|
+
lambda: qct_qst_type2(x, q),
|
181
|
+
)
|