0a4b3d01 |
"n_qubits",
"controlled",
# -- Single qubit gates --
"id",
"x",
"y",
"z",
"not_",
"sqrt_not",
"phase_shift",
# -- 2 qubit gates --
"cnot",
"swap",
# -- 3 qubit gates --
"toffoli",
"cswap",
"fredkin",
"deutsch",
] # type: ignore
|
0a4b3d01 |
def controlled(gate):
"""Return a controlled quantum gate, given a quantum gate.
If 'gate' operates on :math:`n` qubits, then the controlled gate operates
on :math:`n+1` qubits, where the most-significant qubit is the control.
Parameters
----------
gate : np.ndarray[complex]
A quantum gate acting on :math:`n` qubits;
a :math:`2^n×2^n` unitary matrix in the computational basis.
Returns
-------
controlled_gate : np.ndarray[(2**(n+1), 2**(n+1)), complex]
"""
_check_valid_gate(gate)
n = gate.shape[0]
zeros = np.zeros((n, n))
return np.block([[np.identity(n), zeros], [zeros, gate]])
# -- Single qubit gates --
#: The identity gate on 1 qubit
id = np.identity(2, complex)
#: Pauli X gate
x = np.array([[0, 1], [1, 0]], complex)
#: NOT gate
not_ = x
#: Pauli Y gate
y = np.array([[0, -1j], [1j, 0]], complex)
#: Pauli Z gate
z = np.array([[1, 0], [0, -1]], complex)
#: SQRT(NOT) gate
sqrt_not = 0.5 * (1 + 1j * id - 1j * x)
#: Hadamard gate
hadamard = np.sqrt(0.5) * (x + z)
def phase_shift(phi):
"Return a gate that shifts the phase of :math:`|1⟩` by :math:`φ`."
return np.array([[1, 0], [0, np.exp(1j * phi)]])
# -- Two qubit gates --
#: Controlled NOT gate
|
0a4b3d01 |
#: SWAP gate
swap = np.identity(4, complex)[:, (0, 2, 1, 3)]
# -- Three qubit gates --
#: Toffoli (CCNOT) gate
toffoli = controlled(cnot)
#: Controlled SWAP gate
cswap = controlled(swap)
#: Fredkin gate
fredkin = cswap
def deutsch(phi):
"Return a Deutsch gate for angle :math:`φ`."
gate = np.identity(8, complex)
gate[-2:, -2:] = np.array(
[[1j * np.cos(phi), np.sin(phi)], [np.sin(phi), 1j * np.cos(phi)]]
)
return gate
|