BlockEncoding.apply#
- BlockEncoding.apply(*operands: QuantumVariable) list[QuantumVariable][source]#
Applies the BlockEncoding unitary to the given operands.
- Parameters:
- *operandsQuantumVariable
QuantumVariables serving as operands for the block-encoding.
- Returns:
- list[QuantumVariable]
A list of ancilla QuantumVariables used in the application. Must be measured in \(0\) for success of the block-encoding application.
- Raises:
- ValueError
If the number of provided operands does not match the required number of operands (self.num_ops).
Examples
Example 1:
Define a block-encoding and apply it using Repeat-Until-Success.
import numpy as np from qrisp import * from qrisp.block_encodings import BlockEncoding from qrisp.operators import X, Y, Z H = X(0)*X(1) + 0.5*Z(0)*Z(1) BE = BlockEncoding.from_operator(H) def operand_prep(phi): qv = QuantumFloat(2) ry(phi, qv[0]) return qv @RUS def apply_be(BE, phi): qv = operand_prep(phi) ancillas = BE.apply(qv) # Alternatively, also use: # ancillas = BE.create_ancillas() # BE.unitary(*ancillas, qv) bools = jnp.array([(measure(anc) == 0) for anc in ancillas]) success_bool = jnp.all(bools) # garbage collection [reset(anc) for anc in ancillas] [anc.delete() for anc in ancillas] return success_bool, qv @terminal_sampling def main(BE): qv = apply_be(BE, np.pi / 4) return qv main(BE) #{3: 0.6828427278345078, 0: 0.17071065215630213, 2: 0.11715730494804945, 1: 0.02928931506114055}
For convenience, the
apply_rus()method directly applies the block-encoding using RUS.Example 2:
Define a block-encoding and apply it using post-selection.
import numpy as np from qrisp import * from qrisp.block_encodings import BlockEncoding from qrisp.operators import X, Y, Z H = X(0)*X(1) + 0.5*Z(0)*Z(1) BE = BlockEncoding.from_operator(H) def operand_prep(phi): qv = QuantumFloat(2) ry(phi, qv[0]) return qv def main(BE): operand = operand_prep(np.pi / 4) ancillas = BE.apply(operand) return operand, ancillas operand, ancillas = main(BE) res_dict = multi_measurement([operand] + ancillas) # Post-selection on ancillas being in |0> state filtered_dict = {k[0]: p for k, p in res_dict.items() \ if all(x == 0 for x in k[1:])} success_prob = sum(filtered_dict.values()) filtered_dict = {k: p / success_prob for k, p in filtered_dict.items()} filtered_dict #{3: 0.6828427278345078, 0: 0.17071065215630213, 2: 0.11715730494804945, 1: 0.02928931506114055}