Struct quantr::Printer

source ·
pub struct Printer<'a> { /* private fields */ }
Expand description

Constructs, displays and saves the circuit diagram as a UTF-8 string.

The user has the option to print the string to the terminal or a text file, where the text file has the advantage of not wrapping the circuit within the terminal. The Printer will also cache a copy of the diagram so subsequent prints will require no building of the diagram.

Implementations§

source§

impl Printer<'_>

source

pub fn new<'a>(circuit: &'a Circuit<'_>) -> Printer<'a>

Handle the printing of the given circuit.

Examples found in repository?
examples/qft.rs (line 28)
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
fn main() -> Result<(), QuantrError> {
    let mut qc: Circuit = Circuit::new(3)?;

    // Apply qft
    qc.add_repeating_gate(Gate::X, &[1, 2])?
        .add_gate(Gate::Custom(qft, &[0, 1], "QFT".to_string()), 2)?; // QFT on bits 0, 1 and 2

    let mut printer = Printer::new(&qc);
    printer.print_diagram();

    qc.toggle_simulation_progress();

    qc.simulate();

    if let Ok(Measurement::NonObservable(final_sup)) = qc.get_superposition() {
        println!("\nThe final superposition is:");
        for (state, amplitude) in final_sup.into_iter() {
            println!("|{}> : {}", state.to_string(), amplitude);
        }
    }

    Ok(())
}
More examples
Hide additional examples
examples/generalised_control_not_gate.rs (line 31)
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
fn main() -> Result<(), QuantrError> {
    let mut qc: Circuit = Circuit::new(CIRCUIT_SIZE)?;

    // Multi-controlled gate used here.
    qc.add_repeating_gate(Gate::X, &[0, 1, 2, 3, 4, 5])?
        .add_gate(
            Gate::Custom(multicnot::<CIRCUIT_SIZE>, &[0, 1, 2, 3, 4], "X".to_string()),
            5,
        )?;

    let mut circuit_printer: Printer = Printer::new(&qc);
    circuit_printer.print_diagram();

    qc.toggle_simulation_progress();
    qc.simulate();

    // Prints the bin count of measured states.
    if let Ok(Measurement::Observable(bin_count)) = qc.repeat_measurement(50) {
        println!("\nStates observed over 50 measurements:");
        for (states, count) in bin_count.into_iter() {
            println!("|{}> : {}", states.to_string(), count);
        }
    }

    Ok(())
}
examples/custom_gate.rs (line 27)
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
fn main() -> Result<(), QuantrError> {
    let mut qc: Circuit = Circuit::new(4)?;

    // Build a circuit using a CCC-not gate, placing the control nodes on positions 0, 1, 2 and
    // the target on 3.
    qc.add_repeating_gate(Gate::X, &[0, 1, 2])?
        .add_gate(Gate::Custom(cccnot, &[0, 1, 2], "X".to_string()), 3)?;

    // Prints the circuit, viewing the custom gate, and then simulating it.
    let mut circuit_printer: Printer = Printer::new(&qc);
    circuit_printer.print_diagram();

    qc.toggle_simulation_progress(); // prints the simulation toggle_simulation_progress
    qc.simulate();

    // Prints the bin count of measured states.
    if let Ok(Measurement::Observable(bin_count)) = qc.repeat_measurement(50) {
        println!("\nStates observed over 50 measurements:");
        for (states, count) in bin_count.into_iter() {
            println!("|{}> : {}", states.to_string(), count);
        }
    }

    Ok(())
}
examples/grovers.rs (line 40)
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
fn main() -> Result<(), QuantrError>{
    let mut circuit = Circuit::new(3)?;

    // Kick state into superposition of equal weights
    circuit.add_repeating_gate(Gate::H, &[0, 1, 2])?;

    // Oracle
    circuit.add_gate(Gate::CZ(1), 0)?;

    // Amplitude amplification
    circuit
        .add_repeating_gate(Gate::H, &[0, 1, 2])?
        .add_repeating_gate(Gate::X, &[0, 1, 2])?
        .add_gate(Gate::H, 2)?
        .add_gate(Gate::Toffoli(0, 1), 2)?
        .add_gate(Gate::H, 2)?
        .add_repeating_gate(Gate::X, &[0, 1, 2])?
        .add_repeating_gate(Gate::H, &[0, 1, 2])?;

    // Prints the circuit in UTF-8
    let mut printer = Printer::new(&circuit);
    printer.print_diagram();

    // Un-commenting the line below will print the progress of the simulation
    circuit.toggle_simulation_progress();

    // Simulates the circuit
    circuit.simulate();
    println!("");

    // Displays bin count of the resulting 500 repeat measurements of
    // superpositions. bin_count is a HashMap<ProductState, usize>.
    if let Ok(Measurement::Observable(bin_count)) = circuit.repeat_measurement(500) {
        println!("[Observable] Bin count of observed states.");
        for (state, count) in bin_count {
            println!("|{}> observed {} times", state.to_string(), count);
        }
    } 

    // Returns the superpsoition that cannot be directly observed.
    if let Ok(Measurement::NonObservable(output_super_position)) = circuit.get_superposition()
    {
        println!("\n[Non-Observable] The amplitudes of each state in the final superposition.");
        for (state, amplitude) in output_super_position.into_iter() {
            println!("|{}> : {}", state.to_string(), amplitude);
        }
    }

    Ok(())
}
source

pub fn print_diagram(&mut self)

Prints the circuit to the console in UTF-8.

A warning is printed to the console if the circuit diagram is expected to exceed 72 chars.

Example
use quantr::{Circuit, Gate, Printer};

let mut qc: Circuit = Circuit::new(2).unwrap();
qc.add_gate(Gate::CNot(0), 1).unwrap();

let mut printer: Printer = Printer::new(&qc);
printer.print_diagram();

// The above prints:
// ──█──
//   │  
//   │  
// ┏━┷━┓
// ┨ X ┠
// ┗━━━┛
Examples found in repository?
examples/qft.rs (line 29)
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
fn main() -> Result<(), QuantrError> {
    let mut qc: Circuit = Circuit::new(3)?;

    // Apply qft
    qc.add_repeating_gate(Gate::X, &[1, 2])?
        .add_gate(Gate::Custom(qft, &[0, 1], "QFT".to_string()), 2)?; // QFT on bits 0, 1 and 2

    let mut printer = Printer::new(&qc);
    printer.print_diagram();

    qc.toggle_simulation_progress();

    qc.simulate();

    if let Ok(Measurement::NonObservable(final_sup)) = qc.get_superposition() {
        println!("\nThe final superposition is:");
        for (state, amplitude) in final_sup.into_iter() {
            println!("|{}> : {}", state.to_string(), amplitude);
        }
    }

    Ok(())
}
More examples
Hide additional examples
examples/generalised_control_not_gate.rs (line 32)
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
fn main() -> Result<(), QuantrError> {
    let mut qc: Circuit = Circuit::new(CIRCUIT_SIZE)?;

    // Multi-controlled gate used here.
    qc.add_repeating_gate(Gate::X, &[0, 1, 2, 3, 4, 5])?
        .add_gate(
            Gate::Custom(multicnot::<CIRCUIT_SIZE>, &[0, 1, 2, 3, 4], "X".to_string()),
            5,
        )?;

    let mut circuit_printer: Printer = Printer::new(&qc);
    circuit_printer.print_diagram();

    qc.toggle_simulation_progress();
    qc.simulate();

    // Prints the bin count of measured states.
    if let Ok(Measurement::Observable(bin_count)) = qc.repeat_measurement(50) {
        println!("\nStates observed over 50 measurements:");
        for (states, count) in bin_count.into_iter() {
            println!("|{}> : {}", states.to_string(), count);
        }
    }

    Ok(())
}
examples/custom_gate.rs (line 28)
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
fn main() -> Result<(), QuantrError> {
    let mut qc: Circuit = Circuit::new(4)?;

    // Build a circuit using a CCC-not gate, placing the control nodes on positions 0, 1, 2 and
    // the target on 3.
    qc.add_repeating_gate(Gate::X, &[0, 1, 2])?
        .add_gate(Gate::Custom(cccnot, &[0, 1, 2], "X".to_string()), 3)?;

    // Prints the circuit, viewing the custom gate, and then simulating it.
    let mut circuit_printer: Printer = Printer::new(&qc);
    circuit_printer.print_diagram();

    qc.toggle_simulation_progress(); // prints the simulation toggle_simulation_progress
    qc.simulate();

    // Prints the bin count of measured states.
    if let Ok(Measurement::Observable(bin_count)) = qc.repeat_measurement(50) {
        println!("\nStates observed over 50 measurements:");
        for (states, count) in bin_count.into_iter() {
            println!("|{}> : {}", states.to_string(), count);
        }
    }

    Ok(())
}
examples/grovers.rs (line 41)
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
fn main() -> Result<(), QuantrError>{
    let mut circuit = Circuit::new(3)?;

    // Kick state into superposition of equal weights
    circuit.add_repeating_gate(Gate::H, &[0, 1, 2])?;

    // Oracle
    circuit.add_gate(Gate::CZ(1), 0)?;

    // Amplitude amplification
    circuit
        .add_repeating_gate(Gate::H, &[0, 1, 2])?
        .add_repeating_gate(Gate::X, &[0, 1, 2])?
        .add_gate(Gate::H, 2)?
        .add_gate(Gate::Toffoli(0, 1), 2)?
        .add_gate(Gate::H, 2)?
        .add_repeating_gate(Gate::X, &[0, 1, 2])?
        .add_repeating_gate(Gate::H, &[0, 1, 2])?;

    // Prints the circuit in UTF-8
    let mut printer = Printer::new(&circuit);
    printer.print_diagram();

    // Un-commenting the line below will print the progress of the simulation
    circuit.toggle_simulation_progress();

    // Simulates the circuit
    circuit.simulate();
    println!("");

    // Displays bin count of the resulting 500 repeat measurements of
    // superpositions. bin_count is a HashMap<ProductState, usize>.
    if let Ok(Measurement::Observable(bin_count)) = circuit.repeat_measurement(500) {
        println!("[Observable] Bin count of observed states.");
        for (state, count) in bin_count {
            println!("|{}> observed {} times", state.to_string(), count);
        }
    } 

    // Returns the superpsoition that cannot be directly observed.
    if let Ok(Measurement::NonObservable(output_super_position)) = circuit.get_superposition()
    {
        println!("\n[Non-Observable] The amplitudes of each state in the final superposition.");
        for (state, amplitude) in output_super_position.into_iter() {
            println!("|{}> : {}", state.to_string(), amplitude);
        }
    }

    Ok(())
}
source

pub fn save_diagram(&mut self, file_path: &str) -> Result<()>

Saves the circuit diagram in UTF-8 chars to a text file.

If the file already exists, it will overwrite it.

Example
use quantr::{Circuit, Gate, Printer};

let mut qc: Circuit = Circuit::new(2).unwrap();
qc.add_gate(Gate::CNot(0), 1).unwrap();

let mut printer: Printer = Printer::new(&qc);
// printer.save_diagram("diagram.txt").unwrap();
// Saves in directory of Cargo package.
// (Commented so it doesn't create file during `cargo test`.)
source

pub fn print_and_save_diagram(&mut self, file_path: &str) -> Result<()>

Prints the circuit diagram to the terminal and saves it to a text file in UTF-8.

Essentially, this is a combination of Printer::save_diagram and Printer::print_diagram.

Example
use quantr::{Circuit, Gate, Printer};

let mut qc: Circuit = Circuit::new(2).unwrap();
qc.add_gate(Gate::CNot(0), 1).unwrap();

let mut printer: Printer = Printer::new(&qc);
// printer.print_and_save_diagram("diagram.txt").unwrap();
// Saves in directory of cargo project, and prints to console.
// (Commented so it doesn't create file during `cargo test`.)
source

pub fn get_diagram(&mut self) -> String

Returns the circuit diagram that is made from UTF-8 chars.

Example
use quantr::{Circuit, Gate, Printer};

let mut qc: Circuit = Circuit::new(2).unwrap();
qc.add_gate(Gate::CNot(0), 1).unwrap();

let mut printer: Printer = Printer::new(&qc);
println!("{}", printer.get_diagram()); // equivalent to Printer::print_diagram

Auto Trait Implementations§

§

impl<'a> RefUnwindSafe for Printer<'a>

§

impl<'a> Send for Printer<'a>

§

impl<'a> Sync for Printer<'a>

§

impl<'a> Unpin for Printer<'a>

§

impl<'a> UnwindSafe for Printer<'a>

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V