diff --git a/katas/content/nonlocal_games/chsh_classical_strategy/Verification.qs b/katas/content/nonlocal_games/chsh_classical_strategy/Verification.qs index d407458d85..8526baa4d0 100644 --- a/katas/content/nonlocal_games/chsh_classical_strategy/Verification.qs +++ b/katas/content/nonlocal_games/chsh_classical_strategy/Verification.qs @@ -6,8 +6,8 @@ namespace Kata.Verification { operation CheckSolution() : Bool { mutable wins = 0; for i in 1..1000 { - let x = DrawRandomInt(0, 1) == 1 ? true | false; - let y = DrawRandomInt(0, 1) == 1 ? true | false; + let x = DrawRandomBool(0.5); + let y = DrawRandomBool(0.5); let (a, b) = (Kata.AliceClassical(x), Kata.BobClassical(y)); if ((x and y) == (a != b)) { set wins = wins + 1; diff --git a/katas/content/nonlocal_games/chsh_classical_win_condition/index.md b/katas/content/nonlocal_games/chsh_classical_win_condition/index.md index 4485f2f549..bacc59426d 100644 --- a/katas/content/nonlocal_games/chsh_classical_win_condition/index.md +++ b/katas/content/nonlocal_games/chsh_classical_win_condition/index.md @@ -1,6 +1,7 @@ **Input:** -* Alice and Bob's starting bits (X and Y). -* Alice and Bob's output bits (A and B). + +- Alice and Bob's starting bits (X and Y). +- Alice and Bob's output bits (A and B). **Output:** True if Alice and Bob won the CHSH game, that is, if X ∧ Y = A ⊕ B, and false otherwise. diff --git a/katas/content/nonlocal_games/chsh_quantum_alice_strategy/Placeholder.qs b/katas/content/nonlocal_games/chsh_quantum_alice_strategy/Placeholder.qs new file mode 100644 index 0000000000..9aecfc2566 --- /dev/null +++ b/katas/content/nonlocal_games/chsh_quantum_alice_strategy/Placeholder.qs @@ -0,0 +1,7 @@ +namespace Kata { + operation AliceQuantum (bit : Bool, qubit : Qubit) : Bool { + // Implement your solution here... + + return false; + } +} diff --git a/katas/content/nonlocal_games/chsh_quantum_alice_strategy/Solution.qs b/katas/content/nonlocal_games/chsh_quantum_alice_strategy/Solution.qs new file mode 100644 index 0000000000..96a6f61e07 --- /dev/null +++ b/katas/content/nonlocal_games/chsh_quantum_alice_strategy/Solution.qs @@ -0,0 +1,12 @@ +namespace Kata { + operation AliceQuantum (bit : Bool, qubit : Qubit) : Bool { + if bit { + let q = MResetX(qubit); + return q == One; + } + else { + let q = MResetZ(qubit); + return q == One; + } + } +} diff --git a/katas/content/nonlocal_games/chsh_quantum_alice_strategy/Verification.qs b/katas/content/nonlocal_games/chsh_quantum_alice_strategy/Verification.qs new file mode 100644 index 0000000000..d1554e79c7 --- /dev/null +++ b/katas/content/nonlocal_games/chsh_quantum_alice_strategy/Verification.qs @@ -0,0 +1,49 @@ +namespace Kata.Verification { + open Microsoft.Quantum.Convert; + open Microsoft.Quantum.Random; + + @EntryPoint() + operation CheckSolution() : Bool { + use q = Qubit(); + for _ in 1 .. 4 { + // repeat 4 times since we are testing a measurement and wrong basis still might get + // the correct answer, reduces probability of false positives + let result = Kata.AliceQuantum(false, q); + Reset(q); + if (result != false) { + Message("Measuring |0⟩ in the Z basis returned incorrect value; expected false"); + return false; + } + + // apply the Pauli X gate + X(q); + let result = Kata.AliceQuantum(false, q); + Reset(q); + if (result != true) { + Message("Measuring |1⟩ in the Z basis returned incorrect value; expected true"); + return false; + } + + // apply the Hadamard gate + H(q); + let result = Kata.AliceQuantum(true, q); + Reset(q); + if (result != false) { + Message("Measuring |+⟩ in the X basis returned incorrect value; expected false"); + return false; + } + + // apply the Pauli X and then the Hadamard gate + X(q); + H(q); + let result = Kata.AliceQuantum(true, q); + Reset(q); + if (result != true) { + Message("Measuring |-⟩ in the X basis returned incorrect value; expected true"); + return false; + } + } + Message("Correct!"); + true + } +} diff --git a/katas/content/nonlocal_games/chsh_quantum_alice_strategy/index.md b/katas/content/nonlocal_games/chsh_quantum_alice_strategy/index.md new file mode 100644 index 0000000000..fc442e2db0 --- /dev/null +++ b/katas/content/nonlocal_games/chsh_quantum_alice_strategy/index.md @@ -0,0 +1,12 @@ +In the quantum version of the game, the players still can not communicate during the game, +but they are allowed to share qubits from a Bell pair before the start of the game. + +**Inputs:** + +- Alice's starting bit (X). +- Alice's half of Bell pair she shares with Bob. + +**Goal:** + Measure Alice's qubit in the Z basis if her bit is 0 (false), or the X basis if her bit is 1 (true) and + return the measurement result as Boolean value: map `Zero` to false and `One` to true. + The state of the qubit after the operation does not matter. diff --git a/katas/content/nonlocal_games/chsh_quantum_alice_strategy/solution.md b/katas/content/nonlocal_games/chsh_quantum_alice_strategy/solution.md new file mode 100644 index 0000000000..64bbd830f6 --- /dev/null +++ b/katas/content/nonlocal_games/chsh_quantum_alice_strategy/solution.md @@ -0,0 +1,12 @@ +In Q#, you can perform measurements in a specific basis using either the +[Measure operation](https://learn.microsoft.com/qsharp/api/qsharp-lang/microsoft.quantum.intrinsic/measure) +or convenient shorthands for measure-and-reset-to-$\ket{0}$ sequence of operations +[MResetZ](https://learn.microsoft.com/qsharp/api/qsharp-lang/microsoft.quantum.measurement/mresetz) and +[MResetX](https://learn.microsoft.com/qsharp/api/qsharp-lang/microsoft.quantum.measurement/mresetx). + +(See the the lesson below for details on why Alice should follow this strategy.) + +@[solution]({ + "id": "nonlocal_games__chsh_quantum_alice_strategy_solution", + "codePath": "Solution.qs" +}) diff --git a/katas/content/nonlocal_games/chsh_quantum_bob_strategy/Placeholder.qs b/katas/content/nonlocal_games/chsh_quantum_bob_strategy/Placeholder.qs new file mode 100644 index 0000000000..2477ed5ad7 --- /dev/null +++ b/katas/content/nonlocal_games/chsh_quantum_bob_strategy/Placeholder.qs @@ -0,0 +1,9 @@ +namespace Kata { + open Microsoft.Quantum.Math; + + operation BobQuantum (bit : Bool, qubit : Qubit) : Bool { + // Implement your solution here... + + return false; + } +} diff --git a/katas/content/nonlocal_games/chsh_quantum_bob_strategy/Solution.qs b/katas/content/nonlocal_games/chsh_quantum_bob_strategy/Solution.qs new file mode 100644 index 0000000000..ba690fe500 --- /dev/null +++ b/katas/content/nonlocal_games/chsh_quantum_bob_strategy/Solution.qs @@ -0,0 +1,9 @@ +namespace Kata { + open Microsoft.Quantum.Math; + + operation BobQuantum (bit : Bool, qubit : Qubit) : Bool { + let angle = 2.0 * PI() / 8.0; + Ry(not bit ? -angle | angle, qubit); + return M(qubit) == One; + } +} diff --git a/katas/content/nonlocal_games/chsh_quantum_bob_strategy/Verification.qs b/katas/content/nonlocal_games/chsh_quantum_bob_strategy/Verification.qs new file mode 100644 index 0000000000..1d35fd08e5 --- /dev/null +++ b/katas/content/nonlocal_games/chsh_quantum_bob_strategy/Verification.qs @@ -0,0 +1,55 @@ +namespace Kata.Verification { + open Microsoft.Quantum.Math; + + operation RotateBobQubit (clockwise : Bool, qubit : Qubit) : Unit { + if (clockwise) { + Ry(-PI()/4.0, qubit); + } else { + Ry(PI()/4.0, qubit); + } + } + + @EntryPoint() + operation CheckSolution() : Bool { + for _ in 1 .. 4 { + // repeat 4 times since we are testing a measurement and wrong basis still might get + // the correct answer, reduces probability of false positives + use q = Qubit(); + RotateBobQubit(false, q); + let result = Kata.BobQuantum(false, q); + Reset(q); + if (result != false) { + Message("π/8 from |0⟩ not measured as false"); + return false; + } + + X(q); + RotateBobQubit(false, q); + let result = Kata.BobQuantum(false, q); + Reset(q); + if (result != true) { + Message("π/8 from |1⟩ not measured as true"); + return false; + } + + RotateBobQubit(true, q); + let result = Kata.BobQuantum(true, q); + Reset(q); + if (result != false) { + Message("-π/8 from |0⟩ not measured as false"); + return false; + } + + X(q); + RotateBobQubit(true, q); + let result = Kata.BobQuantum(true, q); + Reset(q); + if (result != true) { + Message("-π/8 from |1⟩ not measured as true"); + return false; + } + } + Message("Correct!"); + true + } +} diff --git a/katas/content/nonlocal_games/chsh_quantum_bob_strategy/index.md b/katas/content/nonlocal_games/chsh_quantum_bob_strategy/index.md new file mode 100644 index 0000000000..a7b96bb70a --- /dev/null +++ b/katas/content/nonlocal_games/chsh_quantum_bob_strategy/index.md @@ -0,0 +1,11 @@ +**Inputs:** + +- Bob's starting bit (Y). +- Bob's half of Bell pair he shares with Alice. + +**Goal:** +Measure Bob's qubit in the $\frac{\pi}{8}$ basis if his bit is 0 (false), or the $-\frac{\pi}{8}$ basis +if his bit is 1 (true) and return the measurement result as a Boolean value: map `Zero` to false and `One` to true. +The state of the qubit after the operation does not matter. + +Measuring a qubit in the $\theta$ basis is the same as rotating the qubit by $\theta$, clockwise, and then making a standard measurement in the Z basis. diff --git a/katas/content/nonlocal_games/chsh_quantum_bob_strategy/solution.md b/katas/content/nonlocal_games/chsh_quantum_bob_strategy/solution.md new file mode 100644 index 0000000000..a7841d51b2 --- /dev/null +++ b/katas/content/nonlocal_games/chsh_quantum_bob_strategy/solution.md @@ -0,0 +1,11 @@ +A suitable $R_y$ rotation can be used to go from the computational basis $\{ \ket{0}, \ket{1} \}$ to the $\{ \ket{\psi_+}, \ket{\psi_-} \}$ basis and vice versa. + +To implement the described transformation in Q#, we need to rotate the qubit by $\frac{\pi}{8}$ clockwise if `bit == false` or counterclockwise if `bit == true` and then perform a measurement. +We can do the rotation using the $R_y$ gate (note the negation of the Boolean parameter we need to do). + +(See the lesson below for details on why Bob should follow this strategy.) + +@[solution]({ + "id": "nonlocal_games__chsh_quantum_bob_strategy_solution", + "codePath": "Solution.qs" +}) diff --git a/katas/content/nonlocal_games/examples/CHSHGameDemo.qs b/katas/content/nonlocal_games/examples/CHSHGameDemo.qs new file mode 100644 index 0000000000..b062f35baf --- /dev/null +++ b/katas/content/nonlocal_games/examples/CHSHGameDemo.qs @@ -0,0 +1,52 @@ +namespace Quantum.Kata.CHSHGame { + open Microsoft.Quantum.Random; + open Microsoft.Quantum.Math; + open Microsoft.Quantum.Convert; + + function WinCondition (x : Bool, y : Bool, a : Bool, b : Bool) : Bool { + return (x and y) == (a != b); + } + + function AliceClassical (x : Bool) : Bool { + return false; + } + + function BobClassical (y : Bool) : Bool { + return false; + } + + operation AliceQuantum (bit : Bool, qubit : Qubit) : Bool { + if bit { + return MResetX(qubit) == One; + } + return MResetZ(qubit) == One; + } + + operation BobQuantum (bit : Bool, qubit : Qubit) : Bool { + let angle = 2.0 * PI() / 8.0; + Ry(not bit ? -angle | angle, qubit); + return M(qubit) == One; + } + + @EntryPoint() + operation CHSH_GameDemo() : Unit { + use (aliceQubit, bobQubit) = (Qubit(), Qubit()); + mutable classicalWins = 0; + mutable quantumWins = 0; + let iterations = 1000; + for _ in 1 .. iterations { + H(aliceQubit); + CNOT(aliceQubit, bobQubit); + let (x, y) = (DrawRandomBool(0.5), DrawRandomBool(0.5)); + if WinCondition(x, y, AliceClassical(x), BobClassical(y)) { + set classicalWins += 1; + } + if WinCondition(x, y, AliceQuantum(x, aliceQubit), BobQuantum(y, bobQubit)) { + set quantumWins += 1; + } + ResetAll([aliceQubit, bobQubit]); + } + Message($"Percentage of classical wins is {100.0*IntAsDouble(classicalWins)/IntAsDouble(iterations)}%"); + Message($"Percentage of quantum wins is {100.0*IntAsDouble(quantumWins)/IntAsDouble(iterations)}%"); + } +} diff --git a/katas/content/nonlocal_games/index.md b/katas/content/nonlocal_games/index.md index f81c197037..8d1ba9b4b1 100644 --- a/katas/content/nonlocal_games/index.md +++ b/katas/content/nonlocal_games/index.md @@ -12,13 +12,15 @@ so they cannot communicate with each other during the game. Another characteristics of these games is that they are "refereed", which means the players try to win against the referee. **This kata covers the following topics:** - - Clauser, Horne, Shimony, and Hold thought experiment (often abbreviated as CHSH game) - - Greenberger-Horne-Zeilinger game (often abbreviated as GHZ game) - - The Mermin-Peres Magic Square game + +- Clauser, Horne, Shimony, and Hold thought experiment (often abbreviated as CHSH game) +- Greenberger-Horne-Zeilinger game (often abbreviated as GHZ game) +- The Mermin-Peres Magic Square game **What you should know to start working on this kata:** - - Basic linear algebra - - Basic knowledge of quantum gates and measurements + +- Basic linear algebra +- Basic knowledge of quantum gates and measurements @[section]({ "id": "nonlocal_games__chsh_game", @@ -31,15 +33,11 @@ Each of them is given a bit (Alice gets X and Bob gets Y), and they have to return new bits (Alice returns A and Bob returns B) so that X ∧ Y = A ⊕ B. The trick is, they can not communicate during the game. -> * ∧ is the standard bitwise AND operator. -> * ⊕ is the exclusive or, or XOR operator, so (P ⊕ Q) is true if exactly one of P and Q is true. - -@[section]({ - "id": "nonlocal_games__chsh_game_classical", - "title": "Part I. Classical CHSH" -}) +> - ∧ is the standard bitwise AND operator. +> - ⊕ is the exclusive or, or XOR operator, so (P ⊕ Q) is true if exactly one of P and Q is true. To start with, let's take a look at how you would play the classical variant of this game without access to any quantum tools. +Then, let's proceed with quantum strategies for Alice and Bob. @[exercise]({ "id": "nonlocal_games__chsh_classical_win_condition", @@ -53,9 +51,147 @@ To start with, let's take a look at how you would play the classical variant of "path": "./chsh_classical_strategy/" }) +@[exercise]({ + "id": "nonlocal_games__chsh_quantum_alice_strategy", + "title": "Alice's Quantum Strategy", + "path": "./chsh_quantum_alice_strategy/" +}) + +@[exercise]({ + "id": "nonlocal_games__chsh_quantum_bob_strategy", + "title": "Bob's Quantum Strategy", + "path": "./chsh_quantum_bob_strategy/" +}) + +@[section]({ + "id": "nonlocal_games__discussion", + "title": "Discussion: Probability of Victory for Quantum Strategy" +}) + +The above quantum strategy adopted by Alice and Bob offers a win rate of $\frac{2 + \sqrt{2}}{4}$, or about $85.36\%$. Let's see why this is the case. + +First, consider the outcome if Alice and Bob simply measure their qubits in the Z basis without manipulating them at all. Because of the entanglement inherent to the Bell state they hold, their measurements will always agree (i.e., both true or both false). +This will suffice for victory in the three scenarios (0,0), (0,1) and (1,0) and fail for (1,1), so their win probability is $75\%$, the same as that for the straightforward classical strategies of invariably returning both true or both false. + +Now let's analyze the optimal quantum strategy. + +> As a reminder, probability "wavefunction" for a two-qubit state is given by the following length-4 vector of amplitudes: +> $$\begin{bmatrix}\psi_{00}\\\psi_{01}\\\psi_{10}\\\psi_{11}\end{bmatrix}$$ +> $|\psi_{ij}|^2$ gives the probability of observing the corresponding basis state $\ket{ij}$ upon measuring the qubit pair. + +The initial state $\ket{00}$ has $\psi_{00} = 1$ and $\psi_{01} = \psi_{10} = \psi_{11} = 0$. +The Bell state we prepare as the first step of the game has an amplitude vector as follows (we'll use decimal approximations for matrix elements): + +$$\begin{bmatrix}1/\sqrt{2}\\0\\0\\1/\sqrt{2}\end{bmatrix} = \begin{bmatrix}0.7071\\0\\0\\0.7071\end{bmatrix}$$ + +Let's analyze the probabilities of outcomes in case of different bits received by players. + +## Case 1: Alice holds bit 0 + +In this case Alice simply measures in the Z basis as above. + +- When Bob's bit is 0, he rotates his qubit clockwise by $\pi/8$, which corresponds to the operator + +$$\begin{bmatrix} + 0.9239 & 0.3827 & 0 & 0\\ + -0.3827 & 0.9239 & 0 & 0\\ + 0 & 0 & 0.9239 & 0.3827\\ + 0 & 0 & -0.3827 & 0.9239 +\end{bmatrix}$$ +This performs the $R_y$ rotation by $\pi/8$ radians clockwise on Bob's qubit while leaving Alice's qubit unchanged. + +- If Bob's bit were 1, he would rotate his qubit counterclockwise by $\pi/8$, applying a very similar operator + +$$\begin{bmatrix} + 0.9239 & -0.3827 & 0 & 0\\ + 0.3827 & 0.9239 & 0 & 0\\ + 0 & 0 & 0.9239 & -0.3827\\ + 0 & 0 & 0.3827 & 0.9239 +\end{bmatrix}$$ + +Therefore, when Alice has bit 0, the application of the rotation operator to the Bell state gives +$$\begin{bmatrix} + 0.6533 \\ + -0.2706 \\ + 0.2706 \\ + 0.6533 +\end{bmatrix} \text{ or } +\begin{bmatrix} + 0.6533\\ + 0.2706\\ + -0.2706\\ + 0.6533 +\end{bmatrix}$$ +depending on whether Bob holds 0 (left-hand case) or 1 (right-hand case). + +The result of AND on their input bits will always be 0; thus they win when their outputs agree. These two cases correspond to the top and bottom elements of the vectors above, with a combined probability of $(0.6533)^2 + (0.6533)^2 = 0.4268 + 0.4268 = 0.8536$, so they have an $85.36\%$ win chance. + +## Case 2: Alice holds bit 1 + +When Alice holds bit 1, she measures in basis X (or, equivalently, Hadamard-transforms her qubit, leaving Bob's qubit unchanged, +before making her Z-basis measurement). This corresponds to applying the operator +$$\begin{bmatrix} + 0.7071 & 0 & 0.7071 & 0\\ + 0 & 0.7071 & 0 & 0.7071\\ + 0.7071 & 0 & -0.7071 & 0\\ + 0 & 0.7071 & 0 & -0.7071 +\end{bmatrix}$$ +to the Bell state, resulting in a vector of: +$$\begin{bmatrix} + 0.5\\ + 0.5\\ + 0.5\\ + -0.5 +\end{bmatrix}$$ + +Now, one of the two rotation operators is applied depending on what bit Bob holds, transforming this vector into: +$$\begin{bmatrix} + 0.6533 \\ + 0.2706 \\ + 0.2706 \\ + -0.6533 +\end{bmatrix} \text{ or } +\begin{bmatrix} + 0.2706\\ + 0.6533\\ + 0.6533\\ + -0.2706 + \end{bmatrix}$$ + +When Bob holds 0, they still want to return the same parity, which they again do with $85.36\%$ probability (left-hand vector above). +But when Bob holds 1, the AND condition is now true and the players want to answer in opposite parity. This corresponds to the second and third elements of the right-hand vector above. +Thanks to the "magic" of the combination of the counterclockwise rotation and Hadamard transform, they now do this with probability $(0.6533)^2 + (0.6533)^2 = 0.8536$ and thus $85.36\%$ becomes their win odds once more. + +## Side notes + +- If Bob never rotated his qubit, their entangled state would remain the Bell state if Alice held bit 0 and the state corresponding to $\frac12 \big(\ket{00} + \ket{01} + \ket{10} - \ket{11}\big)$ if Alice held bit 1. +While she and Bob would have a $100\%$ success probability against Alice's 0 bit, they would have only a $50\%$ chance of success if she held bit 1, and thus their win chance would revert to the $75\%$ of the classical strategy again. +- It can be proven that Alice and Bob cannot surpass an overall win probability of $85.36\%$ in the CHSH game. This entails a higher-level discussion of quantum observable theory, for instance see [Tsirelson's bound](https://en.wikipedia.org/wiki/Tsirelson's_bound). + +@[section]({ + "id": "nonlocal_games__chsh_e2e", + "title": "Running CHSH Game End to End" +}) + +Putting together the building blocks we've implemented into a strategy is very simple: +- Allocate two qubits and prepare a Bell state on them. +- Send one of the qubits to Alice and another to Bob (this step is "virtual", not directly reflected in Q# code, other than making sure that Alice and Bob each act on their qubit only). +- Have Alice and Bob perform their measurements on their respective qubits using `AliceQuantum` and `BobQuantum` operations. +- Reset used qubits to $\ket{0}$ before they are released. +- Return their measurement results. + +In the example below you can compare winning percentage of classical and quantum games. + +>You may play with the code and check if there is a difference in results when +>1. The referee picks non-random bits. How can the referee minimize Alice and Bob's win probability? +>2. Bob's qubit is measured first. +>3. Alice and Bob get unentangled qubit pair. + +@[example]({"id": "nonlocal_games__chsh_e2edemo", "codePath": "./examples/CHSHGameDemo.qs"}) + @[section]({ - "id": "nonlocal_games__conclusion", - "title": "Conclusion" + "id": "nonlocal_games__conclusion", + "title": "Conclusion" }) Congratulations! In this kata you learned how to use quantum entanglement in nonlocal quantum games to get results that are better than any classical strategy can offer.