Quantum Gates ============= In quantum computing, gates are used to manipulate quantum registers and to implement quantum algorithms. Built-In Gates -------------- There are a number of gates built into QCGPU. They can all be applied the same way: .. code:: python import qcgpu register = qcgpu.State(2) state.h(0) # Applies the Hadamard (H) gate to the first qubit. state.x(1) # Applies a pauli-x (NOT) gate to the second qubit. ``h`` and ``x`` can be replaced with any of the following: - The Hadamard gate: **h** - ``state.h(0)`` - The S gate: **s** - ``state.s(0)`` - The T gate: **t** - ``state.t(0)`` - The Pauli-X / NOT gate: **x** - ``state.x(0)`` - The Pauli-Y gate: **y** - ``state.y(0)`` - The Pauli-Z gate: **z** - ``state.z(0)`` - The CNOT gate: **cx** - ``state.cx(0, 1) # CNOT with control = 0, target = 1`` - The SWAP gate: **swap** - ``state.swap(0,1) # Swaps the 0th and 1st qubit`` - The Toffoli gate: **toffoli** - ``state.toffoli(0, 1, 2) # Toffoli with controls = (0, 1), target = 2`` These are all shorthand methods for the application of arbitrary gates. For example, the application of a Hadamard gate above is shorthand for .. code:: python import qcgpu h = qcgpu.gate.h() register = qcgpu.State(5) register.apply_gate(h, 0) You can also use any of the gates as controlled gates. For example, the application of the CNOT gate above is shorthand for .. code:: python import qcgpu x = qcgpu.gate.x() register = qcgpu.State(5) register.apply_controlled_gate(x, 0, 1) Applying A Gate To A Whole Register ---------------------------------- There is a convenience method to apply a gate to every qubit in the register. The following applies a Hadamard gate to the whole register, .. code:: python import qcgpu h = qcgpu.gate.h() register = qcgpu.State(5) register.apply_all(h) User Defined Gates ------------------ Gates in QCGPU are represented by the ``qcgpu.Gate`` class. The only gates that can be defined by the user are single qubit gates. The process of creating a gate is .. code:: python import qcgpu import numpy as np gate_matrix = np.array([ [1, 0], [0, np.exp(1j * np.pi / 4)] ]) gate = qcgpu.Gate(gate_matrix) The input to the ``Gate`` constructor is checked to be a 2x2 unitary matrix. This newly created gate can then be applied the long hand way, .. code:: python import qcgpu register = qcgpu.State(2) register.apply_gate(gate, 0)