grover.md 2.5 KB

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

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
}