grovers/grovers.rs
1/*
2* Copyright (c) 2024 Andrew Rowan Barlow. Licensed under the EUPL-1.2
3* or later. You may obtain a copy of the licence at
4* https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12. A copy
5* of the EUPL-1.2 licence in English is given in LICENCE.txt which is
6* found in the root directory of this repository.
7*
8* Author: Andrew Rowan Barlow <a.barlow.dev@gmail.com>
9*/
10
11// A 3 qubit circuit that implements Grovers algorithm. The oracle target the states |110> and
12// |111>. This example will also print the circuit, and show the simulation in real time.
13//
14// This example will print a bin count of measured states from 500 repeated simulations, and the
15// superposition itself.
16
17use quantr::{Circuit, Gate, Measurement, Printer, QuantrError};
18
19#[rustfmt::skip]
20fn main() -> Result<(), QuantrError> {
21 let mut circuit = Circuit::new(3)?;
22
23 // Kick state into superposition of equal weights
24 circuit.add_repeating_gate(Gate::H, &[0, 1, 2])?;
25
26 // Oracle
27 circuit.add_gate(Gate::CZ(1), 0)?;
28
29 // Amplitude amplification
30 circuit
31 .add_repeating_gate(Gate::H, &[0, 1, 2])?
32 .add_repeating_gate(Gate::X, &[0, 1, 2])?
33 .add_gate(Gate::H, 2)?
34 .add_gate(Gate::Toffoli(0, 1), 2)?
35 .add_gate(Gate::H, 2)?
36 .add_repeating_gate(Gate::X, &[0, 1, 2])?
37 .add_repeating_gate(Gate::H, &[0, 1, 2])?;
38
39 // Prints the circuit in UTF-8
40 let mut printer = Printer::new(&circuit);
41 printer.print_diagram();
42
43 // Print the progress of the simulation
44 circuit.set_print_progress(true);
45
46 // Simulates the circuit
47 let simulated_circuit = circuit.simulate();
48 println!("");
49
50 // Displays bin count of the resulting 500 repeat measurements of
51 // superpositions. bin_count is a HashMap<ProductState, usize>.
52 if let Measurement::Observable(bin_count) = simulated_circuit.measure_all(500) {
53 println!("[Observable] Bin count of observed states.");
54 for (state, count) in bin_count {
55 println!("|{}> observed {} times", state, count);
56 }
57 }
58
59 // Returns the superpsoition that cannot be directly observed.
60 if let Measurement::NonObservable(output_super_position) = simulated_circuit.get_state()
61 {
62 println!("\n[Non-Observable] The amplitudes of each state in the final superposition.");
63 for (state, amplitude) in output_super_position.into_iter() {
64 println!("|{}> : {}", state, amplitude);
65 }
66 }
67
68 Ok(())
69}