Struct 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<'circ>(circuit: &'circ Circuit) -> Printer<'circ>

Handle the printing of the given circuit.

Examples found in repository?
examples/post_select.rs (line 23)
17fn main() -> Result<(), QuantrError> {
18    let mut qc = Circuit::new(3)?;
19
20    qc.add_repeating_gate(Gate::H, &[0, 1, 2])?
21        .add_gate(Gate::Custom(post_select, vec![], "P".to_string()), 1)?;
22
23    let mut printer = Printer::new(&qc);
24    printer.print_diagram();
25
26    qc.set_print_progress(true);
27    let simulated_qc = qc.simulate();
28
29    if let Measurement::NonObservable(final_sup) = simulated_qc.get_state() {
30        println!("\nThe final superposition is:");
31        for (state, amplitude) in final_sup.into_iter() {
32            println!("|{}> : {}", state, amplitude);
33        }
34    }
35
36    Ok(())
37}
More examples
Hide additional examples
examples/qft.rs (line 28)
21fn main() -> Result<(), QuantrError> {
22    let mut qc: Circuit = Circuit::new(3)?;
23
24    // Apply qft
25    qc.add_repeating_gate(Gate::X, &[1, 2])?
26        .add_gate(Gate::Custom(qft, vec![0, 1], "QFT".to_string()), 2)?; // QFT on bits 0, 1 and 2
27
28    let mut printer = Printer::new(&qc);
29    printer.print_diagram();
30
31    qc.set_print_progress(true);
32
33    let simulated_circuit = qc.simulate();
34
35    if let Measurement::NonObservable(final_sup) = simulated_circuit.get_state() {
36        println!("\nThe final superposition is:");
37        for (state, amplitude) in final_sup.into_iter() {
38            println!("|{}> : {}", state, amplitude);
39        }
40    }
41
42    Ok(())
43}
examples/generalised_control_not_gate.rs (line 35)
21fn main() -> Result<(), QuantrError> {
22    let mut qc: Circuit = Circuit::new(CIRCUIT_SIZE)?;
23
24    // Multi-controlled gate used here.
25    qc.add_repeating_gate(Gate::X, &[0, 1, 2, 3, 4, 5])?
26        .add_gate(
27            Gate::Custom(
28                multicnot::<CIRCUIT_SIZE>,
29                vec![0, 1, 2, 3, 4],
30                "X".to_string(),
31            ),
32            5,
33        )?;
34
35    let mut circuit_printer: Printer = Printer::new(&qc);
36    circuit_printer.print_diagram();
37
38    qc.set_print_progress(true);
39    let simulated = qc.simulate();
40
41    // Prints the bin count of measured states.
42    if let Measurement::Observable(bin_count) = simulated.measure_all(50) {
43        println!("\nStates observed over 50 measurements:");
44        for (states, count) in bin_count.into_iter() {
45            println!("|{}> : {}", states, count);
46        }
47    }
48
49    Ok(())
50}
examples/custom_gate.rs (line 27)
18fn main() -> Result<(), QuantrError> {
19    let mut qc: Circuit = Circuit::new(4)?;
20
21    // Build a circuit using a CCC-not gate, placing the control nodes on positions 0, 1, 2 and
22    // the target on 3.
23    qc.add_repeating_gate(Gate::X, &[0, 1, 2])?
24        .add_gate(Gate::Custom(cccnot, vec![0, 1, 2], "X".to_string()), 3)?;
25
26    // Prints the circuit, viewing the custom gate.
27    let mut circuit_printer: Printer = Printer::new(&qc);
28    circuit_printer.print_diagram();
29
30    // Prints the simulation process of each gate (excluding identity gates).
31    qc.set_print_progress(true);
32    let simulated = qc.simulate();
33
34    // Prints the bin count of measured states.
35    if let Measurement::Observable(bin_count) = simulated.measure_all(50) {
36        println!("\nStates observed over 50 measurements:");
37        for (states, count) in bin_count.into_iter() {
38            println!("|{}> : {}", states, count);
39        }
40    }
41
42    Ok(())
43}
examples/grovers.rs (line 40)
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}
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/post_select.rs (line 24)
17fn main() -> Result<(), QuantrError> {
18    let mut qc = Circuit::new(3)?;
19
20    qc.add_repeating_gate(Gate::H, &[0, 1, 2])?
21        .add_gate(Gate::Custom(post_select, vec![], "P".to_string()), 1)?;
22
23    let mut printer = Printer::new(&qc);
24    printer.print_diagram();
25
26    qc.set_print_progress(true);
27    let simulated_qc = qc.simulate();
28
29    if let Measurement::NonObservable(final_sup) = simulated_qc.get_state() {
30        println!("\nThe final superposition is:");
31        for (state, amplitude) in final_sup.into_iter() {
32            println!("|{}> : {}", state, amplitude);
33        }
34    }
35
36    Ok(())
37}
More examples
Hide additional examples
examples/qft.rs (line 29)
21fn main() -> Result<(), QuantrError> {
22    let mut qc: Circuit = Circuit::new(3)?;
23
24    // Apply qft
25    qc.add_repeating_gate(Gate::X, &[1, 2])?
26        .add_gate(Gate::Custom(qft, vec![0, 1], "QFT".to_string()), 2)?; // QFT on bits 0, 1 and 2
27
28    let mut printer = Printer::new(&qc);
29    printer.print_diagram();
30
31    qc.set_print_progress(true);
32
33    let simulated_circuit = qc.simulate();
34
35    if let Measurement::NonObservable(final_sup) = simulated_circuit.get_state() {
36        println!("\nThe final superposition is:");
37        for (state, amplitude) in final_sup.into_iter() {
38            println!("|{}> : {}", state, amplitude);
39        }
40    }
41
42    Ok(())
43}
examples/generalised_control_not_gate.rs (line 36)
21fn main() -> Result<(), QuantrError> {
22    let mut qc: Circuit = Circuit::new(CIRCUIT_SIZE)?;
23
24    // Multi-controlled gate used here.
25    qc.add_repeating_gate(Gate::X, &[0, 1, 2, 3, 4, 5])?
26        .add_gate(
27            Gate::Custom(
28                multicnot::<CIRCUIT_SIZE>,
29                vec![0, 1, 2, 3, 4],
30                "X".to_string(),
31            ),
32            5,
33        )?;
34
35    let mut circuit_printer: Printer = Printer::new(&qc);
36    circuit_printer.print_diagram();
37
38    qc.set_print_progress(true);
39    let simulated = qc.simulate();
40
41    // Prints the bin count of measured states.
42    if let Measurement::Observable(bin_count) = simulated.measure_all(50) {
43        println!("\nStates observed over 50 measurements:");
44        for (states, count) in bin_count.into_iter() {
45            println!("|{}> : {}", states, count);
46        }
47    }
48
49    Ok(())
50}
examples/custom_gate.rs (line 28)
18fn main() -> Result<(), QuantrError> {
19    let mut qc: Circuit = Circuit::new(4)?;
20
21    // Build a circuit using a CCC-not gate, placing the control nodes on positions 0, 1, 2 and
22    // the target on 3.
23    qc.add_repeating_gate(Gate::X, &[0, 1, 2])?
24        .add_gate(Gate::Custom(cccnot, vec![0, 1, 2], "X".to_string()), 3)?;
25
26    // Prints the circuit, viewing the custom gate.
27    let mut circuit_printer: Printer = Printer::new(&qc);
28    circuit_printer.print_diagram();
29
30    // Prints the simulation process of each gate (excluding identity gates).
31    qc.set_print_progress(true);
32    let simulated = qc.simulate();
33
34    // Prints the bin count of measured states.
35    if let Measurement::Observable(bin_count) = simulated.measure_all(50) {
36        println!("\nStates observed over 50 measurements:");
37        for (states, count) in bin_count.into_iter() {
38            println!("|{}> : {}", states, count);
39        }
40    }
41
42    Ok(())
43}
examples/grovers.rs (line 41)
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}
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
Source

pub fn set_warnings(&mut self, printing: bool)

Sets if the printer should display warnings.

Auto Trait Implementations§

§

impl<'a> Freeze for Printer<'a>

§

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>,

Source§

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>,

Source§

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.