classiq 0.93.0__py3-none-any.whl → 0.100.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- classiq/__init__.py +11 -19
- classiq/_analyzer_extras/_ipywidgets_async_extension.py +7 -7
- classiq/_analyzer_extras/interactive_hardware.py +19 -12
- classiq/_internals/api_wrapper.py +31 -142
- classiq/_internals/async_utils.py +4 -7
- classiq/_internals/authentication/auth0.py +41 -15
- classiq/_internals/authentication/authorization_code.py +9 -0
- classiq/_internals/authentication/authorization_flow.py +41 -0
- classiq/_internals/authentication/device.py +33 -52
- classiq/_internals/authentication/hybrid_flow.py +19 -0
- classiq/_internals/authentication/password_manager.py +13 -13
- classiq/_internals/authentication/token_manager.py +9 -9
- classiq/_internals/client.py +17 -44
- classiq/_internals/config.py +19 -5
- classiq/_internals/help.py +1 -2
- classiq/_internals/host_checker.py +3 -3
- classiq/_internals/jobs.py +14 -14
- classiq/_internals/type_validation.py +3 -3
- classiq/analyzer/analyzer.py +18 -18
- classiq/analyzer/rb.py +17 -8
- classiq/analyzer/show_interactive_hack.py +1 -1
- classiq/applications/__init__.py +2 -2
- classiq/applications/chemistry/__init__.py +0 -30
- classiq/applications/chemistry/op_utils.py +4 -4
- classiq/applications/chemistry/problems.py +3 -3
- classiq/applications/chemistry/ucc.py +1 -2
- classiq/applications/chemistry/z2_symmetries.py +4 -4
- classiq/applications/combinatorial_helpers/allowed_constraints.py +1 -3
- classiq/applications/combinatorial_helpers/arithmetic/arithmetic_expression.py +2 -1
- classiq/applications/combinatorial_helpers/combinatorial_problem_utils.py +2 -2
- classiq/applications/combinatorial_helpers/encoding_mapping.py +2 -3
- classiq/applications/combinatorial_helpers/encoding_utils.py +2 -2
- classiq/applications/combinatorial_helpers/optimization_model.py +3 -4
- classiq/applications/combinatorial_helpers/pauli_helpers/pauli_sparsing.py +2 -2
- classiq/applications/combinatorial_helpers/pyomo_utils.py +8 -8
- classiq/applications/combinatorial_helpers/sympy_utils.py +1 -3
- classiq/applications/combinatorial_helpers/transformations/encoding.py +3 -3
- classiq/applications/combinatorial_helpers/transformations/fixed_variables.py +1 -2
- classiq/applications/combinatorial_optimization/combinatorial_optimization_config.py +2 -3
- classiq/applications/combinatorial_optimization/combinatorial_optimization_model_constructor.py +4 -6
- classiq/applications/combinatorial_optimization/combinatorial_problem.py +15 -10
- classiq/applications/hamiltonian/pauli_decomposition.py +6 -4
- classiq/applications/iqae/iqae.py +14 -11
- classiq/applications/qnn/datasets/dataset_base_classes.py +6 -6
- classiq/applications/qnn/datasets/dataset_parity.py +6 -6
- classiq/applications/qnn/gradients/simple_quantum_gradient.py +1 -1
- classiq/applications/qnn/qlayer.py +9 -8
- classiq/applications/qnn/torch_utils.py +5 -6
- classiq/applications/qnn/types.py +2 -1
- classiq/applications/qsp/__init__.py +20 -2
- classiq/applications/qsp/qsp.py +238 -10
- classiq/applications/qsvm/qsvm_data_generation.py +1 -2
- classiq/evaluators/classical_expression.py +0 -4
- classiq/evaluators/parameter_types.py +10 -8
- classiq/evaluators/qmod_annotated_expression.py +31 -26
- classiq/evaluators/qmod_expression_visitors/qmod_expression_evaluator.py +14 -14
- classiq/evaluators/qmod_expression_visitors/qmod_expression_simplifier.py +2 -1
- classiq/evaluators/qmod_expression_visitors/sympy_wrappers.py +8 -8
- classiq/evaluators/qmod_node_evaluators/binary_op_evaluation.py +4 -4
- classiq/evaluators/qmod_node_evaluators/classical_function_evaluation.py +14 -4
- classiq/evaluators/qmod_node_evaluators/list_evaluation.py +2 -2
- classiq/evaluators/qmod_node_evaluators/numeric_attrs_utils.py +3 -3
- classiq/evaluators/qmod_node_evaluators/subscript_evaluation.py +9 -9
- classiq/evaluators/qmod_node_evaluators/utils.py +6 -6
- classiq/evaluators/qmod_type_inference/classical_type_inference.py +9 -10
- classiq/evaluators/qmod_type_inference/quantum_type_inference.py +5 -5
- classiq/execution/__init__.py +0 -3
- classiq/execution/execution_session.py +28 -21
- classiq/execution/jobs.py +26 -26
- classiq/execution/qnn.py +1 -2
- classiq/execution/user_budgets.py +71 -37
- classiq/executor.py +1 -3
- classiq/interface/_version.py +1 -1
- classiq/interface/analyzer/analysis_params.py +4 -4
- classiq/interface/analyzer/cytoscape_graph.py +3 -3
- classiq/interface/analyzer/result.py +4 -4
- classiq/interface/ast_node.py +3 -3
- classiq/interface/backend/backend_preferences.py +26 -50
- classiq/interface/backend/ionq/ionq_quantum_program.py +5 -5
- classiq/interface/backend/provider_config/__init__.py +0 -0
- classiq/interface/backend/provider_config/provider_config.py +8 -0
- classiq/interface/backend/provider_config/providers/__init__.py +0 -0
- classiq/interface/backend/provider_config/providers/alice_bob.py +47 -0
- classiq/interface/backend/provider_config/providers/aqt.py +16 -0
- classiq/interface/backend/provider_config/providers/azure.py +37 -0
- classiq/interface/backend/provider_config/providers/braket.py +39 -0
- classiq/interface/backend/provider_config/providers/ibm.py +26 -0
- classiq/interface/backend/provider_config/providers/ionq.py +22 -0
- classiq/interface/backend/quantum_backend_providers.py +20 -2
- classiq/interface/chemistry/ansatz_library.py +3 -5
- classiq/interface/chemistry/operator.py +3 -3
- classiq/interface/combinatorial_optimization/examples/knapsack.py +2 -4
- classiq/interface/combinatorial_optimization/examples/tsp_digraph.py +1 -2
- classiq/interface/compression_utils.py +2 -3
- classiq/interface/debug_info/debug_info.py +8 -7
- classiq/interface/exceptions.py +6 -7
- classiq/interface/execution/primitives.py +6 -6
- classiq/interface/executor/estimate_cost.py +1 -1
- classiq/interface/executor/execution_preferences.py +3 -5
- classiq/interface/executor/execution_request.py +10 -10
- classiq/interface/executor/execution_result.py +1 -2
- classiq/interface/executor/quantum_code.py +8 -8
- classiq/interface/executor/result.py +28 -18
- classiq/interface/executor/user_budget.py +21 -17
- classiq/interface/executor/vqe_result.py +5 -6
- classiq/interface/generator/ansatz_library.py +6 -8
- classiq/interface/generator/application_apis/__init__.py +0 -3
- classiq/interface/generator/arith/arithmetic.py +2 -2
- classiq/interface/generator/arith/arithmetic_arg_type_validator.py +2 -3
- classiq/interface/generator/arith/arithmetic_expression_abc.py +4 -5
- classiq/interface/generator/arith/arithmetic_expression_parser.py +11 -4
- classiq/interface/generator/arith/arithmetic_expression_validator.py +12 -15
- classiq/interface/generator/arith/arithmetic_operations.py +4 -6
- classiq/interface/generator/arith/arithmetic_param_getters.py +70 -107
- classiq/interface/generator/arith/arithmetic_result_builder.py +4 -4
- classiq/interface/generator/arith/ast_node_rewrite.py +8 -4
- classiq/interface/generator/arith/binary_ops.py +15 -40
- classiq/interface/generator/arith/logical_ops.py +2 -3
- classiq/interface/generator/arith/number_utils.py +2 -2
- classiq/interface/generator/arith/register_user_input.py +3 -3
- classiq/interface/generator/arith/unary_ops.py +2 -2
- classiq/interface/generator/circuit_code/circuit_code.py +8 -10
- classiq/interface/generator/circuit_code/types_and_constants.py +1 -1
- classiq/interface/generator/complex_type.py +2 -2
- classiq/interface/generator/copy.py +1 -3
- classiq/interface/generator/expressions/atomic_expression_functions.py +0 -5
- classiq/interface/generator/expressions/evaluated_expression.py +2 -3
- classiq/interface/generator/expressions/expression.py +2 -2
- classiq/interface/generator/expressions/proxies/classical/classical_array_proxy.py +4 -7
- classiq/interface/generator/function_param_list.py +0 -40
- classiq/interface/generator/function_params.py +5 -6
- classiq/interface/generator/functions/classical_function_declaration.py +2 -2
- classiq/interface/generator/functions/classical_type.py +3 -3
- classiq/interface/generator/functions/type_modifier.py +0 -15
- classiq/interface/generator/functions/type_name.py +2 -2
- classiq/interface/generator/generated_circuit_data.py +14 -18
- classiq/interface/generator/generation_request.py +35 -0
- classiq/interface/generator/hamiltonian_evolution/exponentiation.py +2 -4
- classiq/interface/generator/hardware/hardware_data.py +8 -8
- classiq/interface/generator/hardware_efficient_ansatz.py +9 -9
- classiq/interface/generator/mcu.py +3 -3
- classiq/interface/generator/mcx.py +3 -3
- classiq/interface/generator/model/constraints.py +34 -5
- classiq/interface/generator/model/preferences/preferences.py +15 -21
- classiq/interface/generator/model/quantum_register.py +7 -10
- classiq/interface/generator/noise_properties.py +3 -7
- classiq/interface/generator/parameters.py +1 -1
- classiq/interface/generator/partitioned_register.py +1 -2
- classiq/interface/generator/preferences/qasm_to_qmod_params.py +11 -0
- classiq/interface/generator/quantum_function_call.py +9 -12
- classiq/interface/generator/quantum_program.py +10 -23
- classiq/interface/generator/range_types.py +3 -3
- classiq/interface/generator/slice_parsing_utils.py +4 -5
- classiq/interface/generator/standard_gates/standard_gates.py +2 -4
- classiq/interface/generator/synthesis_execution_parameter.py +1 -3
- classiq/interface/generator/synthesis_metadata/synthesis_duration.py +9 -0
- classiq/interface/generator/synthesis_metadata/synthesis_execution_data.py +2 -3
- classiq/interface/generator/transpiler_basis_gates.py +10 -4
- classiq/interface/generator/types/builtin_enum_declarations.py +0 -145
- classiq/interface/generator/types/compilation_metadata.py +13 -2
- classiq/interface/generator/types/enum_declaration.py +2 -1
- classiq/interface/generator/validations/flow_graph.py +3 -3
- classiq/interface/generator/visitor.py +10 -12
- classiq/interface/hardware.py +2 -3
- classiq/interface/helpers/classproperty.py +2 -2
- classiq/interface/helpers/custom_encoders.py +2 -1
- classiq/interface/helpers/custom_pydantic_types.py +1 -1
- classiq/interface/helpers/text_utils.py +5 -4
- classiq/interface/ide/visual_model.py +6 -5
- classiq/interface/interface_version.py +1 -1
- classiq/interface/jobs.py +3 -3
- classiq/interface/model/allocate.py +4 -4
- classiq/interface/model/bind_operation.py +3 -0
- classiq/interface/model/block.py +6 -2
- classiq/interface/model/bounds.py +3 -3
- classiq/interface/model/classical_if.py +4 -0
- classiq/interface/model/control.py +8 -1
- classiq/interface/model/inplace_binary_operation.py +2 -2
- classiq/interface/model/invert.py +4 -0
- classiq/interface/model/model.py +4 -4
- classiq/interface/model/model_visitor.py +40 -1
- classiq/interface/model/parameter.py +1 -3
- classiq/interface/model/port_declaration.py +1 -1
- classiq/interface/model/power.py +4 -0
- classiq/interface/model/quantum_expressions/quantum_expression.py +1 -2
- classiq/interface/model/quantum_function_call.py +3 -6
- classiq/interface/model/quantum_function_declaration.py +1 -0
- classiq/interface/model/quantum_lambda_function.py +4 -4
- classiq/interface/model/quantum_statement.py +11 -4
- classiq/interface/model/quantum_type.py +14 -14
- classiq/interface/model/repeat.py +4 -0
- classiq/interface/model/skip_control.py +4 -0
- classiq/interface/model/validation_handle.py +2 -3
- classiq/interface/model/variable_declaration_statement.py +2 -2
- classiq/interface/model/within_apply_operation.py +4 -0
- classiq/interface/pretty_print/expression_to_qmod.py +3 -4
- classiq/interface/server/routes.py +0 -16
- classiq/interface/source_reference.py +3 -4
- classiq/model_expansions/arithmetic.py +11 -7
- classiq/model_expansions/arithmetic_compute_result_attrs.py +40 -28
- classiq/model_expansions/capturing/captured_vars.py +3 -3
- classiq/model_expansions/capturing/mangling_utils.py +1 -2
- classiq/model_expansions/closure.py +12 -11
- classiq/model_expansions/function_builder.py +14 -6
- classiq/model_expansions/generative_functions.py +7 -12
- classiq/model_expansions/interpreters/base_interpreter.py +3 -7
- classiq/model_expansions/interpreters/frontend_generative_interpreter.py +2 -1
- classiq/model_expansions/interpreters/generative_interpreter.py +5 -3
- classiq/model_expansions/quantum_operations/allocate.py +4 -4
- classiq/model_expansions/quantum_operations/assignment_result_processor.py +2 -4
- classiq/model_expansions/quantum_operations/call_emitter.py +31 -40
- classiq/model_expansions/quantum_operations/declarative_call_emitter.py +2 -2
- classiq/model_expansions/quantum_operations/emitter.py +3 -5
- classiq/model_expansions/quantum_operations/expression_evaluator.py +3 -3
- classiq/model_expansions/quantum_operations/skip_control_verifier.py +1 -2
- classiq/model_expansions/quantum_operations/variable_decleration.py +2 -2
- classiq/model_expansions/scope.py +7 -7
- classiq/model_expansions/scope_initialization.py +4 -0
- classiq/model_expansions/visitors/symbolic_param_inference.py +6 -6
- classiq/model_expansions/visitors/uncomputation_signature_inference.py +328 -0
- classiq/model_expansions/visitors/variable_references.py +15 -14
- classiq/open_library/functions/__init__.py +41 -11
- classiq/open_library/functions/amplitude_loading.py +81 -0
- classiq/open_library/functions/discrete_sine_cosine_transform.py +5 -5
- classiq/open_library/functions/encodings.py +182 -0
- classiq/open_library/functions/grover.py +8 -10
- classiq/open_library/functions/lcu.py +47 -18
- classiq/open_library/functions/modular_exponentiation.py +93 -8
- classiq/open_library/functions/qsvt.py +66 -79
- classiq/open_library/functions/qsvt_temp.py +536 -0
- classiq/open_library/functions/state_preparation.py +137 -31
- classiq/qmod/__init__.py +6 -4
- classiq/qmod/builtins/classical_execution_primitives.py +4 -23
- classiq/qmod/builtins/classical_functions.py +1 -42
- classiq/qmod/builtins/enums.py +15 -153
- classiq/qmod/builtins/functions/__init__.py +9 -18
- classiq/qmod/builtins/functions/allocation.py +25 -4
- classiq/qmod/builtins/functions/arithmetic.py +22 -27
- classiq/qmod/builtins/functions/exponentiation.py +51 -2
- classiq/qmod/builtins/functions/mcx_func.py +7 -0
- classiq/qmod/builtins/functions/standard_gates.py +46 -27
- classiq/qmod/builtins/operations.py +165 -79
- classiq/qmod/builtins/structs.py +24 -91
- classiq/qmod/cfunc.py +3 -2
- classiq/qmod/classical_function.py +2 -1
- classiq/qmod/cparam.py +2 -8
- classiq/qmod/create_model_function.py +7 -7
- classiq/qmod/declaration_inferrer.py +33 -30
- classiq/qmod/expression_query.py +7 -4
- classiq/qmod/model_state_container.py +2 -2
- classiq/qmod/native/pretty_printer.py +25 -14
- classiq/qmod/pretty_print/expression_to_python.py +5 -3
- classiq/qmod/pretty_print/pretty_printer.py +39 -17
- classiq/qmod/python_classical_type.py +40 -13
- classiq/qmod/qfunc.py +124 -19
- classiq/qmod/qmod_constant.py +2 -2
- classiq/qmod/qmod_parameter.py +5 -2
- classiq/qmod/qmod_variable.py +48 -47
- classiq/qmod/quantum_callable.py +18 -13
- classiq/qmod/quantum_expandable.py +31 -26
- classiq/qmod/quantum_function.py +84 -36
- classiq/qmod/semantics/annotation/call_annotation.py +5 -5
- classiq/qmod/semantics/error_manager.py +23 -15
- classiq/qmod/semantics/lambdas.py +1 -2
- classiq/qmod/semantics/validation/types_validation.py +1 -2
- classiq/qmod/symbolic.py +2 -4
- classiq/qmod/utilities.py +13 -20
- classiq/qmod/write_qmod.py +3 -4
- classiq/quantum_program.py +1 -3
- classiq/synthesis.py +11 -7
- {classiq-0.93.0.dist-info → classiq-0.100.0.dist-info}/METADATA +2 -3
- {classiq-0.93.0.dist-info → classiq-0.100.0.dist-info}/RECORD +274 -300
- {classiq-0.93.0.dist-info → classiq-0.100.0.dist-info}/WHEEL +1 -1
- classiq/applications/chemistry/ansatz_parameters.py +0 -29
- classiq/applications/chemistry/chemistry_execution_parameters.py +0 -16
- classiq/applications/chemistry/chemistry_model_constructor.py +0 -532
- classiq/applications/chemistry/ground_state_problem.py +0 -42
- classiq/applications/qsvm/__init__.py +0 -8
- classiq/applications/qsvm/qsvm.py +0 -11
- classiq/evaluators/qmod_expression_visitors/qmod_expression_bwc.py +0 -129
- classiq/execution/iqcc.py +0 -128
- classiq/interface/applications/qsvm.py +0 -117
- classiq/interface/chemistry/elements.py +0 -120
- classiq/interface/chemistry/fermionic_operator.py +0 -208
- classiq/interface/chemistry/ground_state_problem.py +0 -132
- classiq/interface/chemistry/ground_state_result.py +0 -8
- classiq/interface/chemistry/molecule.py +0 -71
- classiq/interface/execution/iqcc.py +0 -44
- classiq/interface/generator/application_apis/chemistry_declarations.py +0 -69
- classiq/interface/generator/application_apis/entangler_declarations.py +0 -29
- classiq/interface/generator/application_apis/qsvm_declarations.py +0 -6
- classiq/interface/generator/chemistry_function_params.py +0 -50
- classiq/interface/generator/entangler_params.py +0 -72
- classiq/interface/generator/entanglers.py +0 -14
- classiq/interface/generator/hamiltonian_evolution/qdrift.py +0 -27
- classiq/interface/generator/hartree_fock.py +0 -26
- classiq/interface/generator/hva.py +0 -22
- classiq/interface/generator/linear_pauli_rotations.py +0 -92
- classiq/interface/generator/qft.py +0 -37
- classiq/interface/generator/qsvm.py +0 -96
- classiq/interface/generator/state_preparation/__init__.py +0 -14
- classiq/interface/generator/state_preparation/bell_state_preparation.py +0 -27
- classiq/interface/generator/state_preparation/computational_basis_state_preparation.py +0 -28
- classiq/interface/generator/state_preparation/distributions.py +0 -53
- classiq/interface/generator/state_preparation/exponential_state_preparation.py +0 -14
- classiq/interface/generator/state_preparation/ghz_state_preparation.py +0 -14
- classiq/interface/generator/state_preparation/metrics.py +0 -41
- classiq/interface/generator/state_preparation/state_preparation.py +0 -113
- classiq/interface/generator/state_preparation/state_preparation_abc.py +0 -24
- classiq/interface/generator/state_preparation/uniform_distibution_state_preparation.py +0 -13
- classiq/interface/generator/state_preparation/w_state_preparation.py +0 -13
- classiq/interface/generator/ucc.py +0 -74
- classiq/interface/helpers/backward_compatibility.py +0 -9
- classiq/model_expansions/transformers/type_modifier_inference.py +0 -392
- classiq/open_library/functions/lookup_table.py +0 -58
- classiq/qmod/builtins/functions/chemistry.py +0 -123
- classiq/qmod/builtins/functions/qsvm.py +0 -24
- {classiq-0.93.0.dist-info → classiq-0.100.0.dist-info}/licenses/LICENSE.txt +0 -0
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
from typing import Literal
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
|
|
5
|
+
from classiq.qmod.builtins.functions.allocation import free
|
|
6
|
+
from classiq.qmod.builtins.functions.standard_gates import CX, SWAP, X
|
|
7
|
+
from classiq.qmod.builtins.operations import allocate, bind, control, invert, repeat
|
|
8
|
+
from classiq.qmod.qfunc import qperm
|
|
9
|
+
from classiq.qmod.qmod_variable import Input, Output, QArray, QBit, QNum
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def get_rewire_list(qvars: list[QBit]) -> list[QBit]:
|
|
13
|
+
rewire_list = qvars[int(np.log2(len(qvars))) :]
|
|
14
|
+
for i, qvar in enumerate(qvars[: int(np.log2(len(qvars)))]):
|
|
15
|
+
rewire_list.insert(2 ** (i + 1) - 1, qvar)
|
|
16
|
+
return rewire_list
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@qperm
|
|
20
|
+
def inplace_binary_to_one_hot(qvar: QArray) -> None:
|
|
21
|
+
"""
|
|
22
|
+
Inplace conversion of binary encoded value to one-hot encoding.
|
|
23
|
+
The implementation is based on https://quantumcomputing.stackexchange.com/questions/5526/garbage-free-reversible-binary-to-unary-decoder-construction.
|
|
24
|
+
The input is assumed to be of size 2^n, where n is the number of bits in the binary representation.
|
|
25
|
+
For example, the state |01000>=|2> will be converted to |00100> (one-hot for 2).
|
|
26
|
+
|
|
27
|
+
Args:
|
|
28
|
+
qvar: binary input array padded with 0's to be converted to one-hot encoding.
|
|
29
|
+
"""
|
|
30
|
+
temp_qvars = [QBit(f"x{i}") for i in range(qvar.len)]
|
|
31
|
+
bind(qvar, temp_qvars) # type: ignore[arg-type]
|
|
32
|
+
bind(get_rewire_list(temp_qvars), qvar) # type: ignore[arg-type]
|
|
33
|
+
|
|
34
|
+
# logic
|
|
35
|
+
X(qvar[0])
|
|
36
|
+
for i in range(int(np.log2(qvar.len))):
|
|
37
|
+
index = 2 ** (i + 1) - 1
|
|
38
|
+
for j in range(2**i - 1):
|
|
39
|
+
control(qvar[index], lambda i=i, j=j: SWAP(qvar[j], qvar[j + 2**i])) # type: ignore[misc]
|
|
40
|
+
for j in range(2**i - 1):
|
|
41
|
+
CX(qvar[j + 2**i], qvar[index])
|
|
42
|
+
|
|
43
|
+
CX(qvar[index], qvar[index - 2**i])
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
@qperm
|
|
47
|
+
def inplace_one_hot_to_unary(qvar: QArray) -> None:
|
|
48
|
+
"""
|
|
49
|
+
Inplace conversion of one-hot encoded value to unary encoding.
|
|
50
|
+
The input is assumed to be of size n, where n is the number of bits in the one-hot representation.
|
|
51
|
+
The remaining unary representation will at the higher n-1 bits, where the lsb is cleared to 0.
|
|
52
|
+
For example, the state |0010> (one-hot for 2) will be converted to |0>|110> (unary for 2).
|
|
53
|
+
|
|
54
|
+
Args:
|
|
55
|
+
qvar: one-hot input array to be converted to unary encoding.
|
|
56
|
+
"""
|
|
57
|
+
# fill with 1s after the leading 1 bit
|
|
58
|
+
repeat(qvar.len - 1, lambda i: CX(qvar[qvar.len - i - 1], qvar[qvar.len - i - 2]))
|
|
59
|
+
# clear the 0 bit, to be excluded from the unary encoding
|
|
60
|
+
X(qvar[0])
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
@qperm
|
|
64
|
+
def one_hot_to_unary(one_hot: Input[QArray], unary: Output[QArray]) -> None:
|
|
65
|
+
"""
|
|
66
|
+
Conversion of one-hot encoded value to unary encoding. The output `unary` variable
|
|
67
|
+
is smaller in 1 qubit than the input `one_hot` variable.
|
|
68
|
+
For example, the state |0010> (one-hot for 2) will be converted to |110> (unary for 2).
|
|
69
|
+
|
|
70
|
+
Args:
|
|
71
|
+
one_hot: one-hot input array to be converted to unary encoding.
|
|
72
|
+
unary: unary output array.
|
|
73
|
+
"""
|
|
74
|
+
inplace_one_hot_to_unary(one_hot)
|
|
75
|
+
lsb: QBit = QBit()
|
|
76
|
+
bind(one_hot, [lsb, unary])
|
|
77
|
+
free(lsb)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
@qperm
|
|
81
|
+
def one_hot_to_binary(
|
|
82
|
+
one_hot: Input[QArray],
|
|
83
|
+
binary: Output[QNum[Literal["ceiling(log(one_hot.len, 2))"]]],
|
|
84
|
+
) -> None:
|
|
85
|
+
"""
|
|
86
|
+
Conversion of one-hot encoded value to binary encoding. The output `binary` variable
|
|
87
|
+
is of size log2(one_hot.size) rounded up.
|
|
88
|
+
For example, the state |0010> (one-hot for 2) will be converted to |01>=|2>.
|
|
89
|
+
|
|
90
|
+
Args:
|
|
91
|
+
one_hot: one-hot input array to be converted to binary encoding.
|
|
92
|
+
binary: binary output variable.
|
|
93
|
+
"""
|
|
94
|
+
extension: QArray = QArray()
|
|
95
|
+
invert(lambda: inplace_binary_to_one_hot(one_hot))
|
|
96
|
+
bind(one_hot, [binary, extension])
|
|
97
|
+
free(extension)
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
@qperm
|
|
101
|
+
def unary_to_binary(unary: Input[QArray], binary: Output[QNum]) -> None:
|
|
102
|
+
"""
|
|
103
|
+
Conversion of unary encoded value to binary encoding. The output `binary` variable
|
|
104
|
+
is of size log2(unary.size + 1) rounded up.
|
|
105
|
+
For example, the state |110> (unary for 2) will be converted to |01>=|2>.
|
|
106
|
+
|
|
107
|
+
Args:
|
|
108
|
+
unary: unary input array to be converted to binary encoding.
|
|
109
|
+
binary: binary output variable.
|
|
110
|
+
"""
|
|
111
|
+
one_hot: QArray = QArray()
|
|
112
|
+
unary_to_one_hot(unary, one_hot)
|
|
113
|
+
one_hot_to_binary(one_hot, binary)
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
@qperm
|
|
117
|
+
def unary_to_one_hot(unary: Input[QArray], one_hot: Output[QArray]) -> None:
|
|
118
|
+
"""
|
|
119
|
+
Conversion of unary encoded value to one-hot encoding. The output `one_hot` variable
|
|
120
|
+
is larger in 1 qubit than the input `unary` variable.
|
|
121
|
+
For example, the state |110> (unary for 2) will be converted to |0010> (one-hot for 2).
|
|
122
|
+
|
|
123
|
+
Args:
|
|
124
|
+
unary: unary input array to be converted to one-hot encoding.
|
|
125
|
+
one_hot: one-hot output array.
|
|
126
|
+
"""
|
|
127
|
+
lsb: QBit = QBit()
|
|
128
|
+
allocate(lsb)
|
|
129
|
+
bind([lsb, unary], one_hot)
|
|
130
|
+
invert(lambda: inplace_one_hot_to_unary(one_hot))
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
@qperm
|
|
134
|
+
def binary_to_one_hot(binary: Input[QNum], one_hot: Output[QArray]) -> None:
|
|
135
|
+
"""
|
|
136
|
+
Conversion of binary encoded value to one-hot encoding. The output `one_hot` variable
|
|
137
|
+
is of size 2^n, where n is the number of bits in the binary representation.
|
|
138
|
+
For example, the state |01>=|2> will be converted to |0010> (one-hot for 2).
|
|
139
|
+
|
|
140
|
+
Args:
|
|
141
|
+
binary: binary input variable to be converted to one-hot encoding.
|
|
142
|
+
one_hot: one-hot output array.
|
|
143
|
+
"""
|
|
144
|
+
extension: QArray = QArray()
|
|
145
|
+
allocate(2**binary.size - binary.size, extension)
|
|
146
|
+
bind([binary, extension], one_hot)
|
|
147
|
+
|
|
148
|
+
inplace_binary_to_one_hot(one_hot)
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
@qperm
|
|
152
|
+
def binary_to_unary(binary: Input[QNum], unary: Output[QArray]) -> None:
|
|
153
|
+
"""
|
|
154
|
+
Conversion of binary encoded value to unary encoding. The output `unary` variable
|
|
155
|
+
is of size 2^n - 1, where n is the number of bits in the binary representation.
|
|
156
|
+
For example, the state |01>=|2> will be converted to |110> (unary for 2).
|
|
157
|
+
|
|
158
|
+
Args:
|
|
159
|
+
binary: binary input variable to be converted to unary encoding.
|
|
160
|
+
unary: unary output array.
|
|
161
|
+
"""
|
|
162
|
+
one_hot: QArray = QArray()
|
|
163
|
+
binary_to_one_hot(binary, one_hot)
|
|
164
|
+
one_hot_to_unary(one_hot, unary)
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
@qperm
|
|
168
|
+
def pad_zeros(total_size: int, qvar: Input[QArray], padded: Output[QArray]) -> None:
|
|
169
|
+
"""
|
|
170
|
+
Pad the input qvar with additional qubits at the end to reach the total_size.
|
|
171
|
+
|
|
172
|
+
Args:
|
|
173
|
+
total_size: The desired total size after padding.
|
|
174
|
+
qvar: The input quantum array to be padded.
|
|
175
|
+
padded: The output quantum array after padding.
|
|
176
|
+
"""
|
|
177
|
+
extension: QArray = QArray()
|
|
178
|
+
allocate(total_size - qvar.len, extension)
|
|
179
|
+
bind([qvar, extension], padded)
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
# TODO: when the functions can have default arguments, add `pad` function with direction and value
|
|
@@ -8,23 +8,21 @@ from classiq.qmod.builtins.operations import (
|
|
|
8
8
|
power,
|
|
9
9
|
within_apply,
|
|
10
10
|
)
|
|
11
|
-
from classiq.qmod.qfunc import qfunc
|
|
11
|
+
from classiq.qmod.qfunc import qfunc, qperm
|
|
12
12
|
from classiq.qmod.qmod_parameter import CInt
|
|
13
|
-
from classiq.qmod.qmod_variable import Const,
|
|
14
|
-
from classiq.qmod.quantum_callable import QCallable
|
|
13
|
+
from classiq.qmod.qmod_variable import Const, QArray, QBit, QNum
|
|
14
|
+
from classiq.qmod.quantum_callable import QCallable, QPerm
|
|
15
15
|
from classiq.qmod.symbolic import pi
|
|
16
16
|
|
|
17
17
|
|
|
18
|
-
@
|
|
19
|
-
def _cond_phase_flip(
|
|
20
|
-
predicate: QCallable[Permutable[QBit]], target: Const[QBit]
|
|
21
|
-
) -> None:
|
|
18
|
+
@qperm(disable_perm_check=True, disable_const_checks=["target"])
|
|
19
|
+
def _cond_phase_flip(predicate: QPerm[QBit], target: Const[QBit]) -> None:
|
|
22
20
|
within_apply(lambda: H(target), lambda: predicate(target))
|
|
23
21
|
|
|
24
22
|
|
|
25
|
-
@
|
|
23
|
+
@qperm
|
|
26
24
|
def phase_oracle(
|
|
27
|
-
predicate:
|
|
25
|
+
predicate: QPerm[Const[QArray[QBit]], QBit],
|
|
28
26
|
target: Const[QArray[QBit]],
|
|
29
27
|
) -> None:
|
|
30
28
|
"""
|
|
@@ -55,7 +53,7 @@ def phase_oracle(
|
|
|
55
53
|
)
|
|
56
54
|
|
|
57
55
|
|
|
58
|
-
@
|
|
56
|
+
@qperm(disable_perm_check=True, disable_const_checks=["packed_vars"])
|
|
59
57
|
def reflect_about_zero(packed_vars: Const[QArray[QBit]]) -> None:
|
|
60
58
|
"""
|
|
61
59
|
[Qmod Classiq-library function]
|
|
@@ -9,6 +9,7 @@ from classiq.open_library.functions.utility_functions import switch
|
|
|
9
9
|
from classiq.qmod.builtins.functions import IDENTITY, X, Y, Z, inplace_prepare_state
|
|
10
10
|
from classiq.qmod.builtins.operations import (
|
|
11
11
|
control,
|
|
12
|
+
if_,
|
|
12
13
|
repeat,
|
|
13
14
|
within_apply,
|
|
14
15
|
)
|
|
@@ -16,7 +17,7 @@ from classiq.qmod.builtins.structs import IndexedPauli, SparsePauliOp
|
|
|
16
17
|
from classiq.qmod.cparam import CArray
|
|
17
18
|
from classiq.qmod.qfunc import qfunc
|
|
18
19
|
from classiq.qmod.qmod_variable import QArray, QBit, QNum
|
|
19
|
-
from classiq.qmod.quantum_callable import QCallableList
|
|
20
|
+
from classiq.qmod.quantum_callable import QCallable, QCallableList
|
|
20
21
|
|
|
21
22
|
|
|
22
23
|
@qfunc
|
|
@@ -36,27 +37,23 @@ def apply_pauli_term(pauli_string: CArray[IndexedPauli], x: QArray[QBit]) -> Non
|
|
|
36
37
|
|
|
37
38
|
|
|
38
39
|
@qfunc
|
|
39
|
-
def
|
|
40
|
+
def prepare_select(
|
|
40
41
|
coefficients: list[float],
|
|
41
|
-
|
|
42
|
+
select: QCallable[QNum],
|
|
42
43
|
block: QNum[Literal["max(ceiling(log(coefficients.len, 2)), 1)"]],
|
|
43
44
|
) -> None:
|
|
44
45
|
"""
|
|
45
46
|
[Qmod Classiq-library function]
|
|
46
47
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
The
|
|
51
|
-
|
|
52
|
-
$$\\sum_j \\alpha_j U_j$$
|
|
53
|
-
|
|
54
|
-
where $U_j$ is a unitary operation applied to `data`.
|
|
48
|
+
Applies the 'Prepare-Select' scheme used for Linear Combination of Unitaries (LCU).
|
|
49
|
+
Compared to the `lcu` function, here the Select operator should be provided directly, allowing to take advantage of some structure for
|
|
50
|
+
the unitaries of the LCU.
|
|
51
|
+
The select operator is defined by: $\\mathrm{SELECT} = \\sum_{j=0}^{m-1} |j\rangle\\!\\langle j|_{block} \\otimes U_j$.
|
|
55
52
|
|
|
56
53
|
Args:
|
|
57
54
|
coefficients: L1-normalized array of $\\{ \\alpha_j \\}$ of the LCU coefficients.
|
|
58
|
-
|
|
59
|
-
block: Quantum variable that holds the
|
|
55
|
+
select: A quantum callable to be applied between the state preparation and its inverse. Its input is the `block` variable, labeling the index of the unitaries in the LCU.
|
|
56
|
+
block: A Quantum variable that holds the index used as input for the 'select' operator.
|
|
60
57
|
"""
|
|
61
58
|
coefficients = coefficients + [0] * (
|
|
62
59
|
2**block.size - len(coefficients) # type:ignore[operator]
|
|
@@ -68,16 +65,48 @@ def lcu(
|
|
|
68
65
|
within_apply(
|
|
69
66
|
lambda: inplace_prepare_state(magnitudes, 0, block),
|
|
70
67
|
lambda: [
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
68
|
+
select(block),
|
|
69
|
+
if_(
|
|
70
|
+
not np.allclose(np.array(phases) % (2 * np.pi), 0),
|
|
71
|
+
lambda: apply_phase_table(phases, block),
|
|
74
72
|
),
|
|
75
|
-
# TODO: replace to sparse constant phase
|
|
76
|
-
apply_phase_table(phases, block),
|
|
77
73
|
],
|
|
78
74
|
)
|
|
79
75
|
|
|
80
76
|
|
|
77
|
+
@qfunc
|
|
78
|
+
def lcu(
|
|
79
|
+
coefficients: list[float],
|
|
80
|
+
unitaries: QCallableList,
|
|
81
|
+
block: QNum[Literal["max(ceiling(log(coefficients.len, 2)), 1)"]],
|
|
82
|
+
) -> None:
|
|
83
|
+
"""
|
|
84
|
+
[Qmod Classiq-library function]
|
|
85
|
+
|
|
86
|
+
Implements a general linear combination of unitaries (LCU) procedure. The algorithm prepares a superposition
|
|
87
|
+
over the `unitaries` according to the given `coefficients`, and then conditionally applies each unitary controlled by the `block`.
|
|
88
|
+
|
|
89
|
+
The operation is of the form:
|
|
90
|
+
|
|
91
|
+
$$\\sum_j \\alpha_j U_j$$
|
|
92
|
+
|
|
93
|
+
where $U_j$ is a unitary operation applied to `data`.
|
|
94
|
+
|
|
95
|
+
Args:
|
|
96
|
+
coefficients: L1-normalized array of $\\{ \\alpha_j \\}$ of the LCU coefficients.
|
|
97
|
+
unitaries: A list of quantum callable functions to be applied conditionally.
|
|
98
|
+
block: Quantum variable that holds the superposition index used for conditional application of each unitary.
|
|
99
|
+
"""
|
|
100
|
+
prepare_select(
|
|
101
|
+
coefficients,
|
|
102
|
+
lambda _block: repeat(
|
|
103
|
+
count=unitaries.len,
|
|
104
|
+
iteration=lambda i: control(_block == i, lambda: unitaries[i]()),
|
|
105
|
+
),
|
|
106
|
+
block,
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
|
|
81
110
|
@qfunc
|
|
82
111
|
def lcu_pauli(
|
|
83
112
|
operator: SparsePauliOp,
|
|
@@ -8,11 +8,12 @@ from classiq.qmod.builtins.operations import (
|
|
|
8
8
|
control,
|
|
9
9
|
invert,
|
|
10
10
|
repeat,
|
|
11
|
+
skip_control,
|
|
11
12
|
within_apply,
|
|
12
13
|
)
|
|
13
14
|
from classiq.qmod.cparam import CInt
|
|
14
|
-
from classiq.qmod.qfunc import qfunc
|
|
15
|
-
from classiq.qmod.qmod_variable import Const,
|
|
15
|
+
from classiq.qmod.qfunc import qfunc, qperm
|
|
16
|
+
from classiq.qmod.qmod_variable import Const, QArray, QBit
|
|
16
17
|
from classiq.qmod.symbolic import min, mod_inverse
|
|
17
18
|
|
|
18
19
|
|
|
@@ -51,9 +52,9 @@ def qft_space_add_const(value: CInt, phi_b: QArray[QBit]) -> None:
|
|
|
51
52
|
)
|
|
52
53
|
|
|
53
54
|
|
|
54
|
-
@
|
|
55
|
+
@qperm(disable_perm_check=True)
|
|
55
56
|
def cc_modular_add(
|
|
56
|
-
n: CInt, a: CInt, phi_b:
|
|
57
|
+
n: CInt, a: CInt, phi_b: QArray[QBit], c1: Const[QBit], c2: Const[QBit]
|
|
57
58
|
) -> None:
|
|
58
59
|
"""
|
|
59
60
|
[Qmod Classiq-library function]
|
|
@@ -91,11 +92,11 @@ def cc_modular_add(
|
|
|
91
92
|
free(aux)
|
|
92
93
|
|
|
93
94
|
|
|
94
|
-
@
|
|
95
|
+
@qperm(disable_perm_check=True)
|
|
95
96
|
def c_modular_multiply(
|
|
96
97
|
n: CInt,
|
|
97
98
|
a: CInt,
|
|
98
|
-
b:
|
|
99
|
+
b: QArray[QBit],
|
|
99
100
|
x: Const[QArray[QBit]],
|
|
100
101
|
ctrl: Const[QBit],
|
|
101
102
|
) -> None:
|
|
@@ -123,8 +124,8 @@ def c_modular_multiply(
|
|
|
123
124
|
)
|
|
124
125
|
|
|
125
126
|
|
|
126
|
-
@
|
|
127
|
-
def multiswap(x:
|
|
127
|
+
@qperm
|
|
128
|
+
def multiswap(x: QArray[QBit], y: QArray[QBit]) -> None:
|
|
128
129
|
"""
|
|
129
130
|
[Qmod Classiq-library function]
|
|
130
131
|
|
|
@@ -164,6 +165,90 @@ def inplace_c_modular_multiply(n: CInt, a: CInt, x: QArray[QBit], ctrl: QBit) ->
|
|
|
164
165
|
free(b)
|
|
165
166
|
|
|
166
167
|
|
|
168
|
+
@qperm(disable_perm_check=True)
|
|
169
|
+
def modular_add_qft_space(n: CInt, a: CInt, phi_b: QArray[QBit]) -> None:
|
|
170
|
+
"""
|
|
171
|
+
[Qmod Classiq-library function]
|
|
172
|
+
|
|
173
|
+
Adds a constant `a` to a quantum number `phi_b` modulo the constant `n`.
|
|
174
|
+
The quantum number `phi_b` is assumed to be in the QFT space.
|
|
175
|
+
|
|
176
|
+
Args:
|
|
177
|
+
n: The modulo number.
|
|
178
|
+
a: The constant to add to the quantum number.
|
|
179
|
+
phi_b: The quantum number to which the constant is added.
|
|
180
|
+
|
|
181
|
+
"""
|
|
182
|
+
aux = QBit()
|
|
183
|
+
|
|
184
|
+
allocate(aux)
|
|
185
|
+
qft_space_add_const(a, phi_b),
|
|
186
|
+
skip_control(
|
|
187
|
+
lambda: (
|
|
188
|
+
invert(lambda: qft_space_add_const(n, phi_b)),
|
|
189
|
+
_check_msb(1, phi_b, aux),
|
|
190
|
+
control(aux, lambda: qft_space_add_const(n, phi_b)),
|
|
191
|
+
)
|
|
192
|
+
)
|
|
193
|
+
invert(lambda: qft_space_add_const(a, phi_b))
|
|
194
|
+
skip_control(lambda: _check_msb(0, phi_b, aux))
|
|
195
|
+
qft_space_add_const(a, phi_b)
|
|
196
|
+
free(aux)
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
@qperm(disable_perm_check=True)
|
|
200
|
+
def modular_multiply(
|
|
201
|
+
n: CInt,
|
|
202
|
+
a: CInt,
|
|
203
|
+
b: QArray[QBit],
|
|
204
|
+
x: Const[QArray[QBit]],
|
|
205
|
+
) -> None:
|
|
206
|
+
"""
|
|
207
|
+
[Qmod Classiq-library function]
|
|
208
|
+
|
|
209
|
+
Performs out-of-place multiplication of a quantum number `x` by a classical number `a` modulo classical number `n`,
|
|
210
|
+
and adds the result to a quantum array `b` (Applies $b += xa \\mod n$).
|
|
211
|
+
|
|
212
|
+
Args:
|
|
213
|
+
n: The modulo number. Should be non-negative.
|
|
214
|
+
a: The classical factor. Should be non-negative.
|
|
215
|
+
b: The quantum number added to the multiplication result. Stores the result of the multiplication.
|
|
216
|
+
x: The quantum factor.
|
|
217
|
+
"""
|
|
218
|
+
within_apply(
|
|
219
|
+
lambda: qft(b),
|
|
220
|
+
lambda: repeat(
|
|
221
|
+
count=x.len,
|
|
222
|
+
iteration=lambda index: control(
|
|
223
|
+
x[index], lambda: modular_add_qft_space(n, (a * (2**index)) % n, b)
|
|
224
|
+
),
|
|
225
|
+
),
|
|
226
|
+
)
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
@qfunc
|
|
230
|
+
def inplace_modular_multiply(n: CInt, a: CInt, x: QArray[QBit]) -> None:
|
|
231
|
+
"""
|
|
232
|
+
[Qmod Classiq-library function]
|
|
233
|
+
|
|
234
|
+
Performs multiplication of a quantum number `x` by a classical number `a` modulo classical number `n`
|
|
235
|
+
(Applies $x=xa \\mod n$).
|
|
236
|
+
|
|
237
|
+
Args:
|
|
238
|
+
n: The modulo number. Should be non-negative.
|
|
239
|
+
a: The classical factor. Should be non-negative.
|
|
240
|
+
x: The quantum factor.
|
|
241
|
+
|
|
242
|
+
Comment: It is assumed that `a` has an inverse modulo `n`
|
|
243
|
+
"""
|
|
244
|
+
b: QArray[QBit] = QArray(length=x.len + 1)
|
|
245
|
+
allocate(b)
|
|
246
|
+
modular_multiply(n, a, b, x)
|
|
247
|
+
multiswap(x, b)
|
|
248
|
+
invert(lambda: modular_multiply(n, mod_inverse(a, n), b, x))
|
|
249
|
+
free(b)
|
|
250
|
+
|
|
251
|
+
|
|
167
252
|
@qfunc
|
|
168
253
|
def modular_exp(n: CInt, a: CInt, x: QArray[QBit], power: QArray[QBit]) -> None:
|
|
169
254
|
"""
|