microsoft/qdk
Publicmirrored from https://github.com/microsoft/qdkAvailable
source/paulimer/src/operations.rs
98lines · modecode
| 1 | // Copyright (c) Microsoft Corporation. |
| 2 | // Licensed under the MIT License. |
| 3 | |
| 4 | use num_derive::{FromPrimitive, ToPrimitive}; |
| 5 | |
| 6 | #[derive(FromPrimitive, ToPrimitive, Clone, Copy, Debug)] |
| 7 | pub enum UnitaryOp { |
| 8 | I, |
| 9 | X, |
| 10 | Y, |
| 11 | Z, |
| 12 | SqrtX, |
| 13 | SqrtXInv, |
| 14 | SqrtY, |
| 15 | SqrtYInv, |
| 16 | SqrtZ, |
| 17 | SqrtZInv, |
| 18 | Hadamard, |
| 19 | Swap, |
| 20 | ControlledX, |
| 21 | ControlledZ, |
| 22 | PrepareBell, |
| 23 | } |
| 24 | |
| 25 | #[macro_export] |
| 26 | macro_rules! assert_1q_gate { |
| 27 | ($x: expr) => { |
| 28 | debug_assert_eq!($x.len(), 1); |
| 29 | }; |
| 30 | } |
| 31 | |
| 32 | #[macro_export] |
| 33 | macro_rules! assert_2q_gate { |
| 34 | ($x: expr) => { |
| 35 | debug_assert_eq!($x.len(), 2); |
| 36 | debug_assert!($x[0] != $x[1]); |
| 37 | }; |
| 38 | } |
| 39 | |
| 40 | pub type Operations = Vec<(UnitaryOp, Vec<usize>)>; |
| 41 | |
| 42 | #[must_use] |
| 43 | pub fn qubit_operations(qubit_count: usize, qubit_op: UnitaryOp) -> Operations { |
| 44 | let mut res = Vec::new(); |
| 45 | for qubit in 0..qubit_count { |
| 46 | res.push((qubit_op, vec![qubit])); |
| 47 | } |
| 48 | res |
| 49 | } |
| 50 | |
| 51 | #[must_use] |
| 52 | pub fn asymmetric_two_qubit_operations(qubit_count: usize, qubit_op: UnitaryOp) -> Operations { |
| 53 | let mut res = Vec::new(); |
| 54 | for qubit1 in 0..qubit_count { |
| 55 | for qubit2 in 0..qubit_count { |
| 56 | if qubit1 != qubit2 { |
| 57 | res.push((qubit_op, vec![qubit1, qubit2])); |
| 58 | } |
| 59 | } |
| 60 | } |
| 61 | res |
| 62 | } |
| 63 | |
| 64 | #[must_use] |
| 65 | pub fn symmetric_two_qubit_operations(qubit_count: usize, qubit_op: UnitaryOp) -> Operations { |
| 66 | let mut res = Vec::new(); |
| 67 | for qubit1 in 0..qubit_count { |
| 68 | for qubit2 in 0..qubit1 { |
| 69 | let gen = (qubit_op, vec![qubit1, qubit2]); |
| 70 | res.push(gen); |
| 71 | } |
| 72 | } |
| 73 | res |
| 74 | } |
| 75 | |
| 76 | #[must_use] |
| 77 | pub fn diagonal_operations(qubit_count: usize) -> Operations { |
| 78 | use UnitaryOp::{ControlledZ, SqrtZ}; |
| 79 | let mut res = Vec::new(); |
| 80 | res.append(&mut symmetric_two_qubit_operations( |
| 81 | qubit_count, |
| 82 | ControlledZ, |
| 83 | )); |
| 84 | res.append(&mut qubit_operations(qubit_count, SqrtZ)); |
| 85 | res |
| 86 | } |
| 87 | |
| 88 | #[must_use] |
| 89 | pub fn css_operations(qubit_count: usize) -> Operations { |
| 90 | use UnitaryOp::{ControlledX, Swap}; |
| 91 | let mut res = Vec::new(); |
| 92 | res.append(&mut symmetric_two_qubit_operations(qubit_count, Swap)); |
| 93 | res.append(&mut asymmetric_two_qubit_operations( |
| 94 | qubit_count, |
| 95 | ControlledX, |
| 96 | )); |
| 97 | res |
| 98 | } |