1pub mod encoder;
8pub mod library;
9pub mod visualisations;
10
11pub use intrico_core::{
13 ClassicalRegister,
14 Complex,
15 ExecutionContext,
16 ExecutionTime,
17 GateKind,
18 MeasurementResult,
19 Operation,
20 QuantumCircuit,
21 QuantumGate,
22 QuantumNode,
23 QuantumState,
24 SamplingResult,
25};
26
27pub use visualisations::plot_histogram;
28
29pub fn execute(circuit: &QuantumCircuit) -> MeasurementResult {
31 use std::time::Instant;
32 let start = Instant::now();
33 let mut ctx = ExecutionContext::new(circuit.num_qubits(), circuit.classical_regs());
34 ctx.run(circuit);
35 let (statevector, classical_register) = ctx.into_inner();
36 MeasurementResult {
37 statevector,
38 classical_register,
39 shots: 1,
40 execution_time: ExecutionTime::from_duration(start.elapsed()),
41 }
42}
43
44pub fn sample(circuit: &QuantumCircuit, shots: usize) -> SamplingResult {
46 use std::collections::HashMap;
47 use std::time::Instant;
48 use rand::RngExt;
49
50 let start = Instant::now();
51 let mut counts: HashMap<String, usize> = HashMap::new();
52 let creg_size = circuit.classical_regs();
53
54 if circuit.has_terminal_measurements_only() {
55 let mut ctx = ExecutionContext::new(circuit.num_qubits(), 0);
57 ctx.run_gates_only(circuit);
58
59 let probs: Vec<f64> = ctx
60 .state()
61 .statevector()
62 .iter()
63 .map(|a| a.norm_squared())
64 .collect();
65
66 let measurements: Vec<(usize, usize)> = circuit
67 .nodes()
68 .iter()
69 .filter_map(|n| match &n.operation {
70 Operation::Measure { qubit, classical_bit } => Some((*qubit, *classical_bit)),
71 _ => None,
72 })
73 .collect();
74
75 let dim = 1 << circuit.num_qubits();
76 let mut rng = rand::rng();
77
78 for _ in 0..shots {
79 let r: f64 = rng.random();
80 let mut cumulative = 0.0;
81 let mut sampled_index = dim - 1;
82 for (i, &p) in probs.iter().enumerate() {
83 cumulative += p;
84 if r < cumulative {
85 sampled_index = i;
86 break;
87 }
88 }
89
90 let mut creg = ClassicalRegister::new(creg_size);
91 for &(qubit, classical_bit) in &measurements {
92 creg.set(classical_bit, ((sampled_index >> qubit) & 1) as u8);
93 }
94 *counts.entry(creg.bitstring()).or_insert(0) += 1;
95 }
96 } else {
97 for _ in 0..shots {
99 let mut ctx = ExecutionContext::new(circuit.num_qubits(), creg_size);
100 ctx.run(circuit);
101 *counts
102 .entry(ctx.classical_register().bitstring())
103 .or_insert(0) += 1;
104 }
105 }
106
107 SamplingResult {
108 counts,
109 shots,
110 execution_time: ExecutionTime::from_duration(start.elapsed()),
111 }
112}