Skip to content

Commit 837fc35

Browse files
committed
add docstrings (AI generated, reviewed by me)
1 parent e42f5cb commit 837fc35

File tree

1 file changed

+65
-0
lines changed

1 file changed

+65
-0
lines changed

src/lib.rs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use pyo3::prelude::*;
22

3+
/// Graph-state based quantum circuit simulator exposed as the `graphsim` Python module.
34
#[pymodule]
45
mod graphsim {
56
use pyo3::prelude::*;
@@ -15,15 +16,24 @@ mod graphsim {
1516
distr::{Distribution, StandardUniform},
1617
};
1718

19+
/// Index of a node / qubit in the graph.
1820
pub type NodeIdx = usize;
1921

22+
/// Result of a single-qubit measurement.
23+
///
24+
/// Exposed to Python as `graphsim.MeasurementResult`.
2025
#[pyclass]
2126
#[derive(PartialEq, Eq, Debug)]
2227
pub enum MeasurementResult {
28+
/// Eigenvalue +1 outcome.
2329
PlusOne,
30+
/// Eigenvalue −1 outcome.
2431
MinusOne,
2532
}
2633

34+
/// Measurement outcome and the axis that was measured.
35+
///
36+
/// Returned in the values of `peek_measure_set`.
2737
#[pyclass]
2838
pub struct Outcome {
2939
result: MeasurementResult,
@@ -2235,6 +2245,9 @@ mod graphsim {
22352245
}
22362246
}
22372247

2248+
/// Simulator for graph states over a fixed number of qubits.
2249+
///
2250+
/// Use this class from Python to apply gates and perform measurements.
22382251
#[derive(Clone)]
22392252
#[pyclass]
22402253
pub struct GraphSim {
@@ -2464,37 +2477,57 @@ mod graphsim {
24642477

24652478
#[pymethods]
24662479
impl GraphSim {
2480+
/// Create a new simulator with `nodes` qubits, all initialized in the |0⟩ state.
24672481
#[new]
24682482
pub fn new(nodes: usize) -> GraphSim {
24692483
GraphSim {
24702484
nodes: repeat_n(Node::default(), nodes).collect(),
24712485
}
24722486
}
24732487

2488+
/// Apply an X (Pauli-X) gate to the given qubit.
2489+
///
2490+
/// `node` is the index of the qubit.
24742491
fn x(&mut self, node: NodeIdx) {
24752492
self[node].vop = X_GATE * self[node].vop;
24762493
}
24772494

2495+
/// Apply a Y (Pauli-Y) gate to the given qubit.
2496+
///
2497+
/// `node` is the index of the qubit.
24782498
fn y(&mut self, node: NodeIdx) {
24792499
self[node].vop = Y_GATE * self[node].vop;
24802500
}
24812501

2502+
/// Apply a Z (Pauli-Z) gate to the given qubit.
2503+
///
2504+
/// `node` is the index of the qubit.
24822505
fn z(&mut self, node: NodeIdx) {
24832506
self[node].vop = Z_GATE * self[node].vop;
24842507
}
24852508

2509+
/// Apply an H (Hadamard) gate to the given qubit.
2510+
///
2511+
/// `node` is the index of the qubit.
24862512
fn h(&mut self, node: NodeIdx) {
24872513
self[node].vop = H_GATE * self[node].vop;
24882514
}
24892515

2516+
/// Apply an S (phase) gate to the given qubit.
2517+
///
2518+
/// `node` is the index of the qubit.
24902519
fn s(&mut self, node: NodeIdx) {
24912520
self[node].vop = S_GATE * self[node].vop;
24922521
}
24932522

2523+
/// Apply an S† (inverse phase) gate to the given qubit.
2524+
///
2525+
/// `node` is the index of the qubit.
24942526
fn sdag(&mut self, node: NodeIdx) {
24952527
self[node].vop = SDAG_GATE * self[node].vop;
24962528
}
24972529

2530+
/// Apply a controlled-Z (CZ) gate with `control` and `target` qubits.
24982531
fn cz(&mut self, control: NodeIdx, target: NodeIdx) {
24992532
let c_has_t = self[control].len() > 1
25002533
|| (self[control].len() == 1 && self[control].adjacent[0] != target);
@@ -2530,54 +2563,83 @@ mod graphsim {
25302563
self[target].vop = val.2;
25312564
}
25322565

2566+
/// Apply a controlled-X (CX) / CNOT gate with `control` and `target`.
25332567
fn cx(&mut self, control: NodeIdx, target: NodeIdx) {
25342568
self.h(target);
25352569
self.cz(control, target);
25362570
self.h(target);
25372571
}
2572+
2573+
/// Apply an X-controlled X gate (CX in the X basis).
25382574
fn xcx(&mut self, control: NodeIdx, target: NodeIdx) {
25392575
self.h(control);
25402576
self.cx(control, target);
25412577
self.h(control);
25422578
}
2579+
2580+
/// Apply a Y-controlled X gate (control qubit in the Y basis).
25432581
fn ycx(&mut self, control: NodeIdx, target: NodeIdx) {
25442582
self.sdag(control);
25452583
self.xcx(control, target);
25462584
self.s(control);
25472585
}
2586+
2587+
/// Apply an X-controlled Z gate (target in X basis).
25482588
fn xcz(&mut self, control: NodeIdx, target: NodeIdx) {
25492589
self.cx(target, control);
25502590
}
2591+
2592+
/// Apply a Y-controlled Z gate (target in Y basis).
25512593
fn ycz(&mut self, control: NodeIdx, target: NodeIdx) {
25522594
self.cy(target, control);
25532595
}
2596+
2597+
/// Apply a controlled-Y (CY) gate with `control` and `target`.
25542598
fn cy(&mut self, control: NodeIdx, target: NodeIdx) {
25552599
self.sdag(target);
25562600
self.cx(control, target);
25572601
self.s(target);
25582602
}
2603+
2604+
/// Apply an X-controlled Y gate (control in X basis).
25592605
fn xcy(&mut self, control: NodeIdx, target: NodeIdx) {
25602606
self.ycx(target, control);
25612607
}
2608+
2609+
/// Apply a Y-controlled Y gate (both in Y basis).
25622610
fn ycy(&mut self, control: NodeIdx, target: NodeIdx) {
25632611
self.sdag(target);
25642612
self.ycx(control, target);
25652613
self.s(target);
25662614
}
25672615

2616+
/// Perform a projective measurement of `qubit` in the X basis.
2617+
///
2618+
/// Returns `MeasurementResult.PlusOne` or `MeasurementResult.MinusOne`.
25682619
fn measure_x(&mut self, qubit: NodeIdx) -> MeasurementResult {
25692620
let (res, _) = self.measure(qubit, Axis::X);
25702621
res
25712622
}
2623+
2624+
/// Perform a projective measurement of `qubit` in the Y basis.
2625+
///
2626+
/// Returns `MeasurementResult.PlusOne` or `MeasurementResult.MinusOne`.
25722627
fn measure_y(&mut self, qubit: NodeIdx) -> MeasurementResult {
25732628
let (res, _) = self.measure(qubit, Axis::Y);
25742629
res
25752630
}
2631+
2632+
/// Perform a projective measurement of `qubit` in the Z basis.
2633+
///
2634+
/// Returns `MeasurementResult.PlusOne` or `MeasurementResult.MinusOne`.
25762635
fn measure_z(&mut self, qubit: NodeIdx) -> MeasurementResult {
25772636
let (res, _) = self.measure(qubit, Axis::Z);
25782637
res
25792638
}
25802639

2640+
/// Return the set of qubits that are entangled with `qubit`.
2641+
///
2642+
/// This follows adjacency in the underlying graph.
25812643
fn get_entangled_group(&self, qubit: NodeIdx) -> HashSet<NodeIdx> {
25822644
let mut queue = VecDeque::new();
25832645
let mut part = HashSet::new();
@@ -2595,6 +2657,9 @@ mod graphsim {
25952657
part
25962658
}
25972659

2660+
/// Simulate measurements on a set of `qubits` without modifying the real state.
2661+
///
2662+
/// Returns a map from qubit index to `Outcome` (result and axis used).
25982663
fn peek_measure_set(
25992664
&self,
26002665
qubits: HashSet<NodeIdx>,

0 commit comments

Comments
 (0)