# Quantum Gates

Gates are used to manipulate quantum registers and to implement quantum algorithms.

## Built In Gates

There are a number of gates built in to QCGPU. They can all be applied the same way:

    # #![allow(unused_variables)]
    #fn main() {
    use qcgpu::State;

    let mut state = State::new(5, 0);

    state.h(0); // Applies the hadamard (`h`) gate to the 0th qubit
    #}

`h` can be replaced with any of the following:

- The hadmard 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 control1 = 0, control1 = 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

    # #![allow(unused_variables)]
    #fn main() {
    use qcgpu::gates::{h};
    use qcgpu::State;

    let mut state = State::new(5, 0);
    state.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

    # #![allow(unused_variables)]
    #fn main() {
    use qcgpu::gates::{x};
    use qcgpu::State;

    let mut state = State::new(5, 0);
    state.apply_controlled_gate(x(), 0, 1);
    #}

## User Defined Gates

Gates in QCGPU are represented by the `Gate` struct, available through `qcgpu::Gate`.

It is defined as follows:

    # #![allow(unused_variables)]
    #fn main() {
    extern crate num_complex;
    use num_complex::Complex32;

    struct Gate {
        a: Complex32,
        b: Complex32,
        c: Complex32,
        d: Complex32,
    }
    #}

To create your own gate, you will need to add the `num_complex` crate to your dependencies.

A gate is created as follows:

    # #![allow(unused_variables)]
    #fn main() {
    let x = Gate {
        Gate {
            a: Complex32::new(0.0, 0.0),
            b: Complex32::new(1.0, 0.0),
            c: Complex32::new(1.0, 0.0),
            d: Complex32::new(0.0, 0.0),
        }
    }
    #}

This corresponds to the matrix

\[x = \begin{bmatrix} 0 & 1 \\ 1 & 0 \end{bmatrix}\]

This can be applied using the same long hand method as above:

    # #![allow(unused_variables)]
    #fn main() {
    let mut state = State::new(1, 0);
    state.apply_gate(x, 0);
    #}