qml.change_op_basis¶
- change_op_basis(compute_op, target_op, uncompute_op=None)[source]¶
Construct an operator that represents the product of the operators provided; particularly a compute-uncompute pattern.
- Parameters:
compute_op (
Operator| Callable) – A single operator orCallablewith no inputs that applies quantum operations.target_op (
Operator| Callable) – A single operator orCallablewith no inputs that applies quantum operations.uncompute_op (None |
Operator| Callable) – An optional single operator orCallablewith no inputs that applies quantum operations.Nonecorresponds touncompute_op=qml.adjoint(compute_op).
- Returns:
the operator representing the compute-uncompute pattern.
- Return type:
- Raises:
TypeError – if any arguments are not
CallablesorOperators, or aCallableargument has input parameters.
Example
Consider the following example involving a
ChangeOpBasis. The compute, uncompute pattern is composed of a Quantum Fourier Transform (QFT), followed by aPhaseAdder, and finally an inverseQFT.import pennylane as qml from functools import partial qml.decomposition.enable_graph() dev = qml.device("default.qubit") @qml.qnode(dev) def circuit(): qml.H(0) qml.CNOT([1,2]) qml.ctrl( qml.change_op_basis(qml.QFT([1,2]), qml.PhaseAdder(1, x_wires=[1,2])), control=0 ) return qml.state() circuit2 = qml.decompose(circuit, max_expansion=1)
When this circuit is decomposed, the
compute_opanduncompute_opare not controlled, resulting in a much more resource-efficient decomposition:>>> print(qml.draw(circuit2)()) 0: ──H──────╭●────────────────┤ State 1: ─╭●─╭QFT─├PhaseAdder─╭QFT†─┤ State 2: ─╰X─╰QFT─╰PhaseAdder─╰QFT†─┤ State
A
Callablecan also be provided as an argument toChangeOpBasis. This can be a function that applies a series ofOperations. SinceChangeOpBasisrequires thisCallableto have no input arguments,functools.partialcan be used to absorb any necessary parameters.def my_compute_op(a, reg1, reg2): qml.BasisState(np.zeros(len(reg2)), reg2) qml.QFT(reg1) qml.RX(a, reg1[0]) def my_target_op(wires): qml.PauliX(wires[0]) dev = qml.device("default.qubit") @qml.qnode(dev) def circuit(): # Use partial to absorb any input parameters compute = partial(my_compute_op, 0.1, [0], [1]) target = partial(my_target_op, [0]) qml.change_op_basis(compute, target) return qml.state() circuit3 = qml.decompose(circuit, max_expansion=1)
>>> print(qml.draw(circuit3)()) 0: ─╭RX(0.10)@QFT@|Ψ⟩──X─╭(RX(0.10)@QFT@|Ψ⟩)†─┤ State 1: ─╰RX(0.10)@QFT@|Ψ⟩────╰(RX(0.10)@QFT@|Ψ⟩)†─┤ State
See also