qcgpu 0.1.0

Open Source, High Performance & Hardware Accelerated, Quantum Computer Simulation in Rust
Documentation
# Grovers Algorithm

Given an unstructured set \\(N = \{a_1, a_2,\dots,a_n\}\\), find
a given element \\(a_i \in N\\).

This implementation looks for a given number \\(target\\) in the set \\(\{0,1,\dots, \text{regwidth}\}\\).

See <https://cs.uwaterloo.ca/~watrous/LectureNotes.html>

```rust
extern crate qcgpu;
extern crate rand;

use qcgpu::State;
use std::f32::consts::PI;

fn main() {
    let mut state = State::new(8, 1);

    let target = 5;
    let reg_width = 3;

    let num_inversions = ((PI / 4.0) * ((1 << reg_width) as f32).sqrt()) as i32;

    state.x(reg_width);

    for i in 0..(reg_width + 1) {
        state.h(i);
    }

    for _ in 0..(num_inversions) {
        iteration(&mut state, target, reg_width);
    }

    state.h(reg_width);

    println!("Measured: {:?}", state.measure_first(reg_width, 1000));
}

fn oracle(state: &mut State, target: i32, reg_width: i32) {
    for i in 0..reg_width {
        if get_bit(target, i) == 0 {
            state.x(i);
        }
    }

    state.toffoli(0, 1, reg_width + 1);

    let mut i = 1;
    while i < reg_width {
        state.toffoli(i, reg_width + i, reg_width + i + 1);
        i += 1;
    }

    state.cx(reg_width + i, reg_width);

    i = reg_width - 1;
    while i > 0 {
        state.toffoli(i, reg_width + i, reg_width + i + 1);
        i -= 1;
    }

    state.toffoli(0, 1, reg_width + 1);

    for i in 0..reg_width {
        if get_bit(target, i) == 0 {
            state.x(i);
        }
    }
}

fn inversion(state: &mut State, reg_width: i32) {
    for i in 0..reg_width {
        state.x(i);
    }

    state.h(reg_width - 1);

    if reg_width == 3 {
        state.toffoli(0, 1, 2);
    } else {
        state.toffoli(0, 1, reg_width + 1);

        let mut i = 1;
        while i < reg_width {
            state.toffoli(i, reg_width + i, reg_width + i + 1);
            i += 1;
        }

        state.cx(reg_width + i, reg_width - 1);

        i = reg_width - 2;
        while i > 0 {
            state.toffoli(i, reg_width + i, reg_width + i + 1);
            i -= 1;
        }

        state.toffoli(0, 1, reg_width + 1);
    }

    state.h(reg_width - 1);

    for i in 0..reg_width {
        state.x(i);
    }
}

fn iteration(state: &mut State, target: i32, reg_width: i32) {
    oracle(state, target, reg_width);

    for i in 0..reg_width {
        state.h(i);
    }

    inversion(state, reg_width);

    for i in 0..reg_width {
        state.h(i);
    }
}

/// Get the value of a bit
fn get_bit(number: i32, n: i32) -> i32 {
    if number & (1 << n) != 0 {
        return 1;
    }
    0
}
```