quantr/lib.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 gate-based quantum circuit simulator that focuses on memory efficency and accessibility.
12//!
13//! Initialise a new quantum circuit by using [Circuit::new] where the argument defines the number
14//! of qubits. Afterwards, various methods can be called to append gates onto the circuit in columns.
15//! For instance, [Circuit::add_gate] will add a single gate, whilst
16//! [Circuit::add_gates_with_positions] and [Circuit::add_repeating_gate] will add multiple.
17//!
18//! Before committing to a simulation, the circuit can be printed to the console or exported as a
19//! UTF-8 string to an external file using [Printer::print_diagram] and [Printer::save_diagram]
20//! respectively. The printer is created with [Printer::new] an by passing a reference to the
21//! circuit that should be printed.
22//!
23//! The circuit can then be simulated with [Circuit::simulate]. The progress of the simulation can
24//! be printed to the terminal by calling [Circuit::set_print_progress] before simulating
25//! the circuit. This produces a new struct [SimulatedCircuit] that guarantees that the circuit was
26//! simulated successfully.
27//!
28//! A bin count of states that are observed over a period of measurements can be performed with
29//! [SimulatedCircuit::measure_all], where a new register is attached before each measurement. Or, the
30//! explicit superposition can be retrieved using [SimulatedCircuit::get_state].
31//!
32//! All errors resulting from the incorrect use of quantr are propagated by [QuantrError].
33//!
34//! More complex examples can be found in the `../examples/` folder within this repository.
35//!
36//! For now, quantr is primiarly designed to simulate pure states, _some_ quantum channels
37//! can be implemented. For an example, see `../examples/post_select.rs`.
38//!
39//! # Example
40//! ```
41//! use quantr::{Circuit, Gate, Printer, Measurement::Observable};
42//!
43//! let mut quantum_circuit: Circuit = Circuit::new(2).unwrap();
44//!
45//! quantum_circuit
46//! .add_gates(&[Gate::H, Gate::Y]).unwrap()
47//! .add_gate(Gate::CNot(0), 1).unwrap();
48//!
49//! let mut printer = Printer::new(&quantum_circuit);
50//! printer.print_diagram();
51//! // The above prints the following:
52//! // ┏━━━┓
53//! // ┨ H ┠──█──
54//! // ┗━━━┛ │
55//! // │
56//! // ┏━━━┓┏━┷━┓
57//! // ┨ Y ┠┨ X ┠
58//! // ┗━━━┛┗━━━┛
59//!
60//! let simulated_circuit = quantum_circuit.simulate();
61//!
62//! // Below prints the number of times that each state was observered
63//! // over 500 measurements of superpositions.
64//!
65//! if let Observable(bin_count) = simulated_circuit.measure_all(500) {
66//! println!("[Observable] Bin count of observed states.");
67//! for (state, count) in bin_count {
68//! println!("|{}> observed {} times", state, count);
69//! }
70//! }
71//!
72
73mod circuit;
74mod complex;
75mod error;
76mod simulated_circuit;
77
78pub extern crate num_complex;
79
80// Make available for public use.
81pub use circuit::gate::Gate;
82pub use circuit::printer::Printer;
83pub use circuit::{measurement::Measurement, states, Circuit};
84pub use error::QuantrError;
85pub use simulated_circuit::SimulatedCircuit;