microsoft/qdk
Publicmirrored fromhttps://github.com/microsoft/qdkAvailable
samples/algorithms/MajoranaQubits/src/GateSet.qs
88lines · modecode
| 1 | /// A set of gates built upon the custom measurements |
| 2 | /// provided by the hardware provider. |
| 3 | /// |
| 4 | /// Source: |
| 5 | /// [1] Surface code compilation via edge-disjoint paths |
| 6 | /// https://arxiv.org/pdf/2110.11493 |
| 7 | |
| 8 | /// Apply a CNOT gate to the given qubits. |
| 9 | /// Source: [1] Figure 3. |
| 10 | operation CNOT(control : Qubit, target : Qubit) : Unit { |
| 11 | // Prepare an ancilla qubit in the |+⟩ state. |
| 12 | use ancilla = Qubit(); |
| 13 | PrepareX(ancilla); |
| 14 | |
| 15 | let a = Mzz(control, ancilla); |
| 16 | let b = Mxx(ancilla, target); |
| 17 | let c = Mz(ancilla); |
| 18 | Reset(ancilla); |
| 19 | |
| 20 | if b == One { |
| 21 | Z(control); |
| 22 | } |
| 23 | |
| 24 | if a != c { |
| 25 | X(target); |
| 26 | } |
| 27 | } |
| 28 | |
| 29 | |
| 30 | /// Prepare a qubit in the |+⟩ state. |
| 31 | operation PrepareX(q : Qubit) : Unit { |
| 32 | if Mx(q) == One { |
| 33 | Z(q); |
| 34 | } |
| 35 | } |
| 36 | |
| 37 | /// Prepare a qubit in the |0⟩ state. |
| 38 | operation PrepareZ(q : Qubit) : Unit { |
| 39 | if Mz(q) == One { |
| 40 | X(q); |
| 41 | } |
| 42 | } |
| 43 | |
| 44 | /// Prepare a Bell Pair. |
| 45 | /// Source: [1] Figure 18a. |
| 46 | operation BellPair(q1 : Qubit, q2 : Qubit) : Unit { |
| 47 | // Collapse the qubits onto the Pauli-Z basis. |
| 48 | Mz(q1); |
| 49 | Mz(q2); |
| 50 | |
| 51 | // If they are not aligned in the Pauli-X basis, phase flip one of them. |
| 52 | if Mxx(q1, q2) == One { |
| 53 | Z(q2); |
| 54 | } |
| 55 | } |
| 56 | |
| 57 | /// Measure a Bell Pair. |
| 58 | /// Source: [1] Figure 18b. |
| 59 | /// Below is a map showing how the Bell states map to the Result pairs: |
| 60 | /// |𝚽⁺⟩ -> (Zero, Zero) |
| 61 | /// |𝚿⁺⟩ -> (Zero, One) |
| 62 | /// |𝚽⁻⟩ -> (One, Zero) |
| 63 | /// |𝚿⁻⟩ -> (One, One) |
| 64 | operation BellMeasurement(q1 : Qubit, q2 : Qubit) : (Result, Result) { |
| 65 | let z = Mzz(q1, q2); |
| 66 | let x = Mxx(q1, q2); |
| 67 | (x, z) |
| 68 | } |
| 69 | |
| 70 | /// User friendly wrapper around the Mx hardware gate. |
| 71 | operation Mx(q : Qubit) : Result { |
| 72 | HardwareIntrinsics.__quantum__qis__mx__body(q) |
| 73 | } |
| 74 | |
| 75 | /// User friendly wrapper around the Mz hardware gate. |
| 76 | operation Mz(q : Qubit) : Result { |
| 77 | HardwareIntrinsics.__quantum__qis__mz__body(q) |
| 78 | } |
| 79 | |
| 80 | /// User friendly wrapper around the Mxx hardware gate. |
| 81 | operation Mxx(q1 : Qubit, q2 : Qubit) : Result { |
| 82 | HardwareIntrinsics.__quantum__qis__mxx__body(q1, q2) |
| 83 | } |
| 84 | |
| 85 | /// User friendly wrapper around the Mzz hardware gate. |
| 86 | operation Mzz(q1 : Qubit, q2 : Qubit) : Result { |
| 87 | HardwareIntrinsics.__quantum__qis__mzz__body(q1, q2) |
| 88 | } |
| 89 | |