classiq 0.93.0__py3-none-any.whl → 0.99.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 +25 -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/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 +12 -4
- classiq/interface/generator/types/builtin_enum_declarations.py +0 -145
- classiq/interface/generator/types/compilation_metadata.py +12 -1
- 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 +1 -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/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 +30 -27
- 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 -37
- 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 +28 -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/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 +130 -27
- 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 +47 -46
- 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 +12 -14
- 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.99.0.dist-info}/METADATA +2 -3
- {classiq-0.93.0.dist-info → classiq-0.99.0.dist-info}/RECORD +271 -299
- {classiq-0.93.0.dist-info → classiq-0.99.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.99.0.dist-info}/licenses/LICENSE.txt +0 -0
|
@@ -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
|
"""
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
from
|
|
1
|
+
from typing import Literal
|
|
2
|
+
|
|
3
|
+
from classiq.qmod.builtins.functions.standard_gates import RZ, H, U, X, Z
|
|
2
4
|
from classiq.qmod.builtins.operations import control, if_, invert, repeat, within_apply
|
|
3
5
|
from classiq.qmod.qfunc import qfunc
|
|
4
6
|
from classiq.qmod.qmod_parameter import CArray, CInt, CReal
|
|
5
|
-
from classiq.qmod.qmod_variable import
|
|
7
|
+
from classiq.qmod.qmod_variable import QBit
|
|
6
8
|
from classiq.qmod.quantum_callable import QCallable
|
|
7
9
|
from classiq.qmod.symbolic import floor, min as qmin
|
|
8
10
|
|
|
@@ -11,10 +13,9 @@ from classiq.qmod.symbolic import floor, min as qmin
|
|
|
11
13
|
def qsvt_step(
|
|
12
14
|
phase1: CReal,
|
|
13
15
|
phase2: CReal,
|
|
14
|
-
proj_cnot_1: QCallable[
|
|
15
|
-
proj_cnot_2: QCallable[
|
|
16
|
-
u: QCallable
|
|
17
|
-
qvar: QArray[QBit],
|
|
16
|
+
proj_cnot_1: QCallable[QBit],
|
|
17
|
+
proj_cnot_2: QCallable[QBit],
|
|
18
|
+
u: QCallable,
|
|
18
19
|
aux: QBit,
|
|
19
20
|
) -> None:
|
|
20
21
|
"""
|
|
@@ -29,25 +30,23 @@ def qsvt_step(
|
|
|
29
30
|
Args:
|
|
30
31
|
phase1: 1st rotation phase.
|
|
31
32
|
phase2: 2nd rotation phase.
|
|
32
|
-
proj_cnot_1: Projector-controlled-not unitary that locates the encoded matrix columns within U. Accepts a
|
|
33
|
-
proj_cnot_2: Projector-controlled-not unitary that locates the encoded matrix rows within U. Accepts a
|
|
34
|
-
u: A block
|
|
35
|
-
qvar: The quantum variable to which U is applied, which resides in the entire block encoding space.
|
|
33
|
+
proj_cnot_1: Projector-controlled-not unitary that locates the encoded matrix columns within U. Accepts a qubit that should be set to |1> when the state is in the block.
|
|
34
|
+
proj_cnot_2: Projector-controlled-not unitary that locates the encoded matrix rows within U. Accepts a qubit that should be set to |1> when the state is in the block.
|
|
35
|
+
u: A block encoding unitary matrix.
|
|
36
36
|
aux: A zero auxilliary qubit, used for the projector-controlled-phase rotations. Given as an inout so that qsvt can be used as a building-block in a larger algorithm.
|
|
37
37
|
"""
|
|
38
|
-
u(
|
|
39
|
-
projector_controlled_phase(phase1, proj_cnot_2,
|
|
40
|
-
invert(lambda: u(
|
|
41
|
-
projector_controlled_phase(phase2, proj_cnot_1,
|
|
38
|
+
u()
|
|
39
|
+
projector_controlled_phase(phase1, proj_cnot_2, aux)
|
|
40
|
+
invert(lambda: u())
|
|
41
|
+
projector_controlled_phase(phase2, proj_cnot_1, aux)
|
|
42
42
|
|
|
43
43
|
|
|
44
44
|
@qfunc
|
|
45
45
|
def qsvt(
|
|
46
46
|
phase_seq: CArray[CReal],
|
|
47
|
-
proj_cnot_1: QCallable[
|
|
48
|
-
proj_cnot_2: QCallable[
|
|
49
|
-
u: QCallable
|
|
50
|
-
qvar: QArray[QBit],
|
|
47
|
+
proj_cnot_1: QCallable[QBit],
|
|
48
|
+
proj_cnot_2: QCallable[QBit],
|
|
49
|
+
u: QCallable,
|
|
51
50
|
aux: QBit,
|
|
52
51
|
) -> None:
|
|
53
52
|
"""
|
|
@@ -72,15 +71,14 @@ def qsvt(
|
|
|
72
71
|
|
|
73
72
|
Args:
|
|
74
73
|
phase_seq: A sequence of phase angles of length d+1.
|
|
75
|
-
proj_cnot_1: Projector-controlled-not unitary that locates the encoded matrix columns within U. Accepts a
|
|
76
|
-
proj_cnot_2: Projector-controlled-not unitary that locates the encoded matrix rows within U. Accepts a
|
|
77
|
-
u: A block
|
|
78
|
-
qvar: The quantum variable to which U is applied, which resides in the entire block encoding space.
|
|
74
|
+
proj_cnot_1: Projector-controlled-not unitary that locates the encoded matrix columns within U. Accepts a qubit that should be set to |1> when the state is in the block.
|
|
75
|
+
proj_cnot_2: Projector-controlled-not unitary that locates the encoded matrix rows within U. Accepts a qubit that should be set to |1> when the state is in the block.
|
|
76
|
+
u: A block encoding unitary matrix.
|
|
79
77
|
aux: A zero auxilliary qubit, used for the projector-controlled-phase rotations. Given as an inout so that qsvt can be used as a building-block in a larger algorithm.
|
|
80
78
|
"""
|
|
81
79
|
H(aux)
|
|
82
80
|
|
|
83
|
-
projector_controlled_phase(phase_seq[0], proj_cnot_1,
|
|
81
|
+
projector_controlled_phase(phase_seq[0], proj_cnot_1, aux)
|
|
84
82
|
repeat(
|
|
85
83
|
count=floor((phase_seq.len - 1) / 2),
|
|
86
84
|
iteration=lambda index: qsvt_step(
|
|
@@ -89,20 +87,18 @@ def qsvt(
|
|
|
89
87
|
proj_cnot_1,
|
|
90
88
|
proj_cnot_2,
|
|
91
89
|
u,
|
|
92
|
-
qvar,
|
|
93
90
|
aux,
|
|
94
91
|
),
|
|
95
92
|
)
|
|
96
93
|
|
|
97
94
|
if_(
|
|
98
95
|
condition=phase_seq.len % 2 == 1,
|
|
99
|
-
then=lambda:
|
|
96
|
+
then=lambda: None,
|
|
100
97
|
else_=lambda: (
|
|
101
|
-
u(
|
|
98
|
+
u(),
|
|
102
99
|
projector_controlled_phase(
|
|
103
100
|
phase_seq[phase_seq.len - 1],
|
|
104
101
|
proj_cnot_2,
|
|
105
|
-
qvar,
|
|
106
102
|
aux,
|
|
107
103
|
),
|
|
108
104
|
),
|
|
@@ -114,8 +110,7 @@ def qsvt(
|
|
|
114
110
|
@qfunc
|
|
115
111
|
def projector_controlled_phase(
|
|
116
112
|
phase: CReal,
|
|
117
|
-
proj_cnot: QCallable[
|
|
118
|
-
qvar: QArray[QBit],
|
|
113
|
+
proj_cnot: QCallable[QBit],
|
|
119
114
|
aux: QBit,
|
|
120
115
|
) -> None:
|
|
121
116
|
"""
|
|
@@ -130,18 +125,16 @@ def projector_controlled_phase(
|
|
|
130
125
|
Args:
|
|
131
126
|
phase: A rotation phase.
|
|
132
127
|
proj_cnot: Projector-controlled-not unitary that sets an auxilliary qubit to |1> when the state is in the projection.
|
|
133
|
-
|
|
134
|
-
aux: A zero auxilliary qubit, used for the projector-controlled-phase rotation. Given as an inout so that qsvt can be used as a building-block in a larger algorithm.
|
|
128
|
+
aux: A zero auxilliary qubit, used for the projector-controlled-phase rotation.
|
|
135
129
|
"""
|
|
136
|
-
within_apply(lambda: proj_cnot(
|
|
130
|
+
within_apply(lambda: proj_cnot(aux), lambda: RZ(phase, aux))
|
|
137
131
|
|
|
138
132
|
|
|
139
133
|
@qfunc
|
|
140
134
|
def qsvt_inversion(
|
|
141
135
|
phase_seq: CArray[CReal],
|
|
142
|
-
block_encoding_cnot: QCallable[
|
|
143
|
-
u: QCallable
|
|
144
|
-
qvar: QArray[QBit],
|
|
136
|
+
block_encoding_cnot: QCallable[QBit],
|
|
137
|
+
u: QCallable,
|
|
145
138
|
aux: QBit,
|
|
146
139
|
) -> None:
|
|
147
140
|
"""
|
|
@@ -152,17 +145,15 @@ def qsvt_inversion(
|
|
|
152
145
|
|
|
153
146
|
Args:
|
|
154
147
|
phase_seq: A sequence of phase angles of length d+1, corresponding to an odd polynomial approximation of the scaled inverse function.
|
|
155
|
-
block_encoding_cnot: Projector-controlled-not unitary that locates the encoded matrix columns within U. Accepts a quantum variable
|
|
156
|
-
u: A block
|
|
157
|
-
qvar: The quantum variable to which U is applied, which resides in the entire block encoding space.
|
|
148
|
+
block_encoding_cnot: Projector-controlled-not unitary that locates the encoded matrix columns within U. Accepts a quantum variable that should be set to |1> when the state is in the block.
|
|
149
|
+
u: A block encoding unitary matrix.
|
|
158
150
|
aux: A zero auxilliary qubit, used for the projector-controlled-phase rotations. Given as an inout so that qsvt can be used as a building-block in a larger algorithm.
|
|
159
151
|
"""
|
|
160
152
|
qsvt(
|
|
161
153
|
phase_seq,
|
|
162
154
|
block_encoding_cnot,
|
|
163
155
|
block_encoding_cnot,
|
|
164
|
-
lambda
|
|
165
|
-
qvar,
|
|
156
|
+
lambda: invert(lambda: u()),
|
|
166
157
|
aux,
|
|
167
158
|
)
|
|
168
159
|
|
|
@@ -171,8 +162,7 @@ def qsvt_inversion(
|
|
|
171
162
|
def projector_controlled_double_phase(
|
|
172
163
|
phase_even: CReal,
|
|
173
164
|
phase_odd: CReal,
|
|
174
|
-
proj_cnot: QCallable[
|
|
175
|
-
qvar: QArray[QBit],
|
|
165
|
+
proj_cnot: QCallable[QBit],
|
|
176
166
|
aux: QBit,
|
|
177
167
|
lcu: QBit,
|
|
178
168
|
) -> None:
|
|
@@ -187,15 +177,15 @@ def projector_controlled_double_phase(
|
|
|
187
177
|
$$
|
|
188
178
|
|
|
189
179
|
Args:
|
|
190
|
-
phase_even: Rotation phase, corresponds to 'lcu'=
|
|
191
|
-
phase_odd: Rotation phase, corresponds to 'lcu'=
|
|
180
|
+
phase_even: Rotation phase, corresponds to 'lcu'=0.
|
|
181
|
+
phase_odd: Rotation phase, corresponds to 'lcu'=1.
|
|
192
182
|
proj_cnot: Projector-controlled-not unitary that sets an auxilliary qubit to |1> when the state is in the projection.
|
|
193
|
-
qvar: The quantum variable to which the rotation applies, which resides in the entire block encoding space.
|
|
194
183
|
aux: A zero auxilliary qubit, used for the projector-controlled-phase rotation. Given as an inout so that qsvt can be used as a building-block in a larger algorithm.
|
|
184
|
+
lcu: The quantum variable used for controlling the phase assignment.
|
|
195
185
|
"""
|
|
196
186
|
within_apply(
|
|
197
|
-
lambda: proj_cnot(
|
|
198
|
-
lambda: control(lcu, lambda: RZ(
|
|
187
|
+
lambda: proj_cnot(aux),
|
|
188
|
+
lambda: control(lcu, lambda: RZ(phase_odd, aux), lambda: RZ(phase_even, aux)),
|
|
199
189
|
)
|
|
200
190
|
|
|
201
191
|
|
|
@@ -203,10 +193,9 @@ def projector_controlled_double_phase(
|
|
|
203
193
|
def qsvt_lcu_step(
|
|
204
194
|
phases_even: CArray[CReal],
|
|
205
195
|
phases_odd: CArray[CReal],
|
|
206
|
-
proj_cnot_1: QCallable[
|
|
207
|
-
proj_cnot_2: QCallable[
|
|
208
|
-
u: QCallable
|
|
209
|
-
qvar: QArray[QBit],
|
|
196
|
+
proj_cnot_1: QCallable[QBit],
|
|
197
|
+
proj_cnot_2: QCallable[QBit],
|
|
198
|
+
u: QCallable,
|
|
210
199
|
aux: QBit,
|
|
211
200
|
lcu: QBit,
|
|
212
201
|
) -> None:
|
|
@@ -222,20 +211,19 @@ def qsvt_lcu_step(
|
|
|
222
211
|
Args:
|
|
223
212
|
phases_even: 2 rotation phases for the even polynomial
|
|
224
213
|
phases_odd: 2 rotation phases for the odd polynomial
|
|
225
|
-
proj_cnot_1: Projector-controlled-not unitary that locates the encoded matrix columns within U. Accepts a
|
|
226
|
-
proj_cnot_2: Projector-controlled-not unitary that locates the encoded matrix rows within U. Accepts a
|
|
227
|
-
u: A block
|
|
228
|
-
qvar: The quantum variable to which U is applied, which resides in the entire block encoding space.
|
|
214
|
+
proj_cnot_1: Projector-controlled-not unitary that locates the encoded matrix columns within U. Accepts a qubit that should be set to |1> when the state is in the block.
|
|
215
|
+
proj_cnot_2: Projector-controlled-not unitary that locates the encoded matrix rows within U. Accepts a qubit that should be set to |1> when the state is in the block.
|
|
216
|
+
u: A block encoding unitary matrix.
|
|
229
217
|
aux: A zero auxilliary qubit, used for the projector-controlled-phase rotations. Given as an inout so that qsvt can be used as a building-block in a larger algorithm.
|
|
230
218
|
lcu: A qubit used for the combination of 2 polynomials within a single qsvt application
|
|
231
219
|
"""
|
|
232
|
-
u(
|
|
220
|
+
u()
|
|
233
221
|
projector_controlled_double_phase(
|
|
234
|
-
phases_even[0], phases_odd[0], proj_cnot_2,
|
|
222
|
+
phases_even[0], phases_odd[0], proj_cnot_2, aux, lcu
|
|
235
223
|
)
|
|
236
|
-
invert(lambda: u(
|
|
224
|
+
invert(lambda: u())
|
|
237
225
|
projector_controlled_double_phase(
|
|
238
|
-
phases_even[1], phases_odd[1], proj_cnot_1,
|
|
226
|
+
phases_even[1], phases_odd[1], proj_cnot_1, aux, lcu
|
|
239
227
|
)
|
|
240
228
|
|
|
241
229
|
|
|
@@ -243,10 +231,9 @@ def qsvt_lcu_step(
|
|
|
243
231
|
def qsvt_lcu(
|
|
244
232
|
phase_seq_even: CArray[CReal],
|
|
245
233
|
phase_seq_odd: CArray[CReal],
|
|
246
|
-
proj_cnot_1: QCallable[
|
|
247
|
-
proj_cnot_2: QCallable[
|
|
248
|
-
u: QCallable
|
|
249
|
-
qvar: QArray[QBit],
|
|
234
|
+
proj_cnot_1: QCallable[QBit],
|
|
235
|
+
proj_cnot_2: QCallable[QBit],
|
|
236
|
+
u: QCallable,
|
|
250
237
|
aux: QBit,
|
|
251
238
|
lcu: QBit,
|
|
252
239
|
) -> None:
|
|
@@ -262,23 +249,22 @@ def qsvt_lcu(
|
|
|
262
249
|
|
|
263
250
|
The function is intended to be called within a context of LCU, where it is called as the SELECT operator, and wrapped
|
|
264
251
|
with initialization of the `lcu` qubit to get the desired combination coefficients.
|
|
265
|
-
The even polynomial corresponds to the case where the $lcu=|0\\rangle$, while the odd to
|
|
252
|
+
The even polynomial corresponds to the case where the $lcu=|0\\rangle$, while the odd to $lcu=|1\\rangle$.
|
|
266
253
|
|
|
267
254
|
Note: the two polynomials should have the same degree up to a difference of 1.
|
|
268
255
|
|
|
269
256
|
Args:
|
|
270
257
|
phase_seq_odd: A sequence of phase angles of length d+(d%2) for the odd polynomial.
|
|
271
258
|
phase_seq_even: A sequence of phase angles of length d+(d+1)%2 for the even polynomial.
|
|
272
|
-
proj_cnot_1: Projector-controlled-not unitary that locates the encoded matrix columns within U. Accepts a
|
|
273
|
-
proj_cnot_2: Projector-controlled-not unitary that locates the encoded matrix rows within U. Accepts a
|
|
274
|
-
u: A block
|
|
275
|
-
qvar: The quantum variable to which U is applied, which resides in the entire block encoding space.
|
|
259
|
+
proj_cnot_1: Projector-controlled-not unitary that locates the encoded matrix columns within U. Accepts a qubit that should be set to |1> when the state is in the block.
|
|
260
|
+
proj_cnot_2: Projector-controlled-not unitary that locates the encoded matrix rows within U. Accepts a qubit that should be set to |1> when the state is in the block.
|
|
261
|
+
u: A block encoding unitary matrix.
|
|
276
262
|
aux: A zero auxilliary qubit, used for the projector-controlled-phase rotations. Given as an inout so that qsvt can be used as a building-block in a larger algorithm.
|
|
277
263
|
lcu: A qubit used for the combination of 2 polynomials within a single qsvt application
|
|
278
264
|
"""
|
|
279
265
|
H(aux)
|
|
280
266
|
projector_controlled_double_phase(
|
|
281
|
-
phase_seq_even[0], phase_seq_odd[0], proj_cnot_1,
|
|
267
|
+
phase_seq_even[0], phase_seq_odd[0], proj_cnot_1, aux, lcu
|
|
282
268
|
)
|
|
283
269
|
repeat(
|
|
284
270
|
count=floor((qmin(phase_seq_odd.len - 1, phase_seq_even.len - 1)) / 2),
|
|
@@ -288,7 +274,6 @@ def qsvt_lcu(
|
|
|
288
274
|
proj_cnot_1,
|
|
289
275
|
proj_cnot_2,
|
|
290
276
|
u,
|
|
291
|
-
qvar,
|
|
292
277
|
aux,
|
|
293
278
|
lcu,
|
|
294
279
|
),
|
|
@@ -296,11 +281,11 @@ def qsvt_lcu(
|
|
|
296
281
|
if_(
|
|
297
282
|
condition=phase_seq_odd.len > phase_seq_even.len,
|
|
298
283
|
then=lambda: control(
|
|
299
|
-
lcu
|
|
284
|
+
lcu,
|
|
300
285
|
lambda: [
|
|
301
|
-
u(
|
|
286
|
+
u(),
|
|
302
287
|
projector_controlled_phase(
|
|
303
|
-
phase_seq_odd[phase_seq_odd.len - 1], proj_cnot_2,
|
|
288
|
+
phase_seq_odd[phase_seq_odd.len - 1], proj_cnot_2, aux
|
|
304
289
|
),
|
|
305
290
|
],
|
|
306
291
|
),
|
|
@@ -308,21 +293,20 @@ def qsvt_lcu(
|
|
|
308
293
|
if_(
|
|
309
294
|
condition=phase_seq_odd.len < phase_seq_even.len,
|
|
310
295
|
then=lambda: (
|
|
311
|
-
u(
|
|
296
|
+
u(),
|
|
312
297
|
projector_controlled_double_phase(
|
|
313
298
|
phase_seq_even[phase_seq_even.len - 2],
|
|
314
299
|
phase_seq_odd[phase_seq_odd.len - 1],
|
|
315
300
|
proj_cnot_2,
|
|
316
|
-
qvar,
|
|
317
301
|
aux,
|
|
318
302
|
lcu,
|
|
319
303
|
),
|
|
320
304
|
control(
|
|
321
|
-
lcu,
|
|
305
|
+
lcu == 0,
|
|
322
306
|
lambda: [
|
|
323
|
-
invert(lambda: u(
|
|
307
|
+
invert(lambda: u()),
|
|
324
308
|
projector_controlled_phase(
|
|
325
|
-
phase_seq_even[phase_seq_even.len - 1], proj_cnot_1,
|
|
309
|
+
phase_seq_even[phase_seq_even.len - 1], proj_cnot_1, aux
|
|
326
310
|
),
|
|
327
311
|
],
|
|
328
312
|
),
|
|
@@ -342,7 +326,10 @@ def _gqsp_r_gate(theta: CReal, phi: CReal, _lambda: CReal, q: QBit) -> None:
|
|
|
342
326
|
|
|
343
327
|
@qfunc
|
|
344
328
|
def gqsp(
|
|
345
|
-
u: QCallable,
|
|
329
|
+
u: QCallable,
|
|
330
|
+
aux: QBit,
|
|
331
|
+
phases: CArray[CArray[CReal], Literal[3]],
|
|
332
|
+
negative_power: CInt,
|
|
346
333
|
) -> None:
|
|
347
334
|
"""
|
|
348
335
|
Implements Generalized Quantum Signal Processing (GQSP), which realizes a
|