classiq 0.38.0__py3-none-any.whl → 0.65.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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.4.dist-info}/METADATA +16 -9
- classiq-0.65.4.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.4.dist-info}/WHEEL +0 -0
@@ -1,24 +1,29 @@
|
|
1
1
|
import math
|
2
|
+
from collections.abc import Iterable
|
2
3
|
from typing import (
|
3
4
|
Any,
|
4
5
|
ClassVar,
|
5
|
-
Dict,
|
6
6
|
Generic,
|
7
|
-
Iterable,
|
8
7
|
Literal,
|
9
8
|
Optional,
|
10
|
-
Tuple,
|
11
|
-
Type,
|
12
9
|
TypeVar,
|
13
10
|
Union,
|
14
11
|
)
|
15
12
|
|
16
13
|
import pydantic
|
17
|
-
from pydantic
|
14
|
+
from pydantic import BaseModel
|
15
|
+
from pydantic_core.core_schema import ValidationInfo
|
16
|
+
from typing_extensions import Self
|
18
17
|
|
18
|
+
from classiq.interface.enum_utils import StrEnum
|
19
|
+
from classiq.interface.exceptions import ClassiqValueError
|
19
20
|
from classiq.interface.generator.arith import argument_utils, number_utils
|
20
|
-
from classiq.interface.generator.arith.argument_utils import
|
21
|
+
from classiq.interface.generator.arith.argument_utils import (
|
22
|
+
RegisterOrConst,
|
23
|
+
as_arithmetic_info,
|
24
|
+
)
|
21
25
|
from classiq.interface.generator.arith.arithmetic_operations import (
|
26
|
+
MODULO_WITH_FRACTION_PLACES_ERROR_MSG,
|
22
27
|
ArithmeticOperationParams,
|
23
28
|
)
|
24
29
|
from classiq.interface.generator.arith.ast_node_rewrite import (
|
@@ -28,9 +33,6 @@ from classiq.interface.generator.arith.register_user_input import RegisterArithm
|
|
28
33
|
from classiq.interface.generator.arith.unary_ops import Negation
|
29
34
|
from classiq.interface.generator.function_params import get_zero_input_name
|
30
35
|
|
31
|
-
from classiq._internals.enum_utils import StrEnum
|
32
|
-
from classiq.exceptions import ClassiqValueError
|
33
|
-
|
34
36
|
LeftDataT = TypeVar("LeftDataT")
|
35
37
|
RightDataT = TypeVar("RightDataT")
|
36
38
|
_NumericArgumentInplaceErrorMessage: str = "Cannot inplace the numeric argument {}"
|
@@ -51,23 +53,24 @@ class ArgToInplace(StrEnum):
|
|
51
53
|
|
52
54
|
|
53
55
|
class BinaryOpParams(
|
54
|
-
ArithmeticOperationParams,
|
56
|
+
ArithmeticOperationParams, BaseModel, Generic[LeftDataT, RightDataT]
|
55
57
|
):
|
56
58
|
left_arg: LeftDataT
|
57
59
|
right_arg: RightDataT
|
58
60
|
left_arg_name: ClassVar[str] = DEFAULT_LEFT_ARG_NAME
|
59
61
|
right_arg_name: ClassVar[str] = DEFAULT_RIGHT_ARG_NAME
|
60
62
|
|
61
|
-
@pydantic.
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
63
|
+
@pydantic.model_validator(mode="before")
|
64
|
+
@classmethod
|
65
|
+
def _clone_repeated_arg(cls, values: Any) -> dict[str, Any]:
|
66
|
+
if isinstance(values, dict):
|
67
|
+
left_arg = values.get("left_arg")
|
68
|
+
right_arg = values.get("right_arg")
|
69
|
+
|
70
|
+
if left_arg is right_arg and isinstance(left_arg, pydantic.BaseModel):
|
71
|
+
# In case both arguments refer to the same object, copy it.
|
72
|
+
# This prevents changes performed on one argument to affect the other.
|
73
|
+
values["right_arg"] = left_arg.model_copy(deep=True)
|
71
74
|
return values
|
72
75
|
|
73
76
|
def garbage_output_size(self) -> pydantic.NonNegativeInt:
|
@@ -105,19 +108,21 @@ class InplacableBinaryOpParams(
|
|
105
108
|
):
|
106
109
|
inplace_arg: Optional[ArgToInplace] = None
|
107
110
|
|
108
|
-
@pydantic.
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
111
|
+
@pydantic.model_validator(mode="before")
|
112
|
+
@classmethod
|
113
|
+
def _validate_inplace_arg(cls, values: Any) -> dict[str, Any]:
|
114
|
+
if isinstance(values, dict):
|
115
|
+
left_arg = values.get("left_arg")
|
116
|
+
right_arg = values.get("right_arg")
|
117
|
+
inplace_arg: Optional[ArgToInplace] = values.get("inplace_arg")
|
118
|
+
if inplace_arg == ArgToInplace.RIGHT and isinstance(right_arg, Numeric):
|
119
|
+
raise ClassiqValueError(
|
120
|
+
_NumericArgumentInplaceErrorMessage.format(right_arg)
|
121
|
+
)
|
122
|
+
elif inplace_arg == ArgToInplace.LEFT and isinstance(left_arg, Numeric):
|
123
|
+
raise ClassiqValueError(
|
124
|
+
_NumericArgumentInplaceErrorMessage.format(left_arg)
|
125
|
+
)
|
121
126
|
return values
|
122
127
|
|
123
128
|
def _create_ios(self) -> None:
|
@@ -154,9 +159,13 @@ class InplacableBinaryOpParams(
|
|
154
159
|
if self.inplace_arg is None:
|
155
160
|
return 0
|
156
161
|
arg = self.left_arg if self.inplace_arg == ArgToInplace.LEFT else self.right_arg
|
157
|
-
return max(
|
162
|
+
return max(
|
163
|
+
0, arg.integer_part_size - self.result_register.integer_part_size # type: ignore[attr-defined]
|
164
|
+
) + max(
|
165
|
+
0, arg.fraction_places - self.result_register.fraction_places # type: ignore[attr-defined]
|
166
|
+
)
|
158
167
|
|
159
|
-
def _carried_arguments(self) ->
|
168
|
+
def _carried_arguments(self) -> tuple[Optional[LeftDataT], Optional[RightDataT]]:
|
160
169
|
if self.inplace_arg == ArgToInplace.RIGHT and isinstance(
|
161
170
|
self.left_arg, RegisterArithmeticInfo
|
162
171
|
):
|
@@ -187,28 +196,28 @@ class InplacableBinaryOpParams(
|
|
187
196
|
yield ArgToInplace.LEFT
|
188
197
|
|
189
198
|
def get_params_inplace_options(self) -> Iterable["InplacableBinaryOpParams"]:
|
190
|
-
params_kwargs = self.
|
199
|
+
params_kwargs = self.model_copy().__dict__
|
191
200
|
for inplace_arg in self._get_binary_op_inplace_options():
|
192
201
|
params_kwargs["inplace_arg"] = inplace_arg
|
193
202
|
yield self.__class__(**params_kwargs)
|
194
203
|
|
195
204
|
|
196
205
|
class BinaryOpWithIntInputs(BinaryOpParams[RegisterOrInt, RegisterOrInt]):
|
197
|
-
@pydantic.
|
198
|
-
def validate_int_registers(
|
199
|
-
left_arg =
|
206
|
+
@pydantic.model_validator(mode="after")
|
207
|
+
def validate_int_registers(self) -> Self:
|
208
|
+
left_arg = self.left_arg
|
200
209
|
is_left_arg_float_register = (
|
201
210
|
isinstance(left_arg, RegisterArithmeticInfo)
|
202
211
|
and left_arg.fraction_places > 0
|
203
212
|
)
|
204
|
-
right_arg =
|
213
|
+
right_arg = self.right_arg
|
205
214
|
is_right_arg_float_register = (
|
206
215
|
isinstance(right_arg, RegisterArithmeticInfo)
|
207
216
|
and right_arg.fraction_places > 0
|
208
217
|
)
|
209
218
|
if is_left_arg_float_register or is_right_arg_float_register:
|
210
219
|
raise ClassiqValueError(BOOLEAN_OP_WITH_FRACTIONS_ERROR)
|
211
|
-
return
|
220
|
+
return self
|
212
221
|
|
213
222
|
@staticmethod
|
214
223
|
def _is_signed(arg: Union[int, RegisterArithmeticInfo]) -> bool:
|
@@ -259,15 +268,21 @@ class Adder(InplacableBinaryOpParams[RegisterOrConst, RegisterOrConst]):
|
|
259
268
|
output_name = "sum"
|
260
269
|
|
261
270
|
def _get_result_register(self) -> RegisterArithmeticInfo:
|
262
|
-
|
263
|
-
self.
|
271
|
+
left_arg = argument_utils.limit_fraction_places(
|
272
|
+
self.left_arg, self.machine_precision
|
273
|
+
)
|
274
|
+
right_arg = argument_utils.limit_fraction_places(
|
275
|
+
self.right_arg, self.machine_precision
|
276
|
+
)
|
277
|
+
lb = argument_utils.lower_bound(left_arg) + argument_utils.lower_bound(
|
278
|
+
right_arg
|
264
279
|
)
|
265
|
-
ub = argument_utils.upper_bound(
|
266
|
-
|
280
|
+
ub = argument_utils.upper_bound(left_arg) + argument_utils.upper_bound(
|
281
|
+
right_arg
|
267
282
|
)
|
268
283
|
fraction_places = max(
|
269
|
-
argument_utils.fraction_places(
|
270
|
-
argument_utils.fraction_places(
|
284
|
+
argument_utils.fraction_places(left_arg),
|
285
|
+
argument_utils.fraction_places(right_arg),
|
271
286
|
)
|
272
287
|
return RegisterArithmeticInfo(
|
273
288
|
size=self.output_size or self._get_output_size(ub, lb, fraction_places),
|
@@ -278,8 +293,9 @@ class Adder(InplacableBinaryOpParams[RegisterOrConst, RegisterOrConst]):
|
|
278
293
|
|
279
294
|
def _get_output_size(self, ub: float, lb: float, fraction_places: int) -> int:
|
280
295
|
if isinstance(self.left_arg, float) and self.left_arg == 0.0:
|
281
|
-
|
282
|
-
|
296
|
+
if isinstance(self.right_arg, RegisterArithmeticInfo):
|
297
|
+
return self.right_arg.size
|
298
|
+
return as_arithmetic_info(self.right_arg).size
|
283
299
|
elif isinstance(self.right_arg, float) and self.right_arg == 0.0:
|
284
300
|
assert isinstance(self.left_arg, RegisterArithmeticInfo)
|
285
301
|
return self.left_arg.size
|
@@ -291,60 +307,121 @@ class Adder(InplacableBinaryOpParams[RegisterOrConst, RegisterOrConst]):
|
|
291
307
|
class Subtractor(InplacableBinaryOpParams[RegisterOrConst, RegisterOrConst]):
|
292
308
|
output_name = "difference"
|
293
309
|
|
310
|
+
@staticmethod
|
311
|
+
def _get_effective_arg(
|
312
|
+
arg: RegisterOrConst, machine_precision: int
|
313
|
+
) -> RegisterOrConst:
|
314
|
+
return argument_utils.limit_fraction_places(arg, machine_precision)
|
315
|
+
|
316
|
+
@property
|
317
|
+
def effective_left_arg(self) -> RegisterOrConst:
|
318
|
+
return self._get_effective_arg(self.left_arg, self.machine_precision)
|
319
|
+
|
320
|
+
@property
|
321
|
+
def effective_right_arg(self) -> RegisterOrConst:
|
322
|
+
return self._get_effective_arg(self.right_arg, self.machine_precision)
|
323
|
+
|
324
|
+
@staticmethod
|
325
|
+
def _is_arg_trimmed_register(arg: RegisterOrConst, machine_precision: int) -> bool:
|
326
|
+
return (
|
327
|
+
isinstance(arg, RegisterArithmeticInfo)
|
328
|
+
and arg.fraction_places > machine_precision
|
329
|
+
)
|
330
|
+
|
331
|
+
@property
|
332
|
+
def left_arg_is_trimmed_register(self) -> bool:
|
333
|
+
return self._is_arg_trimmed_register(self.left_arg, self.machine_precision)
|
334
|
+
|
335
|
+
@property
|
336
|
+
def right_arg_is_trimmed_register(self) -> bool:
|
337
|
+
return self._is_arg_trimmed_register(self.right_arg, self.machine_precision)
|
338
|
+
|
294
339
|
def _get_result_register(self) -> RegisterArithmeticInfo:
|
295
340
|
bounds = (
|
296
|
-
argument_utils.lower_bound(self.
|
297
|
-
- argument_utils.upper_bound(self.
|
298
|
-
argument_utils.upper_bound(self.
|
299
|
-
- argument_utils.lower_bound(self.
|
341
|
+
argument_utils.lower_bound(self.effective_left_arg)
|
342
|
+
- argument_utils.upper_bound(self.effective_right_arg),
|
343
|
+
argument_utils.upper_bound(self.effective_left_arg)
|
344
|
+
- argument_utils.lower_bound(self.effective_right_arg),
|
300
345
|
)
|
301
346
|
fraction_places = max(
|
302
|
-
argument_utils.fraction_places(self.
|
303
|
-
argument_utils.fraction_places(self.
|
347
|
+
argument_utils.fraction_places(self.effective_left_arg),
|
348
|
+
argument_utils.fraction_places(self.effective_right_arg),
|
304
349
|
)
|
305
350
|
|
351
|
+
size = self.output_size or self._get_output_size(bounds, fraction_places)
|
352
|
+
is_signed = self._include_sign and min(bounds) < 0
|
306
353
|
return RegisterArithmeticInfo(
|
307
|
-
size=
|
354
|
+
size=size,
|
308
355
|
fraction_places=fraction_places,
|
309
|
-
is_signed=
|
310
|
-
bounds=self._legal_bounds(
|
356
|
+
is_signed=is_signed,
|
357
|
+
bounds=self._legal_bounds(
|
358
|
+
bounds,
|
359
|
+
RegisterArithmeticInfo.get_maximal_bounds(
|
360
|
+
size=size, is_signed=is_signed, fraction_places=fraction_places
|
361
|
+
),
|
362
|
+
),
|
311
363
|
)
|
312
364
|
|
313
365
|
def _get_output_size(
|
314
|
-
self, bounds:
|
366
|
+
self, bounds: tuple[float, float], fraction_places: int
|
315
367
|
) -> int:
|
316
|
-
if isinstance(self.right_arg, float) and self.
|
317
|
-
assert isinstance(self.
|
318
|
-
return self.
|
368
|
+
if isinstance(self.right_arg, float) and self.effective_right_arg == 0:
|
369
|
+
assert isinstance(self.effective_left_arg, RegisterArithmeticInfo)
|
370
|
+
return self.effective_left_arg.size
|
319
371
|
integer_part_size = number_utils.bounds_to_integer_part_size(*bounds)
|
320
372
|
size_needed = integer_part_size + fraction_places
|
321
373
|
return size_needed
|
322
374
|
|
323
375
|
def garbage_output_size(self) -> pydantic.NonNegativeInt:
|
324
|
-
if
|
376
|
+
if (
|
377
|
+
not self.left_arg_is_trimmed_register
|
378
|
+
and not self.right_arg_is_trimmed_register
|
379
|
+
):
|
380
|
+
return self._untrimmed_garbage_output_size()
|
381
|
+
if not self.is_inplaced():
|
382
|
+
return 0
|
383
|
+
inplace_arg_name = (
|
384
|
+
self.left_arg_name
|
385
|
+
if self.inplace_arg == ArgToInplace.LEFT
|
386
|
+
else self.right_arg_name
|
387
|
+
)
|
388
|
+
return max(
|
389
|
+
0,
|
390
|
+
self._inputs[inplace_arg_name].fraction_places
|
391
|
+
- self.result_register.fraction_places,
|
392
|
+
)
|
393
|
+
|
394
|
+
def _untrimmed_garbage_output_size(self) -> pydantic.NonNegativeInt:
|
395
|
+
if not isinstance(self.effective_right_arg, RegisterArithmeticInfo):
|
325
396
|
adder_params = Adder(
|
326
|
-
left_arg=self.
|
327
|
-
right_arg=-self.
|
397
|
+
left_arg=self.effective_left_arg,
|
398
|
+
right_arg=-self.effective_right_arg,
|
328
399
|
output_size=self.output_size,
|
329
400
|
inplace_arg=self.inplace_arg,
|
330
401
|
)
|
331
402
|
return adder_params.garbage_output_size()
|
332
403
|
|
333
404
|
negation_params = Negation(
|
334
|
-
arg=self.
|
405
|
+
arg=self.effective_right_arg,
|
335
406
|
output_size=self.negation_output_size,
|
336
407
|
inplace=self.should_inplace_negation,
|
408
|
+
bypass_bounds_validation=True,
|
337
409
|
)
|
338
410
|
negation_result = negation_params.result_register
|
339
|
-
if self.output_size is None and max(self.
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
411
|
+
if self.output_size is None and max(self.effective_right_arg.bounds) > 0:
|
412
|
+
bounds = (
|
413
|
+
-max(self.effective_right_arg.bounds),
|
414
|
+
-min(self.effective_right_arg.bounds),
|
415
|
+
)
|
416
|
+
negation_result = RegisterArithmeticInfo(
|
417
|
+
size=negation_result.size,
|
418
|
+
fraction_places=negation_result.fraction_places,
|
419
|
+
is_signed=True,
|
420
|
+
bounds=bounds,
|
421
|
+
bypass_bounds_validation=True,
|
345
422
|
)
|
346
423
|
adder_params = Adder(
|
347
|
-
left_arg=self.
|
424
|
+
left_arg=self.effective_left_arg,
|
348
425
|
right_arg=negation_result,
|
349
426
|
output_size=self.output_size,
|
350
427
|
inplace_arg=self.arg_to_inplace_adder,
|
@@ -359,10 +436,10 @@ class Subtractor(InplacableBinaryOpParams[RegisterOrConst, RegisterOrConst]):
|
|
359
436
|
return self.inplace_arg == ArgToInplace.LEFT
|
360
437
|
|
361
438
|
def _expected_negation_output_size(self) -> int:
|
362
|
-
return argument_utils.fraction_places(self.
|
439
|
+
return argument_utils.fraction_places(self.effective_right_arg) + min(
|
363
440
|
self.result_register.integer_part_size,
|
364
441
|
number_utils.bounds_to_integer_part_size(
|
365
|
-
*(-bound for bound in argument_utils.bounds(self.
|
442
|
+
*(-bound for bound in argument_utils.bounds(self.effective_right_arg))
|
366
443
|
),
|
367
444
|
)
|
368
445
|
|
@@ -390,54 +467,61 @@ class Multiplier(BinaryOpWithFloatInputs):
|
|
390
467
|
|
391
468
|
def expected_fraction_places(self) -> int:
|
392
469
|
return argument_utils.fraction_places(
|
393
|
-
argument_utils.limit_fraction_places(
|
394
|
-
self.left_arg, machine_precision=self.machine_precision
|
395
|
-
)
|
470
|
+
argument_utils.limit_fraction_places(self.left_arg, self.machine_precision)
|
396
471
|
) + argument_utils.fraction_places(
|
397
|
-
argument_utils.limit_fraction_places(
|
398
|
-
self.right_arg, machine_precision=self.machine_precision
|
399
|
-
)
|
472
|
+
argument_utils.limit_fraction_places(self.right_arg, self.machine_precision)
|
400
473
|
)
|
401
474
|
|
402
475
|
@staticmethod
|
403
476
|
def _get_bounds(
|
404
|
-
args:
|
405
|
-
) ->
|
477
|
+
args: tuple[RegisterOrConst, RegisterOrConst], machine_precision: int
|
478
|
+
) -> tuple[float, float]:
|
406
479
|
extremal_values = [
|
407
480
|
left * right
|
408
481
|
for left in argument_utils.bounds(args[0])
|
409
482
|
for right in argument_utils.bounds(args[1])
|
410
483
|
]
|
411
484
|
return (
|
412
|
-
number_utils.limit_fraction_places(
|
413
|
-
|
414
|
-
),
|
415
|
-
number_utils.limit_fraction_places(
|
416
|
-
max(extremal_values), machine_precision=machine_precision
|
417
|
-
),
|
485
|
+
number_utils.limit_fraction_places(min(extremal_values), machine_precision),
|
486
|
+
number_utils.limit_fraction_places(max(extremal_values), machine_precision),
|
418
487
|
)
|
419
488
|
|
420
489
|
def _get_result_register(self) -> RegisterArithmeticInfo:
|
421
490
|
fraction_places = min(self.machine_precision, self.expected_fraction_places())
|
422
491
|
left_arg = argument_utils.limit_fraction_places(
|
423
|
-
self.left_arg,
|
492
|
+
self.left_arg, self.machine_precision
|
424
493
|
)
|
425
494
|
right_arg = argument_utils.limit_fraction_places(
|
426
|
-
self.right_arg,
|
495
|
+
self.right_arg, self.machine_precision
|
427
496
|
)
|
428
497
|
bounds = self._get_bounds((left_arg, right_arg), self.machine_precision)
|
498
|
+
if self.output_size:
|
499
|
+
if fraction_places:
|
500
|
+
raise ValueError(MODULO_WITH_FRACTION_PLACES_ERROR_MSG)
|
501
|
+
max_bounds = RegisterArithmeticInfo.get_maximal_bounds(
|
502
|
+
size=self.output_size, is_signed=False, fraction_places=0
|
503
|
+
)
|
504
|
+
bounds = number_utils.bounds_cut(bounds, max_bounds)
|
429
505
|
|
506
|
+
size = self.output_size or self._get_output_size(
|
507
|
+
bounds, fraction_places, left_arg, right_arg
|
508
|
+
)
|
509
|
+
is_signed = self._include_sign and min(bounds) < 0
|
430
510
|
return RegisterArithmeticInfo(
|
431
|
-
size=
|
432
|
-
or self._get_output_size(bounds, fraction_places, left_arg, right_arg),
|
511
|
+
size=size,
|
433
512
|
fraction_places=fraction_places,
|
434
|
-
is_signed=
|
435
|
-
bounds=self._legal_bounds(
|
513
|
+
is_signed=is_signed,
|
514
|
+
bounds=self._legal_bounds(
|
515
|
+
bounds,
|
516
|
+
RegisterArithmeticInfo.get_maximal_bounds(
|
517
|
+
size=size, is_signed=is_signed, fraction_places=fraction_places
|
518
|
+
),
|
519
|
+
),
|
436
520
|
)
|
437
521
|
|
438
522
|
@staticmethod
|
439
523
|
def _get_output_size(
|
440
|
-
bounds:
|
524
|
+
bounds: tuple[float, float],
|
441
525
|
fraction_places: int,
|
442
526
|
left_arg: Union[RegisterArithmeticInfo, float],
|
443
527
|
right_arg: Union[RegisterArithmeticInfo, float],
|
@@ -497,7 +581,8 @@ class LessEqual(Comparator):
|
|
497
581
|
class Power(BinaryOpParams[RegisterArithmeticInfo, pydantic.PositiveInt]):
|
498
582
|
output_name = "powered"
|
499
583
|
|
500
|
-
@pydantic.
|
584
|
+
@pydantic.field_validator("right_arg", mode="before")
|
585
|
+
@classmethod
|
501
586
|
def _validate_legal_power(cls, right_arg: Any) -> pydantic.PositiveInt:
|
502
587
|
if not float(right_arg).is_integer():
|
503
588
|
raise ClassiqValueError("Power must be an integer")
|
@@ -509,13 +594,13 @@ class Power(BinaryOpParams[RegisterArithmeticInfo, pydantic.PositiveInt]):
|
|
509
594
|
return (
|
510
595
|
argument_utils.fraction_places(
|
511
596
|
argument_utils.limit_fraction_places(
|
512
|
-
self.left_arg,
|
597
|
+
self.left_arg, self.machine_precision
|
513
598
|
)
|
514
599
|
)
|
515
600
|
* self.right_arg
|
516
601
|
)
|
517
602
|
|
518
|
-
def _get_result_bounds(self) ->
|
603
|
+
def _get_result_bounds(self) -> tuple[float, float]:
|
519
604
|
bounds = [
|
520
605
|
number_utils.limit_fraction_places(
|
521
606
|
bound, machine_precision=self.machine_precision
|
@@ -556,11 +641,11 @@ class Power(BinaryOpParams[RegisterArithmeticInfo, pydantic.PositiveInt]):
|
|
556
641
|
|
557
642
|
def _get_inner_action_garbage_size(
|
558
643
|
self,
|
559
|
-
action_type: Union[
|
644
|
+
action_type: Union[type["Power"], type[Multiplier]],
|
560
645
|
*,
|
561
646
|
arg: RegisterArithmeticInfo,
|
562
647
|
action_right_arg: RegisterOrConst,
|
563
|
-
compute_power: int
|
648
|
+
compute_power: int,
|
564
649
|
) -> pydantic.NonNegativeInt:
|
565
650
|
inner_compute_power_params = Power(
|
566
651
|
left_arg=arg,
|
@@ -609,19 +694,19 @@ class LShift(EffectiveUnaryOpParams[pydantic.NonNegativeInt]):
|
|
609
694
|
output_name = "left_shifted"
|
610
695
|
inplace_arg: Optional[ArgToInplace] = ArgToInplace.LEFT
|
611
696
|
|
612
|
-
@pydantic.
|
613
|
-
def _validate_legal_modulo(
|
614
|
-
output_size =
|
697
|
+
@pydantic.model_validator(mode="after")
|
698
|
+
def _validate_legal_modulo(self) -> Self:
|
699
|
+
output_size = self.output_size
|
615
700
|
if output_size is None:
|
616
|
-
return
|
617
|
-
arg =
|
618
|
-
shift =
|
701
|
+
return self
|
702
|
+
arg = self.left_arg
|
703
|
+
shift = self.right_arg
|
619
704
|
if not isinstance(arg, RegisterArithmeticInfo):
|
620
705
|
raise ClassiqValueError("left arg must be a RegisterArithmeticInfo")
|
621
706
|
if not isinstance(shift, int):
|
622
707
|
raise ClassiqValueError("Shift must be an integer")
|
623
708
|
assert arg.fraction_places - shift <= 0, _FLOATING_POINT_MODULO_ERROR_MESSAGE
|
624
|
-
return
|
709
|
+
return self
|
625
710
|
|
626
711
|
def garbage_output_size(self) -> pydantic.NonNegativeInt:
|
627
712
|
if self.inplace_arg is None or self.output_size is None:
|
@@ -650,21 +735,21 @@ class RShift(EffectiveUnaryOpParams[pydantic.NonNegativeInt]):
|
|
650
735
|
def _shifted_fraction_places(*, arg: RegisterArithmeticInfo, shift: int) -> int:
|
651
736
|
return arg.fraction_places * int(arg.is_signed or shift < arg.size)
|
652
737
|
|
653
|
-
@pydantic.
|
654
|
-
def _validate_legal_modulo(
|
655
|
-
output_size =
|
738
|
+
@pydantic.model_validator(mode="after")
|
739
|
+
def _validate_legal_modulo(self) -> Self:
|
740
|
+
output_size = self.output_size
|
656
741
|
if output_size is None:
|
657
|
-
return
|
658
|
-
arg =
|
659
|
-
shift =
|
742
|
+
return self
|
743
|
+
arg = self.left_arg
|
744
|
+
shift = self.right_arg
|
660
745
|
if not isinstance(arg, RegisterArithmeticInfo):
|
661
746
|
raise ClassiqValueError("left arg must be a RegisterArithmeticInfo")
|
662
747
|
if not isinstance(shift, int):
|
663
748
|
raise ClassiqValueError("Shift must be an integer")
|
664
749
|
assert (
|
665
|
-
|
750
|
+
self._shifted_fraction_places(arg=arg, shift=shift) == 0
|
666
751
|
), _FLOATING_POINT_MODULO_ERROR_MESSAGE
|
667
|
-
return
|
752
|
+
return self
|
668
753
|
|
669
754
|
def garbage_output_size(self) -> pydantic.NonNegativeInt:
|
670
755
|
if self.inplace_arg is None:
|
@@ -694,16 +779,16 @@ class CyclicShift(EffectiveUnaryOpParams[int]):
|
|
694
779
|
output_name = "cyclic_shifted"
|
695
780
|
inplace_arg: Optional[ArgToInplace] = ArgToInplace.LEFT
|
696
781
|
|
697
|
-
@pydantic.
|
698
|
-
def _validate_legal_modulo(
|
699
|
-
output_size =
|
782
|
+
@pydantic.model_validator(mode="after")
|
783
|
+
def _validate_legal_modulo(self) -> Self:
|
784
|
+
output_size = self.output_size
|
700
785
|
if output_size is None:
|
701
|
-
return
|
702
|
-
arg =
|
786
|
+
return self
|
787
|
+
arg = self.left_arg
|
703
788
|
if not isinstance(arg, RegisterArithmeticInfo):
|
704
789
|
raise ClassiqValueError("left arg must be a RegisterArithmeticInfo")
|
705
790
|
assert arg.fraction_places == 0, _FLOATING_POINT_MODULO_ERROR_MESSAGE
|
706
|
-
return
|
791
|
+
return self
|
707
792
|
|
708
793
|
def garbage_output_size(self) -> pydantic.NonNegativeInt:
|
709
794
|
if self.inplace_arg is None:
|
@@ -722,27 +807,30 @@ class Modulo(EffectiveUnaryOpParams[int]):
|
|
722
807
|
output_name = "modulus"
|
723
808
|
inplace_arg: Optional[ArgToInplace] = ArgToInplace.LEFT
|
724
809
|
|
725
|
-
@pydantic.
|
810
|
+
@pydantic.field_validator("left_arg", mode="before")
|
811
|
+
@classmethod
|
726
812
|
def _validate_left_arg_is_integer(
|
727
813
|
cls, left_arg: RegisterArithmeticInfo
|
728
814
|
) -> RegisterArithmeticInfo:
|
729
815
|
assert left_arg.fraction_places == 0, _FLOATING_POINT_MODULO_ERROR_MESSAGE
|
730
816
|
return left_arg
|
731
817
|
|
732
|
-
@pydantic.
|
818
|
+
@pydantic.field_validator("right_arg", mode="before")
|
819
|
+
@classmethod
|
733
820
|
def _validate_right_arg_is_a_power_of_two(
|
734
|
-
cls, right_arg: int,
|
821
|
+
cls, right_arg: int, info: ValidationInfo
|
735
822
|
) -> int:
|
736
823
|
repr_qubits_float = math.log2(right_arg)
|
737
824
|
repr_qubits = round(repr_qubits_float)
|
738
825
|
assert abs(repr_qubits - repr_qubits_float) < 10**-8, NOT_POWER_OF_TWO_ERROR_MSG
|
739
|
-
output_size =
|
826
|
+
output_size = info.data.get("output_size")
|
740
827
|
if output_size is not None:
|
741
828
|
repr_qubits = min(repr_qubits, output_size)
|
742
|
-
|
829
|
+
info.data["output_size"] = None
|
743
830
|
return 2 ** (repr_qubits)
|
744
831
|
|
745
832
|
def _get_result_register(self) -> RegisterArithmeticInfo:
|
746
|
-
|
747
|
-
|
748
|
-
|
833
|
+
size = round(math.log2(self.right_arg))
|
834
|
+
if size <= 0:
|
835
|
+
raise ClassiqValueError("Cannot use a quantum expression with zero size")
|
836
|
+
return RegisterArithmeticInfo(size=size, is_signed=False, fraction_places=0)
|