From 0cbf87a885976fed4800727b3f3426bd7ffbac6e Mon Sep 17 00:00:00 2001 From: Oscar Puente <156957451+orpuente-MS@users.noreply.github.com> Date: Thu, 31 Oct 2024 13:55:30 -0700 Subject: [PATCH 01/24] add custom measurements sample --- samples/language/CustomMeasurements.qs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 samples/language/CustomMeasurements.qs diff --git a/samples/language/CustomMeasurements.qs b/samples/language/CustomMeasurements.qs new file mode 100644 index 0000000000..c5831c5e6c --- /dev/null +++ b/samples/language/CustomMeasurements.qs @@ -0,0 +1,24 @@ +// # Sample +// Custom Operations +// +// # Description +// The @Measurement attribute in Q# allows you to define custom measurements +// that are lowered to QIR in the same way the `M` measurement in the standard +// library is lowered. That means an `"irreversible"` attribute is added to +// the callable declaration and the output results are moved to the paramaters +// and treated as result registers. +// +// # Who is this for? +// The target audience are library authors targeting specific hardware. + +/// Try running the command `Q#: Get QIR for the current Q# program` +/// in VS-Code's Command Palette. +operation Main() : Result { + use q = Qubit(); + Mx(q) +} + +@Measurement() +operation Mx(q: Qubit) : Result { + body intrinsic; +} From 8d57c34bf6dbae42f6fda7991b49bb2806d83c22 Mon Sep 17 00:00:00 2001 From: Oscar Puente <156957451+orpuente-MS@users.noreply.github.com> Date: Mon, 18 Nov 2024 09:21:20 -0800 Subject: [PATCH 02/24] add custom operations sample --- samples/algorithms/MajoranaQubits.qs | 93 ++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 samples/algorithms/MajoranaQubits.qs diff --git a/samples/algorithms/MajoranaQubits.qs b/samples/algorithms/MajoranaQubits.qs new file mode 100644 index 0000000000..e51e7b8c52 --- /dev/null +++ b/samples/algorithms/MajoranaQubits.qs @@ -0,0 +1,93 @@ +/// # Sample +/// Majorana Qubits +/// +/// # Description +/// In hardware providing majorana qubits, common quantum operations +/// are implemented using measurements and Pauli corrections. This +/// sample shows a hypotetical hardware provider exposing some custom +/// gates to Q# and a small library built on top of it. + +namespace Main { + /// Sample program using gates for custom hardware provider. + operation Main() : (Result, Result) { + use qs = Qubit[2]; + GateSet.BellPair(qs[0], qs[1]); + GateSet.BellMeasurement(qs[0], qs[1]) + } +} + +/// A set of gates built upon the custom measurements +/// provided by the hardware provider. +/// +/// Source: +/// [1] Surface code compilation via edge-disjoint paths +/// https://arxiv.org/pdf/2110.11493 +namespace GateSet { + /// Apply a CNOT gate to the given qubits. + /// Source: [1] Figure 3. + operation CNOT(control: Qubit, target: Qubit) : Unit { + use ancilla = Qubit(); + let a = HardwareProvider.Mzz(control, target); + let b = HardwareProvider.Mxx(target, ancilla); + let c = HardwareProvider.Mx(target); + if b == One { + HardwareProvider.Z(control); + } + if [a, c] == [One, One] { + HardwareProvider.X(ancilla); + } + } + + /// Prepare a Bell Pair. + /// Source: [1] Figure 18a. + operation BellPair(q1: Qubit, q2: Qubit) : Unit { + // Bring the qubits to their ground state. + HardwareProvider.Mz(q1); + HardwareProvider.Mz(q2); + + // Bell Pair preparation + if HardwareProvider.Mxx(q1, q2) == One { + HardwareProvider.Z(q2); + } + } + + /// Measure a Bell Pair. + /// Source: [1] Figure 18b. + operation BellMeasurement(q1: Qubit, q2: Qubit) : (Result, Result) { + let z = HardwareProvider.Mzz(q1, q2); + let x = HardwareProvider.Mxx(q1, q2); + (x, z) + } +} + +/// A set of custom measurements exposed from a hardware +/// provider using Majorana Qubits. +namespace HardwareProvider { + operation X(q: Qubit) : Unit { + body intrinsic; + } + + operation Z(q: Qubit) : Unit { + body intrinsic; + } + + @Measurement() + operation Mx(q: Qubit) : Result { + body intrinsic; + } + + @Measurement() + operation Mz(q: Qubit) : Result { + body intrinsic; + } + + @Measurement() + operation Mxx(q1: Qubit, q2: Qubit) : Result { + body intrinsic; + } + + @Measurement() + operation Mzz(q1: Qubit, q2: Qubit) : Result { + body intrinsic; + } +} From c0f9372ef39f21ebfad1371fed7d143b18ced1a5 Mon Sep 17 00:00:00 2001 From: Oscar Puente <156957451+orpuente-MS@users.noreply.github.com> Date: Mon, 18 Nov 2024 09:57:50 -0800 Subject: [PATCH 03/24] fix unit tests --- samples/algorithms/MajoranaQubits.qs | 23 ++++++++++++++++------- samples/language/CustomMeasurements.qs | 5 ++++- samples_test/src/tests/algorithms.rs | 2 ++ samples_test/src/tests/language.rs | 2 ++ 4 files changed, 24 insertions(+), 8 deletions(-) diff --git a/samples/algorithms/MajoranaQubits.qs b/samples/algorithms/MajoranaQubits.qs index e51e7b8c52..48a5506bc6 100644 --- a/samples/algorithms/MajoranaQubits.qs +++ b/samples/algorithms/MajoranaQubits.qs @@ -12,7 +12,9 @@ namespace Main { operation Main() : (Result, Result) { use qs = Qubit[2]; GateSet.BellPair(qs[0], qs[1]); - GateSet.BellMeasurement(qs[0], qs[1]) + let res = GateSet.BellMeasurement(qs[0], qs[1]); + ResetAll(qs); + res } } @@ -63,31 +65,38 @@ namespace GateSet { /// A set of custom measurements exposed from a hardware /// provider using Majorana Qubits. namespace HardwareProvider { + @SimulatableIntrinsic() operation X(q: Qubit) : Unit { - body intrinsic; + Std.Intrinsic.X(q); } + @SimulatableIntrinsic() operation Z(q: Qubit) : Unit { - body intrinsic; + Std.Intrinsic.Z(q); } @Measurement() + @SimulatableIntrinsic() operation Mx(q: Qubit) : Result { - body intrinsic; + H(q); + M(q) } @Measurement() + @SimulatableIntrinsic() operation Mz(q: Qubit) : Result { - body intrinsic; + M(q) } @Measurement() + @SimulatableIntrinsic() operation Mxx(q1: Qubit, q2: Qubit) : Result { - body intrinsic; + Std.Intrinsic.Measure([PauliX, PauliX], [q1, q2]) } @Measurement() + @SimulatableIntrinsic() operation Mzz(q1: Qubit, q2: Qubit) : Result { - body intrinsic; + Std.Intrinsic.Measure([PauliZ, PauliZ], [q1, q2]) } } diff --git a/samples/language/CustomMeasurements.qs b/samples/language/CustomMeasurements.qs index c5831c5e6c..b60c3537ba 100644 --- a/samples/language/CustomMeasurements.qs +++ b/samples/language/CustomMeasurements.qs @@ -15,10 +15,13 @@ /// in VS-Code's Command Palette. operation Main() : Result { use q = Qubit(); + H(q); Mx(q) } @Measurement() +@SimulatableIntrinsic() operation Mx(q: Qubit) : Result { - body intrinsic; + H(q); + M(q) } diff --git a/samples_test/src/tests/algorithms.rs b/samples_test/src/tests/algorithms.rs index f2d596881a..fc4f050df7 100644 --- a/samples_test/src/tests/algorithms.rs +++ b/samples_test/src/tests/algorithms.rs @@ -178,6 +178,8 @@ pub const JOINTMEASUREMENT_EXPECT_DEBUG: Expect = expect![[r#" STATE: |11⟩: 1.0000+0.0000𝑖 (Zero, [One, One])"#]]; +pub const MAJORANAQUBITS_EXPECT: Expect = expect!["(Zero, Zero)"]; +pub const MAJORANAQUBITS_EXPECT_DEBUG: Expect = expect!["(Zero, Zero)"]; pub const MEASUREMENT_EXPECT: Expect = expect!["(Zero, [Zero, Zero])"]; pub const MEASUREMENT_EXPECT_DEBUG: Expect = expect!["(Zero, [Zero, Zero])"]; pub const PHASEFLIPCODE_EXPECT: Expect = expect![[r#" diff --git a/samples_test/src/tests/language.rs b/samples_test/src/tests/language.rs index 4b51b10169..61b7137eca 100644 --- a/samples_test/src/tests/language.rs +++ b/samples_test/src/tests/language.rs @@ -144,6 +144,8 @@ pub const COPYANDUPDATEOPERATOR_EXPECT_DEBUG: Expect = expect![[r#" Updated array: [10, 11, 100, 13] Updated array: [10, 100, 12, 200] ()"#]]; +pub const CUSTOMMEASUREMENTS_EXPECT: Expect = expect!["Zero"]; +pub const CUSTOMMEASUREMENTS_EXPECT_DEBUG: Expect = expect!["Zero"]; pub const DATATYPES_EXPECT: Expect = expect![[r#" Binary BigInt: 42 Octal BigInt: 42 From 6574fa6c1731a005a966f06cf547ba80e22b5e1a Mon Sep 17 00:00:00 2001 From: Oscar Puente <156957451+orpuente-MS@users.noreply.github.com> Date: Mon, 18 Nov 2024 10:06:12 -0800 Subject: [PATCH 04/24] fix formatting --- samples/algorithms/MajoranaQubits.qs | 18 +++++++++--------- samples/language/CustomMeasurements.qs | 12 ++++++------ 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/samples/algorithms/MajoranaQubits.qs b/samples/algorithms/MajoranaQubits.qs index 48a5506bc6..aee95903e3 100644 --- a/samples/algorithms/MajoranaQubits.qs +++ b/samples/algorithms/MajoranaQubits.qs @@ -27,7 +27,7 @@ namespace Main { namespace GateSet { /// Apply a CNOT gate to the given qubits. /// Source: [1] Figure 3. - operation CNOT(control: Qubit, target: Qubit) : Unit { + operation CNOT(control : Qubit, target : Qubit) : Unit { use ancilla = Qubit(); let a = HardwareProvider.Mzz(control, target); let b = HardwareProvider.Mxx(target, ancilla); @@ -42,7 +42,7 @@ namespace GateSet { /// Prepare a Bell Pair. /// Source: [1] Figure 18a. - operation BellPair(q1: Qubit, q2: Qubit) : Unit { + operation BellPair(q1 : Qubit, q2 : Qubit) : Unit { // Bring the qubits to their ground state. HardwareProvider.Mz(q1); HardwareProvider.Mz(q2); @@ -55,7 +55,7 @@ namespace GateSet { /// Measure a Bell Pair. /// Source: [1] Figure 18b. - operation BellMeasurement(q1: Qubit, q2: Qubit) : (Result, Result) { + operation BellMeasurement(q1 : Qubit, q2 : Qubit) : (Result, Result) { let z = HardwareProvider.Mzz(q1, q2); let x = HardwareProvider.Mxx(q1, q2); (x, z) @@ -66,37 +66,37 @@ namespace GateSet { /// provider using Majorana Qubits. namespace HardwareProvider { @SimulatableIntrinsic() - operation X(q: Qubit) : Unit { + operation X(q : Qubit) : Unit { Std.Intrinsic.X(q); } @SimulatableIntrinsic() - operation Z(q: Qubit) : Unit { + operation Z(q : Qubit) : Unit { Std.Intrinsic.Z(q); } @Measurement() @SimulatableIntrinsic() - operation Mx(q: Qubit) : Result { + operation Mx(q : Qubit) : Result { H(q); M(q) } @Measurement() @SimulatableIntrinsic() - operation Mz(q: Qubit) : Result { + operation Mz(q : Qubit) : Result { M(q) } @Measurement() @SimulatableIntrinsic() - operation Mxx(q1: Qubit, q2: Qubit) : Result { + operation Mxx(q1 : Qubit, q2 : Qubit) : Result { Std.Intrinsic.Measure([PauliX, PauliX], [q1, q2]) } @Measurement() @SimulatableIntrinsic() - operation Mzz(q1: Qubit, q2: Qubit) : Result { + operation Mzz(q1 : Qubit, q2 : Qubit) : Result { Std.Intrinsic.Measure([PauliZ, PauliZ], [q1, q2]) } } diff --git a/samples/language/CustomMeasurements.qs b/samples/language/CustomMeasurements.qs index b60c3537ba..8c7104e721 100644 --- a/samples/language/CustomMeasurements.qs +++ b/samples/language/CustomMeasurements.qs @@ -14,14 +14,14 @@ /// Try running the command `Q#: Get QIR for the current Q# program` /// in VS-Code's Command Palette. operation Main() : Result { - use q = Qubit(); - H(q); - Mx(q) + use q = Qubit(); + H(q); + Mx(q) } @Measurement() @SimulatableIntrinsic() -operation Mx(q: Qubit) : Result { - H(q); - M(q) +operation Mx(q : Qubit) : Result { + H(q); + M(q) } From fe56c36f5a4cf2dfe0e47d069e974badaaafa6c0 Mon Sep 17 00:00:00 2001 From: Oscar Puente <156957451+orpuente-MS@users.noreply.github.com> Date: Mon, 18 Nov 2024 13:00:26 -0800 Subject: [PATCH 05/24] use QIR compliant names --- samples/algorithms/MajoranaQubits.qs | 60 +++++++++++++++----------- samples/language/CustomMeasurements.qs | 4 +- 2 files changed, 37 insertions(+), 27 deletions(-) diff --git a/samples/algorithms/MajoranaQubits.qs b/samples/algorithms/MajoranaQubits.qs index aee95903e3..a48637a53c 100644 --- a/samples/algorithms/MajoranaQubits.qs +++ b/samples/algorithms/MajoranaQubits.qs @@ -29,14 +29,14 @@ namespace GateSet { /// Source: [1] Figure 3. operation CNOT(control : Qubit, target : Qubit) : Unit { use ancilla = Qubit(); - let a = HardwareProvider.Mzz(control, target); - let b = HardwareProvider.Mxx(target, ancilla); - let c = HardwareProvider.Mx(target); + let a = Mzz(control, target); + let b = Mxx(target, ancilla); + let c = Mx(target); if b == One { - HardwareProvider.Z(control); + Z(control); } if [a, c] == [One, One] { - HardwareProvider.X(ancilla); + X(ancilla); } } @@ -44,59 +44,69 @@ namespace GateSet { /// Source: [1] Figure 18a. operation BellPair(q1 : Qubit, q2 : Qubit) : Unit { // Bring the qubits to their ground state. - HardwareProvider.Mz(q1); - HardwareProvider.Mz(q2); + Mz(q1); + Mz(q2); // Bell Pair preparation - if HardwareProvider.Mxx(q1, q2) == One { - HardwareProvider.Z(q2); + if Mxx(q1, q2) == One { + Z(q2); } } /// Measure a Bell Pair. /// Source: [1] Figure 18b. operation BellMeasurement(q1 : Qubit, q2 : Qubit) : (Result, Result) { - let z = HardwareProvider.Mzz(q1, q2); - let x = HardwareProvider.Mxx(q1, q2); + let z = Mzz(q1, q2); + let x = Mxx(q1, q2); (x, z) } -} -/// A set of custom measurements exposed from a hardware -/// provider using Majorana Qubits. -namespace HardwareProvider { - @SimulatableIntrinsic() - operation X(q : Qubit) : Unit { - Std.Intrinsic.X(q); + /// User friendly wrapper around the Mx hardware gate. + operation Mx(q : Qubit) : Result { + HardwareProvider.__quantum__qis__mx__body(q) } - @SimulatableIntrinsic() - operation Z(q : Qubit) : Unit { - Std.Intrinsic.Z(q); + /// User friendly wrapper around the Mz hardware gate. + operation Mz(q : Qubit) : Result { + HardwareProvider.__quantum__qis__mz__body(q) + } + + /// User friendly wrapper around the Mxx hardware gate. + operation Mxx(q1 : Qubit, q2 : Qubit) : Result { + HardwareProvider.__quantum__qis__mxx__body(q1, q2) } + /// User friendly wrapper around the Mzz hardware gate. + operation Mzz(q1 : Qubit, q2 : Qubit) : Result { + HardwareProvider.__quantum__qis__mzz__body(q1, q2) + } +} + +/// A set of custom measurements exposed from a hardware +/// provider using Majorana Qubits. +namespace HardwareProvider { @Measurement() @SimulatableIntrinsic() - operation Mx(q : Qubit) : Result { + operation __quantum__qis__mx__body(q : Qubit) : Result { H(q); M(q) } @Measurement() @SimulatableIntrinsic() - operation Mz(q : Qubit) : Result { + operation __quantum__qis__mz__body(q : Qubit) : Result { M(q) } @Measurement() @SimulatableIntrinsic() - operation Mxx(q1 : Qubit, q2 : Qubit) : Result { + operation __quantum__qis__mxx__body(q1 : Qubit, q2 : Qubit) : Result { Std.Intrinsic.Measure([PauliX, PauliX], [q1, q2]) } @Measurement() @SimulatableIntrinsic() - operation Mzz(q1 : Qubit, q2 : Qubit) : Result { + operation __quantum__qis__mzz__body(q1 : Qubit, q2 : Qubit) : Result { Std.Intrinsic.Measure([PauliZ, PauliZ], [q1, q2]) } } diff --git a/samples/language/CustomMeasurements.qs b/samples/language/CustomMeasurements.qs index 8c7104e721..8addd2d654 100644 --- a/samples/language/CustomMeasurements.qs +++ b/samples/language/CustomMeasurements.qs @@ -16,12 +16,12 @@ operation Main() : Result { use q = Qubit(); H(q); - Mx(q) + __quantum__qis__mx__body(q) } @Measurement() @SimulatableIntrinsic() -operation Mx(q : Qubit) : Result { +operation __quantum__qis__mx__body(q : Qubit) : Result { H(q); M(q) } From 5800eca5e0038c237abbfc84ccd0ed2643ebbe6a Mon Sep 17 00:00:00 2001 From: Oscar Puente <156957451+orpuente-MS@users.noreply.github.com> Date: Mon, 18 Nov 2024 15:48:33 -0800 Subject: [PATCH 06/24] write the sample as a multifile project --- samples/algorithms/MajoranaQubits.qs | 112 ------------------ samples/algorithms/MajoranaQubits/qsharp.json | 12 ++ .../algorithms/MajoranaQubits/src/GateSet.qs | 62 ++++++++++ .../MajoranaQubits/src/HardwareIntrinsics.qs | 27 +++++ samples/algorithms/MajoranaQubits/src/Main.qs | 17 +++ samples_test/src/tests/algorithms.rs | 2 - 6 files changed, 118 insertions(+), 114 deletions(-) delete mode 100644 samples/algorithms/MajoranaQubits.qs create mode 100644 samples/algorithms/MajoranaQubits/qsharp.json create mode 100644 samples/algorithms/MajoranaQubits/src/GateSet.qs create mode 100644 samples/algorithms/MajoranaQubits/src/HardwareIntrinsics.qs create mode 100644 samples/algorithms/MajoranaQubits/src/Main.qs diff --git a/samples/algorithms/MajoranaQubits.qs b/samples/algorithms/MajoranaQubits.qs deleted file mode 100644 index a48637a53c..0000000000 --- a/samples/algorithms/MajoranaQubits.qs +++ /dev/null @@ -1,112 +0,0 @@ -/// # Sample -/// Majorana Qubits -/// -/// # Description -/// In hardware providing majorana qubits, common quantum operations -/// are implemented using measurements and Pauli corrections. This -/// sample shows a hypotetical hardware provider exposing some custom -/// gates to Q# and a small library built on top of it. - -namespace Main { - /// Sample program using gates for custom hardware provider. - operation Main() : (Result, Result) { - use qs = Qubit[2]; - GateSet.BellPair(qs[0], qs[1]); - let res = GateSet.BellMeasurement(qs[0], qs[1]); - ResetAll(qs); - res - } -} - -/// A set of gates built upon the custom measurements -/// provided by the hardware provider. -/// -/// Source: -/// [1] Surface code compilation via edge-disjoint paths -/// https://arxiv.org/pdf/2110.11493 -namespace GateSet { - /// Apply a CNOT gate to the given qubits. - /// Source: [1] Figure 3. - operation CNOT(control : Qubit, target : Qubit) : Unit { - use ancilla = Qubit(); - let a = Mzz(control, target); - let b = Mxx(target, ancilla); - let c = Mx(target); - if b == One { - Z(control); - } - if [a, c] == [One, One] { - X(ancilla); - } - } - - /// Prepare a Bell Pair. - /// Source: [1] Figure 18a. - operation BellPair(q1 : Qubit, q2 : Qubit) : Unit { - // Bring the qubits to their ground state. - Mz(q1); - Mz(q2); - - // Bell Pair preparation - if Mxx(q1, q2) == One { - Z(q2); - } - } - - /// Measure a Bell Pair. - /// Source: [1] Figure 18b. - operation BellMeasurement(q1 : Qubit, q2 : Qubit) : (Result, Result) { - let z = Mzz(q1, q2); - let x = Mxx(q1, q2); - (x, z) - } - - /// User friendly wrapper around the Mx hardware gate. - operation Mx(q : Qubit) : Result { - HardwareProvider.__quantum__qis__mx__body(q) - } - - /// User friendly wrapper around the Mz hardware gate. - operation Mz(q : Qubit) : Result { - HardwareProvider.__quantum__qis__mz__body(q) - } - - /// User friendly wrapper around the Mxx hardware gate. - operation Mxx(q1 : Qubit, q2 : Qubit) : Result { - HardwareProvider.__quantum__qis__mxx__body(q1, q2) - } - - /// User friendly wrapper around the Mzz hardware gate. - operation Mzz(q1 : Qubit, q2 : Qubit) : Result { - HardwareProvider.__quantum__qis__mzz__body(q1, q2) - } -} - -/// A set of custom measurements exposed from a hardware -/// provider using Majorana Qubits. -namespace HardwareProvider { - @Measurement() - @SimulatableIntrinsic() - operation __quantum__qis__mx__body(q : Qubit) : Result { - H(q); - M(q) - } - - @Measurement() - @SimulatableIntrinsic() - operation __quantum__qis__mz__body(q : Qubit) : Result { - M(q) - } - - @Measurement() - @SimulatableIntrinsic() - operation __quantum__qis__mxx__body(q1 : Qubit, q2 : Qubit) : Result { - Std.Intrinsic.Measure([PauliX, PauliX], [q1, q2]) - } - - @Measurement() - @SimulatableIntrinsic() - operation __quantum__qis__mzz__body(q1 : Qubit, q2 : Qubit) : Result { - Std.Intrinsic.Measure([PauliZ, PauliZ], [q1, q2]) - } -} diff --git a/samples/algorithms/MajoranaQubits/qsharp.json b/samples/algorithms/MajoranaQubits/qsharp.json new file mode 100644 index 0000000000..9ccae959e3 --- /dev/null +++ b/samples/algorithms/MajoranaQubits/qsharp.json @@ -0,0 +1,12 @@ +{ + "lints": [ + { + "lint": "deprecatedWithOperator", + "level": "error" + }, + { + "lint": "deprecatedDoubleColonOperator", + "level": "error" + } + ] +} diff --git a/samples/algorithms/MajoranaQubits/src/GateSet.qs b/samples/algorithms/MajoranaQubits/src/GateSet.qs new file mode 100644 index 0000000000..11cd6dd110 --- /dev/null +++ b/samples/algorithms/MajoranaQubits/src/GateSet.qs @@ -0,0 +1,62 @@ +/// A set of gates built upon the custom measurements +/// provided by the hardware provider. +/// +/// Source: +/// [1] Surface code compilation via edge-disjoint paths +/// https://arxiv.org/pdf/2110.11493 + +/// Apply a CNOT gate to the given qubits. +/// Source: [1] Figure 3. +operation CNOT(control : Qubit, target : Qubit) : Unit { + use ancilla = Qubit(); + let a = Mzz(control, target); + let b = Mxx(target, ancilla); + let c = Mx(target); + if b == One { + Z(control); + } + if [a, c] == [One, One] { + X(ancilla); + } +} + +/// Prepare a Bell Pair. +/// Source: [1] Figure 18a. +operation BellPair(q1 : Qubit, q2 : Qubit) : Unit { + // Bring the qubits to their ground state. + Mz(q1); + Mz(q2); + + // Bell Pair preparation + if Mxx(q1, q2) == One { + Z(q2); + } +} + +/// Measure a Bell Pair. +/// Source: [1] Figure 18b. +operation BellMeasurement(q1 : Qubit, q2 : Qubit) : (Result, Result) { + let z = Mzz(q1, q2); + let x = Mxx(q1, q2); + (x, z) +} + +/// User friendly wrapper around the Mx hardware gate. +operation Mx(q : Qubit) : Result { + HardwareIntrinsics.__quantum__qis__mx__body(q) +} + +/// User friendly wrapper around the Mz hardware gate. +operation Mz(q : Qubit) : Result { + HardwareIntrinsics.__quantum__qis__mz__body(q) +} + +/// User friendly wrapper around the Mxx hardware gate. +operation Mxx(q1 : Qubit, q2 : Qubit) : Result { + HardwareIntrinsics.__quantum__qis__mxx__body(q1, q2) +} + +/// User friendly wrapper around the Mzz hardware gate. +operation Mzz(q1 : Qubit, q2 : Qubit) : Result { + HardwareIntrinsics.__quantum__qis__mzz__body(q1, q2) +} diff --git a/samples/algorithms/MajoranaQubits/src/HardwareIntrinsics.qs b/samples/algorithms/MajoranaQubits/src/HardwareIntrinsics.qs new file mode 100644 index 0000000000..0921939c71 --- /dev/null +++ b/samples/algorithms/MajoranaQubits/src/HardwareIntrinsics.qs @@ -0,0 +1,27 @@ +/// A set of custom measurements exposed from a hardware +/// provider using Majorana Qubits. + +@Measurement() +@SimulatableIntrinsic() +operation __quantum__qis__mx__body(q : Qubit) : Result { + H(q); + M(q) +} + +@Measurement() +@SimulatableIntrinsic() +operation __quantum__qis__mz__body(q : Qubit) : Result { + M(q) +} + +@Measurement() +@SimulatableIntrinsic() +operation __quantum__qis__mxx__body(q1 : Qubit, q2 : Qubit) : Result { + Std.Intrinsic.Measure([PauliX, PauliX], [q1, q2]) +} + +@Measurement() +@SimulatableIntrinsic() +operation __quantum__qis__mzz__body(q1 : Qubit, q2 : Qubit) : Result { + Std.Intrinsic.Measure([PauliZ, PauliZ], [q1, q2]) +} diff --git a/samples/algorithms/MajoranaQubits/src/Main.qs b/samples/algorithms/MajoranaQubits/src/Main.qs new file mode 100644 index 0000000000..473b5ed82a --- /dev/null +++ b/samples/algorithms/MajoranaQubits/src/Main.qs @@ -0,0 +1,17 @@ +/// # Sample +/// Majorana Qubits +/// +/// # Description +/// In hardware providing majorana qubits, common quantum operations +/// are implemented using measurements and Pauli corrections. This +/// sample shows a hypotetical hardware provider exposing some custom +/// gates to Q# and a small library built on top of it. + +/// Sample program using gates for custom hardware provider. +operation Main() : (Result, Result) { + use qs = Qubit[2]; + GateSet.BellPair(qs[0], qs[1]); + let res = GateSet.BellMeasurement(qs[0], qs[1]); + ResetAll(qs); + res +} diff --git a/samples_test/src/tests/algorithms.rs b/samples_test/src/tests/algorithms.rs index fc4f050df7..f2d596881a 100644 --- a/samples_test/src/tests/algorithms.rs +++ b/samples_test/src/tests/algorithms.rs @@ -178,8 +178,6 @@ pub const JOINTMEASUREMENT_EXPECT_DEBUG: Expect = expect![[r#" STATE: |11⟩: 1.0000+0.0000𝑖 (Zero, [One, One])"#]]; -pub const MAJORANAQUBITS_EXPECT: Expect = expect!["(Zero, Zero)"]; -pub const MAJORANAQUBITS_EXPECT_DEBUG: Expect = expect!["(Zero, Zero)"]; pub const MEASUREMENT_EXPECT: Expect = expect!["(Zero, [Zero, Zero])"]; pub const MEASUREMENT_EXPECT_DEBUG: Expect = expect!["(Zero, [Zero, Zero])"]; pub const PHASEFLIPCODE_EXPECT: Expect = expect![[r#" From 2a539bf8de68e019cf32409a67ffc26430fc6dc6 Mon Sep 17 00:00:00 2001 From: Oscar Puente <156957451+orpuente-MS@users.noreply.github.com> Date: Mon, 18 Nov 2024 18:09:46 -0800 Subject: [PATCH 07/24] fix CNOT gate and BellPair comments --- samples/algorithms/MajoranaQubits/src/GateSet.qs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/samples/algorithms/MajoranaQubits/src/GateSet.qs b/samples/algorithms/MajoranaQubits/src/GateSet.qs index 11cd6dd110..3b9677ea96 100644 --- a/samples/algorithms/MajoranaQubits/src/GateSet.qs +++ b/samples/algorithms/MajoranaQubits/src/GateSet.qs @@ -8,10 +8,13 @@ /// Apply a CNOT gate to the given qubits. /// Source: [1] Figure 3. operation CNOT(control : Qubit, target : Qubit) : Unit { + // Prepare an ancilla qubit in the |+> state. use ancilla = Qubit(); - let a = Mzz(control, target); - let b = Mxx(target, ancilla); - let c = Mx(target); + H(ancilla); + + let a = Mzz(control, ancilla); + let b = Mxx(ancilla, target); + let c = Mx(ancilla); if b == One { Z(control); } @@ -23,11 +26,11 @@ operation CNOT(control : Qubit, target : Qubit) : Unit { /// Prepare a Bell Pair. /// Source: [1] Figure 18a. operation BellPair(q1 : Qubit, q2 : Qubit) : Unit { - // Bring the qubits to their ground state. + // Collapse the qubits to the X basis. Mz(q1); Mz(q2); - // Bell Pair preparation + // If their parity is different, flip the second qubit. if Mxx(q1, q2) == One { Z(q2); } From 6f9b55cd95e4498412d9e4e34cc504c8cba18518 Mon Sep 17 00:00:00 2001 From: Oscar Puente <156957451+orpuente-MS@users.noreply.github.com> Date: Mon, 18 Nov 2024 18:14:17 -0800 Subject: [PATCH 08/24] Fix CNOT --- samples/algorithms/MajoranaQubits/src/GateSet.qs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/algorithms/MajoranaQubits/src/GateSet.qs b/samples/algorithms/MajoranaQubits/src/GateSet.qs index 3b9677ea96..35e5292b94 100644 --- a/samples/algorithms/MajoranaQubits/src/GateSet.qs +++ b/samples/algorithms/MajoranaQubits/src/GateSet.qs @@ -19,7 +19,7 @@ operation CNOT(control : Qubit, target : Qubit) : Unit { Z(control); } if [a, c] == [One, One] { - X(ancilla); + X(target); } } From c62aefce8ec3b9312889099030387d2696822cf3 Mon Sep 17 00:00:00 2001 From: orpuente-MS <156957451+orpuente-MS@users.noreply.github.com> Date: Tue, 19 Nov 2024 14:02:11 -0800 Subject: [PATCH 09/24] Update samples/algorithms/MajoranaQubits/src/GateSet.qs Co-authored-by: Stefan J. Wernli --- samples/algorithms/MajoranaQubits/src/GateSet.qs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/samples/algorithms/MajoranaQubits/src/GateSet.qs b/samples/algorithms/MajoranaQubits/src/GateSet.qs index 35e5292b94..19052a334e 100644 --- a/samples/algorithms/MajoranaQubits/src/GateSet.qs +++ b/samples/algorithms/MajoranaQubits/src/GateSet.qs @@ -15,10 +15,11 @@ operation CNOT(control : Qubit, target : Qubit) : Unit { let a = Mzz(control, ancilla); let b = Mxx(ancilla, target); let c = Mx(ancilla); + let c = Mz(ancilla); if b == One { Z(control); } - if [a, c] == [One, One] { + if a != c { X(target); } } From d3c8464d6cd093a21bcf34e1092f0f7cf815c866 Mon Sep 17 00:00:00 2001 From: Oscar Puente <156957451+orpuente-MS@users.noreply.github.com> Date: Tue, 19 Nov 2024 14:08:56 -0800 Subject: [PATCH 10/24] simplify sample --- .../algorithms/MajoranaQubits/src/GateSet.qs | 20 ++++++------------- .../MajoranaQubits/src/HardwareIntrinsics.qs | 13 ------------ 2 files changed, 6 insertions(+), 27 deletions(-) diff --git a/samples/algorithms/MajoranaQubits/src/GateSet.qs b/samples/algorithms/MajoranaQubits/src/GateSet.qs index 19052a334e..651d94e6c7 100644 --- a/samples/algorithms/MajoranaQubits/src/GateSet.qs +++ b/samples/algorithms/MajoranaQubits/src/GateSet.qs @@ -14,11 +14,13 @@ operation CNOT(control : Qubit, target : Qubit) : Unit { let a = Mzz(control, ancilla); let b = Mxx(ancilla, target); - let c = Mx(ancilla); - let c = Mz(ancilla); + let c = M(ancilla); + Reset(ancilla); + if b == One { Z(control); } + if a != c { X(target); } @@ -28,8 +30,8 @@ operation CNOT(control : Qubit, target : Qubit) : Unit { /// Source: [1] Figure 18a. operation BellPair(q1 : Qubit, q2 : Qubit) : Unit { // Collapse the qubits to the X basis. - Mz(q1); - Mz(q2); + M(q1); + M(q2); // If their parity is different, flip the second qubit. if Mxx(q1, q2) == One { @@ -45,16 +47,6 @@ operation BellMeasurement(q1 : Qubit, q2 : Qubit) : (Result, Result) { (x, z) } -/// User friendly wrapper around the Mx hardware gate. -operation Mx(q : Qubit) : Result { - HardwareIntrinsics.__quantum__qis__mx__body(q) -} - -/// User friendly wrapper around the Mz hardware gate. -operation Mz(q : Qubit) : Result { - HardwareIntrinsics.__quantum__qis__mz__body(q) -} - /// User friendly wrapper around the Mxx hardware gate. operation Mxx(q1 : Qubit, q2 : Qubit) : Result { HardwareIntrinsics.__quantum__qis__mxx__body(q1, q2) diff --git a/samples/algorithms/MajoranaQubits/src/HardwareIntrinsics.qs b/samples/algorithms/MajoranaQubits/src/HardwareIntrinsics.qs index 0921939c71..ba3a4b7602 100644 --- a/samples/algorithms/MajoranaQubits/src/HardwareIntrinsics.qs +++ b/samples/algorithms/MajoranaQubits/src/HardwareIntrinsics.qs @@ -1,19 +1,6 @@ /// A set of custom measurements exposed from a hardware /// provider using Majorana Qubits. -@Measurement() -@SimulatableIntrinsic() -operation __quantum__qis__mx__body(q : Qubit) : Result { - H(q); - M(q) -} - -@Measurement() -@SimulatableIntrinsic() -operation __quantum__qis__mz__body(q : Qubit) : Result { - M(q) -} - @Measurement() @SimulatableIntrinsic() operation __quantum__qis__mxx__body(q1 : Qubit, q2 : Qubit) : Result { From 5bcdd2f7f51c5c9d4dff89586cb314cc8896649f Mon Sep 17 00:00:00 2001 From: Oscar Puente <156957451+orpuente-MS@users.noreply.github.com> Date: Tue, 19 Nov 2024 14:24:16 -0800 Subject: [PATCH 11/24] express PreparePlus in terms of Mx to stay within the measurements based operations theme --- samples/algorithms/MajoranaQubits/src/GateSet.qs | 15 ++++++++++++++- .../MajoranaQubits/src/HardwareIntrinsics.qs | 7 +++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/samples/algorithms/MajoranaQubits/src/GateSet.qs b/samples/algorithms/MajoranaQubits/src/GateSet.qs index 651d94e6c7..2642001d73 100644 --- a/samples/algorithms/MajoranaQubits/src/GateSet.qs +++ b/samples/algorithms/MajoranaQubits/src/GateSet.qs @@ -10,7 +10,7 @@ operation CNOT(control : Qubit, target : Qubit) : Unit { // Prepare an ancilla qubit in the |+> state. use ancilla = Qubit(); - H(ancilla); + PreparePlus(ancilla); let a = Mzz(control, ancilla); let b = Mxx(ancilla, target); @@ -26,6 +26,14 @@ operation CNOT(control : Qubit, target : Qubit) : Unit { } } + +/// Prepare a qubit in the |+> state. +operation PreparePlus(q : Qubit) : Unit { + if Mx(q) == One { + Z(q); + } +} + /// Prepare a Bell Pair. /// Source: [1] Figure 18a. operation BellPair(q1 : Qubit, q2 : Qubit) : Unit { @@ -47,6 +55,11 @@ operation BellMeasurement(q1 : Qubit, q2 : Qubit) : (Result, Result) { (x, z) } +/// User friendly wrapper around the Mx hardware gate. +operation Mx(q : Qubit) : Result { + HardwareIntrinsics.__quantum__qis__mx__body(q) +} + /// User friendly wrapper around the Mxx hardware gate. operation Mxx(q1 : Qubit, q2 : Qubit) : Result { HardwareIntrinsics.__quantum__qis__mxx__body(q1, q2) diff --git a/samples/algorithms/MajoranaQubits/src/HardwareIntrinsics.qs b/samples/algorithms/MajoranaQubits/src/HardwareIntrinsics.qs index ba3a4b7602..da9d92fa77 100644 --- a/samples/algorithms/MajoranaQubits/src/HardwareIntrinsics.qs +++ b/samples/algorithms/MajoranaQubits/src/HardwareIntrinsics.qs @@ -1,6 +1,13 @@ /// A set of custom measurements exposed from a hardware /// provider using Majorana Qubits. +@Measurement() +@SimulatableIntrinsic() +operation __quantum__qis__mx__body(q : Qubit) : Result { + H(q); + M(q) +} + @Measurement() @SimulatableIntrinsic() operation __quantum__qis__mxx__body(q1 : Qubit, q2 : Qubit) : Result { From 4ee6d46af6193fa251b467d8b9984c552aac1361 Mon Sep 17 00:00:00 2001 From: Oscar Puente <156957451+orpuente-MS@users.noreply.github.com> Date: Tue, 19 Nov 2024 14:36:18 -0800 Subject: [PATCH 12/24] remove lints --- samples/language/MultiFileProject/qsharp.json | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/samples/language/MultiFileProject/qsharp.json b/samples/language/MultiFileProject/qsharp.json index 9ccae959e3..0967ef424b 100644 --- a/samples/language/MultiFileProject/qsharp.json +++ b/samples/language/MultiFileProject/qsharp.json @@ -1,12 +1 @@ -{ - "lints": [ - { - "lint": "deprecatedWithOperator", - "level": "error" - }, - { - "lint": "deprecatedDoubleColonOperator", - "level": "error" - } - ] -} +{} From 54ab66c29b5513d2f638f07d953f87d7b24b2a87 Mon Sep 17 00:00:00 2001 From: Oscar Puente <156957451+orpuente-MS@users.noreply.github.com> Date: Tue, 19 Nov 2024 14:39:43 -0800 Subject: [PATCH 13/24] remove lints --- samples/algorithms/MajoranaQubits/qsharp.json | 13 +------------ samples/language/MultiFileProject/qsharp.json | 13 ++++++++++++- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/samples/algorithms/MajoranaQubits/qsharp.json b/samples/algorithms/MajoranaQubits/qsharp.json index 9ccae959e3..0967ef424b 100644 --- a/samples/algorithms/MajoranaQubits/qsharp.json +++ b/samples/algorithms/MajoranaQubits/qsharp.json @@ -1,12 +1 @@ -{ - "lints": [ - { - "lint": "deprecatedWithOperator", - "level": "error" - }, - { - "lint": "deprecatedDoubleColonOperator", - "level": "error" - } - ] -} +{} diff --git a/samples/language/MultiFileProject/qsharp.json b/samples/language/MultiFileProject/qsharp.json index 0967ef424b..9ccae959e3 100644 --- a/samples/language/MultiFileProject/qsharp.json +++ b/samples/language/MultiFileProject/qsharp.json @@ -1 +1,12 @@ -{} +{ + "lints": [ + { + "lint": "deprecatedWithOperator", + "level": "error" + }, + { + "lint": "deprecatedDoubleColonOperator", + "level": "error" + } + ] +} From ac8ebf0bd2910d59c53c9ed6989fd9fac6d19d04 Mon Sep 17 00:00:00 2001 From: Oscar Puente <156957451+orpuente-MS@users.noreply.github.com> Date: Tue, 19 Nov 2024 15:03:10 -0800 Subject: [PATCH 14/24] Show how the BellMeasurement can detect the four Bell states. --- samples/algorithms/MajoranaQubits/src/Main.qs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/samples/algorithms/MajoranaQubits/src/Main.qs b/samples/algorithms/MajoranaQubits/src/Main.qs index 473b5ed82a..834f638462 100644 --- a/samples/algorithms/MajoranaQubits/src/Main.qs +++ b/samples/algorithms/MajoranaQubits/src/Main.qs @@ -7,10 +7,22 @@ /// sample shows a hypotetical hardware provider exposing some custom /// gates to Q# and a small library built on top of it. -/// Sample program using gates for custom hardware provider. +/// Sample program using custom gates from a hardware provider. operation Main() : (Result, Result) { use qs = Qubit[2]; GateSet.BellPair(qs[0], qs[1]); + + // Applying X to any of the qubits will result in the (Zero, One) Bell state. + // X(qs[0]); // Uncomment to try + + // Applying Z to any of the qubits will result in the (One, Zero) Bell state. + // Z(qs[0]); // Uncomment to try + + // Applying X and Z to the pair will result in the (One, One) Bell state. + // Note they can be applied to the same Qubit. + // Z(qs[0]); // Uncomment to try + // X(qs[0]); + let res = GateSet.BellMeasurement(qs[0], qs[1]); ResetAll(qs); res From c9a080c3117041ff68a8d80a3fcc45bc6e278e43 Mon Sep 17 00:00:00 2001 From: Oscar Puente <156957451+orpuente-MS@users.noreply.github.com> Date: Tue, 19 Nov 2024 15:14:01 -0800 Subject: [PATCH 15/24] improve comments of `BellPair` operation --- samples/algorithms/MajoranaQubits/src/GateSet.qs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/algorithms/MajoranaQubits/src/GateSet.qs b/samples/algorithms/MajoranaQubits/src/GateSet.qs index 2642001d73..64bb24b4fd 100644 --- a/samples/algorithms/MajoranaQubits/src/GateSet.qs +++ b/samples/algorithms/MajoranaQubits/src/GateSet.qs @@ -37,11 +37,11 @@ operation PreparePlus(q : Qubit) : Unit { /// Prepare a Bell Pair. /// Source: [1] Figure 18a. operation BellPair(q1 : Qubit, q2 : Qubit) : Unit { - // Collapse the qubits to the X basis. + // Collapse the qubits to the |0> or |1> states. M(q1); M(q2); - // If their parity is different, flip the second qubit. + // If their parity is different, flip one of them. if Mxx(q1, q2) == One { Z(q2); } From acc20fccaefd8a3bb02f8026a4b8cd792f030e5e Mon Sep 17 00:00:00 2001 From: Oscar Puente <156957451+orpuente-MS@users.noreply.github.com> Date: Tue, 19 Nov 2024 15:35:33 -0800 Subject: [PATCH 16/24] improve Bell Measurement docstring --- samples/algorithms/MajoranaQubits/src/GateSet.qs | 5 +++++ samples/algorithms/MajoranaQubits/src/Main.qs | 9 +++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/samples/algorithms/MajoranaQubits/src/GateSet.qs b/samples/algorithms/MajoranaQubits/src/GateSet.qs index 64bb24b4fd..0aca552ce9 100644 --- a/samples/algorithms/MajoranaQubits/src/GateSet.qs +++ b/samples/algorithms/MajoranaQubits/src/GateSet.qs @@ -49,6 +49,11 @@ operation BellPair(q1 : Qubit, q2 : Qubit) : Unit { /// Measure a Bell Pair. /// Source: [1] Figure 18b. +/// Below is a map showing how the Bell states map to the Result pairs: +/// |𝚽⁺⟩ -> (Zero, Zero) +/// |𝚿⁺⟩ -> (Zero, One) +/// |𝚽⁻⟩ -> (One, Zero) +/// |𝚿⁻⟩ -> (One, One) operation BellMeasurement(q1 : Qubit, q2 : Qubit) : (Result, Result) { let z = Mzz(q1, q2); let x = Mxx(q1, q2); diff --git a/samples/algorithms/MajoranaQubits/src/Main.qs b/samples/algorithms/MajoranaQubits/src/Main.qs index 834f638462..4047d7c931 100644 --- a/samples/algorithms/MajoranaQubits/src/Main.qs +++ b/samples/algorithms/MajoranaQubits/src/Main.qs @@ -9,17 +9,18 @@ /// Sample program using custom gates from a hardware provider. operation Main() : (Result, Result) { + // Create a Bell Pair in the |𝚽⁺⟩ state. use qs = Qubit[2]; GateSet.BellPair(qs[0], qs[1]); - // Applying X to any of the qubits will result in the (Zero, One) Bell state. + // Applying X to any of the qubits will result in the |𝚿⁺⟩ Bell state. // X(qs[0]); // Uncomment to try - // Applying Z to any of the qubits will result in the (One, Zero) Bell state. + // Applying Z to any of the qubits will result in the |𝚽⁻⟩ Bell state. // Z(qs[0]); // Uncomment to try - // Applying X and Z to the pair will result in the (One, One) Bell state. - // Note they can be applied to the same Qubit. + // Applying X and Z to the pair will result in the |𝚿⁻⟩ Bell state. + // Note that they can be applied to the same Qubit. // Z(qs[0]); // Uncomment to try // X(qs[0]); From e4f4529307fccc7de1469d9c39c60ddde0057cef Mon Sep 17 00:00:00 2001 From: Oscar Puente <156957451+orpuente-MS@users.noreply.github.com> Date: Tue, 19 Nov 2024 15:37:12 -0800 Subject: [PATCH 17/24] correct BellPair comment --- samples/algorithms/MajoranaQubits/src/GateSet.qs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/algorithms/MajoranaQubits/src/GateSet.qs b/samples/algorithms/MajoranaQubits/src/GateSet.qs index 0aca552ce9..4f0a11911a 100644 --- a/samples/algorithms/MajoranaQubits/src/GateSet.qs +++ b/samples/algorithms/MajoranaQubits/src/GateSet.qs @@ -37,7 +37,7 @@ operation PreparePlus(q : Qubit) : Unit { /// Prepare a Bell Pair. /// Source: [1] Figure 18a. operation BellPair(q1 : Qubit, q2 : Qubit) : Unit { - // Collapse the qubits to the |0> or |1> states. + // Collapse the qubits onto the Pauli-Z basis. M(q1); M(q2); From ac3ad416f571ba00fb00ce69becc0410284e3885 Mon Sep 17 00:00:00 2001 From: Oscar Puente <156957451+orpuente-MS@users.noreply.github.com> Date: Tue, 19 Nov 2024 15:43:24 -0800 Subject: [PATCH 18/24] more specific comment in BellPair preparation --- samples/algorithms/MajoranaQubits/src/GateSet.qs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/algorithms/MajoranaQubits/src/GateSet.qs b/samples/algorithms/MajoranaQubits/src/GateSet.qs index 4f0a11911a..b6143a37e8 100644 --- a/samples/algorithms/MajoranaQubits/src/GateSet.qs +++ b/samples/algorithms/MajoranaQubits/src/GateSet.qs @@ -41,7 +41,7 @@ operation BellPair(q1 : Qubit, q2 : Qubit) : Unit { M(q1); M(q2); - // If their parity is different, flip one of them. + // If they are not aligned in the Pauli-X basis, phase flip one of them. if Mxx(q1, q2) == One { Z(q2); } From 53f6ad1ed7301fdcc14c29f589720a187c4cef69 Mon Sep 17 00:00:00 2001 From: Oscar Puente <156957451+orpuente-MS@users.noreply.github.com> Date: Tue, 19 Nov 2024 16:13:32 -0800 Subject: [PATCH 19/24] use mathematical angular bracket in comment and docstring --- samples/algorithms/MajoranaQubits/src/GateSet.qs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/algorithms/MajoranaQubits/src/GateSet.qs b/samples/algorithms/MajoranaQubits/src/GateSet.qs index b6143a37e8..2e5b52586e 100644 --- a/samples/algorithms/MajoranaQubits/src/GateSet.qs +++ b/samples/algorithms/MajoranaQubits/src/GateSet.qs @@ -8,7 +8,7 @@ /// Apply a CNOT gate to the given qubits. /// Source: [1] Figure 3. operation CNOT(control : Qubit, target : Qubit) : Unit { - // Prepare an ancilla qubit in the |+> state. + // Prepare an ancilla qubit in the |+⟩ state. use ancilla = Qubit(); PreparePlus(ancilla); @@ -27,7 +27,7 @@ operation CNOT(control : Qubit, target : Qubit) : Unit { } -/// Prepare a qubit in the |+> state. +/// Prepare a qubit in the |+⟩ state. operation PreparePlus(q : Qubit) : Unit { if Mx(q) == One { Z(q); From 606aa39f0be10cee13524f816c11ca7c824f1ff8 Mon Sep 17 00:00:00 2001 From: Oscar Puente <156957451+orpuente-MS@users.noreply.github.com> Date: Fri, 22 Nov 2024 07:03:24 -0800 Subject: [PATCH 20/24] Add Mz gate for simmetry --- samples/algorithms/MajoranaQubits/src/GateSet.qs | 11 ++++++++--- .../MajoranaQubits/src/HardwareIntrinsics.qs | 6 ++++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/samples/algorithms/MajoranaQubits/src/GateSet.qs b/samples/algorithms/MajoranaQubits/src/GateSet.qs index 2e5b52586e..aae758adf1 100644 --- a/samples/algorithms/MajoranaQubits/src/GateSet.qs +++ b/samples/algorithms/MajoranaQubits/src/GateSet.qs @@ -14,7 +14,7 @@ operation CNOT(control : Qubit, target : Qubit) : Unit { let a = Mzz(control, ancilla); let b = Mxx(ancilla, target); - let c = M(ancilla); + let c = Mz(ancilla); Reset(ancilla); if b == One { @@ -38,8 +38,8 @@ operation PreparePlus(q : Qubit) : Unit { /// Source: [1] Figure 18a. operation BellPair(q1 : Qubit, q2 : Qubit) : Unit { // Collapse the qubits onto the Pauli-Z basis. - M(q1); - M(q2); + Mz(q1); + Mz(q2); // If they are not aligned in the Pauli-X basis, phase flip one of them. if Mxx(q1, q2) == One { @@ -65,6 +65,11 @@ operation Mx(q : Qubit) : Result { HardwareIntrinsics.__quantum__qis__mx__body(q) } +/// User friendly wrapper around the Mz hardware gate. +operation Mz(q : Qubit) : Result { + HardwareIntrinsics.__quantum__qis__mx__body(q) +} + /// User friendly wrapper around the Mxx hardware gate. operation Mxx(q1 : Qubit, q2 : Qubit) : Result { HardwareIntrinsics.__quantum__qis__mxx__body(q1, q2) diff --git a/samples/algorithms/MajoranaQubits/src/HardwareIntrinsics.qs b/samples/algorithms/MajoranaQubits/src/HardwareIntrinsics.qs index da9d92fa77..0921939c71 100644 --- a/samples/algorithms/MajoranaQubits/src/HardwareIntrinsics.qs +++ b/samples/algorithms/MajoranaQubits/src/HardwareIntrinsics.qs @@ -8,6 +8,12 @@ operation __quantum__qis__mx__body(q : Qubit) : Result { M(q) } +@Measurement() +@SimulatableIntrinsic() +operation __quantum__qis__mz__body(q : Qubit) : Result { + M(q) +} + @Measurement() @SimulatableIntrinsic() operation __quantum__qis__mxx__body(q1 : Qubit, q2 : Qubit) : Result { From 7bd97f6fac8b6727faceb170980acbb9c0873be1 Mon Sep 17 00:00:00 2001 From: Oscar Puente <156957451+orpuente-MS@users.noreply.github.com> Date: Fri, 22 Nov 2024 07:13:35 -0800 Subject: [PATCH 21/24] Rename `PreparePlus` to `PrepareX` --- samples/algorithms/MajoranaQubits/src/GateSet.qs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/samples/algorithms/MajoranaQubits/src/GateSet.qs b/samples/algorithms/MajoranaQubits/src/GateSet.qs index aae758adf1..d53e9d4fd2 100644 --- a/samples/algorithms/MajoranaQubits/src/GateSet.qs +++ b/samples/algorithms/MajoranaQubits/src/GateSet.qs @@ -10,7 +10,7 @@ operation CNOT(control : Qubit, target : Qubit) : Unit { // Prepare an ancilla qubit in the |+⟩ state. use ancilla = Qubit(); - PreparePlus(ancilla); + PrepareX(ancilla); let a = Mzz(control, ancilla); let b = Mxx(ancilla, target); @@ -28,7 +28,8 @@ operation CNOT(control : Qubit, target : Qubit) : Unit { /// Prepare a qubit in the |+⟩ state. -operation PreparePlus(q : Qubit) : Unit { +/// `q` must be in the |0⟩ state. +operation PrepareX(q : Qubit) : Unit { if Mx(q) == One { Z(q); } From a9a8fd3b02b9e79d0e7ac4e85c2652b380ebe590 Mon Sep 17 00:00:00 2001 From: Oscar Puente <156957451+orpuente-MS@users.noreply.github.com> Date: Fri, 22 Nov 2024 11:12:41 -0800 Subject: [PATCH 22/24] fix Mz wrapper --- samples/algorithms/MajoranaQubits/src/GateSet.qs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/algorithms/MajoranaQubits/src/GateSet.qs b/samples/algorithms/MajoranaQubits/src/GateSet.qs index d53e9d4fd2..d27538f287 100644 --- a/samples/algorithms/MajoranaQubits/src/GateSet.qs +++ b/samples/algorithms/MajoranaQubits/src/GateSet.qs @@ -68,7 +68,7 @@ operation Mx(q : Qubit) : Result { /// User friendly wrapper around the Mz hardware gate. operation Mz(q : Qubit) : Result { - HardwareIntrinsics.__quantum__qis__mx__body(q) + HardwareIntrinsics.__quantum__qis__mz__body(q) } /// User friendly wrapper around the Mxx hardware gate. From 0d65c2242e9eb03b2cc1a55d0d0b2f9dab906ee9 Mon Sep 17 00:00:00 2001 From: Oscar Puente <156957451+orpuente-MS@users.noreply.github.com> Date: Fri, 22 Nov 2024 11:13:42 -0800 Subject: [PATCH 23/24] remove innacurate docstring sentence --- samples/algorithms/MajoranaQubits/src/GateSet.qs | 1 - 1 file changed, 1 deletion(-) diff --git a/samples/algorithms/MajoranaQubits/src/GateSet.qs b/samples/algorithms/MajoranaQubits/src/GateSet.qs index d27538f287..358b72e2a4 100644 --- a/samples/algorithms/MajoranaQubits/src/GateSet.qs +++ b/samples/algorithms/MajoranaQubits/src/GateSet.qs @@ -28,7 +28,6 @@ operation CNOT(control : Qubit, target : Qubit) : Unit { /// Prepare a qubit in the |+⟩ state. -/// `q` must be in the |0⟩ state. operation PrepareX(q : Qubit) : Unit { if Mx(q) == One { Z(q); From 9434fdf3c355749f1b791f4f2efbedeaebd5dc41 Mon Sep 17 00:00:00 2001 From: Oscar Puente <156957451+orpuente-MS@users.noreply.github.com> Date: Fri, 22 Nov 2024 11:15:54 -0800 Subject: [PATCH 24/24] include `PrepareZ` for completness --- samples/algorithms/MajoranaQubits/src/GateSet.qs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/samples/algorithms/MajoranaQubits/src/GateSet.qs b/samples/algorithms/MajoranaQubits/src/GateSet.qs index 358b72e2a4..3396842f2b 100644 --- a/samples/algorithms/MajoranaQubits/src/GateSet.qs +++ b/samples/algorithms/MajoranaQubits/src/GateSet.qs @@ -34,6 +34,13 @@ operation PrepareX(q : Qubit) : Unit { } } +/// Prepare a qubit in the |0⟩ state. +operation PrepareZ(q : Qubit) : Unit { + if Mz(q) == One { + X(q); + } +} + /// Prepare a Bell Pair. /// Source: [1] Figure 18a. operation BellPair(q1 : Qubit, q2 : Qubit) : Unit {