custom_gate/
custom_gate.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// Shows the use of `Gate::Custom` in implementing the CCC-not gate.
12
13use quantr::{
14    states::{ProductState, Qubit, SuperPosition},
15    Circuit, Gate, Measurement, Printer, QuantrError,
16};
17
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}
44
45// Implements the CCC-not gate.
46fn cccnot(input_state: ProductState) -> Option<SuperPosition> {
47    let state: &[Qubit] = input_state.get_qubits();
48    let state_slice: [Qubit; 4] = [state[0], state[1], state[2], state[3]];
49    // In this format, this guarantees that state_slice has length 4 to the
50    // rust compiler. Useful for the match statement.
51    match state_slice {
52        [Qubit::One, Qubit::One, Qubit::One, Qubit::Zero] => {
53            Some(ProductState::new(&[Qubit::One; 4]).unwrap().into())
54        }
55        [Qubit::One, Qubit::One, Qubit::One, Qubit::One] => Some(
56            ProductState::new(&[Qubit::One, Qubit::One, Qubit::One, Qubit::Zero])
57                .unwrap()
58                .into(),
59        ),
60        _ => return None,
61    }
62}