pub struct SimulatedCircuit { /* private fields */ }Expand description
Contains the resulting state vector produced from the simulation of a circuit.
Implementations§
Source§impl SimulatedCircuit
impl SimulatedCircuit
Sourcepub fn measure_all(
&self,
shots: usize,
) -> Measurement<HashMap<ProductState, usize>>
pub fn measure_all( &self, shots: usize, ) -> Measurement<HashMap<ProductState, usize>>
Returns a HashMap that contains the number of times the corresponding state was observed over
n measurements of the superpositions (shots).
Explicitly, this performs repeated measurements where a register is attached to the circuit,
the resulting superposition measured in the computational basis, and then the reduced state
recorded. If the HashMap does not include a product state, then it was not observed over the
n measurements.
For efficiency, this will use the cached register from the simulated circuit. If your circuit contains mixed states, then most likely the circuit will have to be simulated again for each shot. To achieve this, use SimulatedCircuit::measure_all_without_cache.
§Example
use quantr::{states::SuperPosition, Circuit, Measurement::Observable, Gate};
let mut circuit = Circuit::new(3).unwrap();
circuit.add_gate(Gate::H, 2).unwrap();
let simulated_circuit = circuit.simulate();
// Measures 500 superpositions.
println!("State | Number of Times Observed");
if let Observable(bin_count) = simulated_circuit.measure_all(500) {
for (state, observed_count) in bin_count {
println!("|{}> : {}", state, observed_count);
}
}
// State | Number of Times Observed
// |000> : 247
// |001> : 253Examples found in repository?
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}More examples
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}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}Sourcepub fn measure_all_without_cache(
self,
shots: usize,
) -> Measurement<HashMap<ProductState, usize>>
pub fn measure_all_without_cache( self, shots: usize, ) -> Measurement<HashMap<ProductState, usize>>
Similar to SimulatedCircuit::measure_all, however for every shot it will simulate the circuit, where the input register is reset to the zero state.
This potentially allows for mixed states to be simulated, through the implementation of Gate::Custom. In doing so will dramatically increase the simulation time, as a new circuit will be simulated for each shot.
Sourcepub fn get_state(&self) -> Measurement<&SuperPosition>
pub fn get_state(&self) -> Measurement<&SuperPosition>
Returns the resulting superposition after the circuit has been simulated using super::Circuit::simulate.
This is a non-physical observable, as the superposition would reduce to a single state upon measurement.
§Example
use quantr::{states::SuperPosition, Circuit, Measurement::NonObservable, Gate};
let mut circuit = Circuit::new(3).unwrap();
circuit.add_gate(Gate::H, 2).unwrap();
circuit.add_gate(Gate::Y, 2).unwrap();
let simulated_circuit = circuit.simulate();
println!("State | Amplitude of State");
if let NonObservable(super_pos) = simulated_circuit.get_state() {
for (state, amplitude) in super_pos.into_iter() {
println!("|{}> : {}", state.to_string(), amplitude);
}
}
// State | Amplitude of State
// |000> : 0 - 0.71...i
// |001> : 0 + 0.71...iExamples found in repository?
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
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}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}Sourcepub fn print_warnings(&mut self, printing: bool)
pub fn print_warnings(&mut self, printing: bool)
Sets if the printer should display warnings.
Sourcepub fn get_circuit_gates(&self) -> &Vec<Gate>
pub fn get_circuit_gates(&self) -> &Vec<Gate>
The slice of gates that composed the circuit, equivalent to Circuit::get_gates.
Sourcepub fn get_num_qubits(&self) -> usize
pub fn get_num_qubits(&self) -> usize
The number of qubits that composed the circuit, equivalent to Circuit::get_num_qubits.
Sourcepub fn set_print_progress(&mut self, printing: bool)
pub fn set_print_progress(&mut self, printing: bool)
Sets whether the simulation progress of the circuit will be printed to the terminal. This value is inherited from the circuit this struct was derived from.
Sourcepub fn take_state(self) -> Measurement<SuperPosition>
pub fn take_state(self) -> Measurement<SuperPosition>
Takes ownership of the state that the SimulatedCircuit wraps around, that is the state
that resulted from a circuit simulation.
Examples found in repository?
47fn qft(input_state: ProductState) -> Option<SuperPosition> {
48 let qubit_num = input_state.num_qubits();
49 let mut mini_circuit: Circuit = Circuit::new(qubit_num).unwrap();
50
51 for pos in 0..qubit_num {
52 mini_circuit.add_gate(Gate::H, pos).unwrap();
53 for k in 2..=(qubit_num - pos) {
54 mini_circuit
55 .add_gate(Gate::CRk(k as i32, pos + k - 1), pos)
56 .unwrap();
57 }
58 }
59
60 mini_circuit
61 .change_register(SuperPosition::from(input_state))
62 .unwrap();
63
64 Some(mini_circuit.simulate().take_state().take())
65}