generalised_control_not_gate/
generalised_control_not_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//! This example is a copy of `example/custom_gate.rs`, but instead uses a custom function that
12//! showcases a controlled not gate which generalises the number of control nodes.
13
14use quantr::{
15    states::{ProductState, Qubit, SuperPosition},
16    Circuit, Gate, Measurement, Printer, QuantrError,
17};
18
19const CIRCUIT_SIZE: usize = 6;
20
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}
51
52// Implements a multi-controlled Not gate.
53fn multicnot<const NUM_CONTROL: usize>(input_state: ProductState) -> Option<SuperPosition> {
54    let mut copy_state = input_state;
55    if copy_state.get_qubits() == [Qubit::One; NUM_CONTROL] {
56        copy_state.get_mut_qubits()[NUM_CONTROL - 1] = Qubit::Zero;
57        return Some(copy_state.into());
58    } else if copy_state.get_qubits() == {
59        let mut temp = [Qubit::One; NUM_CONTROL];
60        temp[NUM_CONTROL - 1] = Qubit::Zero;
61        temp
62    } {
63        copy_state.get_mut_qubits()[NUM_CONTROL - 1] = Qubit::One;
64        return Some(copy_state.into());
65    } else {
66        None
67    }
68}