# How to implement Projector Control-Not in Qiskit?

I want to impliment Projector Control-Not in Qiskit just like in this , which is a $$|0\rangle\langle 0|$$ projector found in the paper "Grand Unification of Quantum Algorithm" page 7. Also, is the angle $$\phi$$ and the exp same as the parameter of rz($$\phi$$) in Qiskit.

From PhD thesis of András Gilyén, Quantum Singular Value Transformation & Its Algorithmic Applications[1], page 19

Projector-controlled NOT gate. For an orthogonal projector $$\Pi$$ we will frequently use the $$\Pi$$-controlled NOT gate, denoted by $$\text{C}_{\Pi}\text{NOT}$$, which flips the value of the first (single-qubit) register whenever the state of the second register is in the image of $$\Pi$$. For example if $$\Pi = |1 \rangle\langle 1|$$ is the projector to the single-qubit basis state $$|1\rangle$$, then we just get back the CNOT gate controlled by the second qubit.

2.1.1. DEFINITION ($$\text{C}_{\Pi}\text{NOT}$$ gate). For an orthogonal projector $$\Pi$$ let us define the $$\Pi$$-controlled NOT gate as the unitary operator

$$\text{C}_{\Pi}\text{NOT} := X \otimes \Pi + I \otimes (I - \Pi)$$

This operator can be used for instance for implementing a coherent (unitary) analogue of a projective measurement. Also note that up to a conjugation by a Hadamard gate on the first qubit, this gate is the same as the controlled reflection $$(I - 2\Pi)$$ gate.

For your other question, we have[2] $$R_z(\lambda) = \exp(-i\frac{\lambda}{2}Z)$$ So, the phase shift in the figure is equivalent to $$\text{rz}(2 \phi)$$

Based on the above, we can implement the projector-controlled NOT gate when the projector equals $$|0\rangle\langle0|$$ as follows:

from qiskit.circuit import Parameter
from qiskit.quantum_info import Statevector
from qiskit.opflow import I, X, PrimitiveOp

zero_state = Statevector.from_label('0')
projector = PrimitiveOp(zero_state.to_operator())

# Qiskit uses little-endian bit ordering:
projector_controlled_not = (projector ^ X) + ((I - projector) ^ I)

phi = Parameter('ϕ')
circ.unitary(projector_controlled_not, [0, 1])
circ.rz(2*phi, 0)
circ.unitary(projector_controlled_not, [0, 1])
circ.draw('mpl')


It's easy to get confused with all the mathematical jargon. Here's what the Projector-CNOT means in simple language:

You can think of this Projector-CNOT as applying a CNOT on the ancilla qubit if the projector qubit is in the state you want it to be. For example, in this case you apply the CNOT if the projector qubit is in the $$\vert0\rangle$$ state. You can easily implement this by applying an $$X$$ gate on the projector qubit, using the projector qubit as the control to apply CNOT on the ancilla, and then applying $$X$$ again on the projector qubit. (For the above example, 2 of the $$X$$ gates in the middle would cancel out so you would only need the outer ones)

In terms of the angles, it doesn't really matter. But if you're using the angles calculated by others based on this definition, you would have to use $$R_z(2\phi)$$.