Skip to content

Commit

Permalink
[Measurements] Clean up the workbook (microsoft#329)
Browse files Browse the repository at this point in the history
  • Loading branch information
vivanwin authored Apr 22, 2020
1 parent c348345 commit 4988d84
Show file tree
Hide file tree
Showing 2 changed files with 138 additions and 59 deletions.
49 changes: 49 additions & 0 deletions Measurements/Measurements.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,13 @@
"}"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"*Can't come up with a solution? See the explained solution in the [Measurements Workbook](./Workbook_Measurements.ipynb#Task-1.1.-$|0\\rangle$-or-$|1\\rangle$?).*"
]
},
{
"cell_type": "markdown",
"metadata": {},
Expand All @@ -127,6 +134,13 @@
"}"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"*Can't come up with a solution? See the explained solution in the [Measurements Workbook](./Workbook_Measurements.ipynb#Task-1.2.-Set-the-qubit-to-the-$|0\\rangle$-state.).*"
]
},
{
"cell_type": "markdown",
"metadata": {},
Expand All @@ -151,6 +165,13 @@
"}"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"*Can't come up with a solution? See the explained solution in the [Measurements Workbook](./Workbook_Measurements.ipynb#Task-1.3.-$|+\\rangle$-or-$|-\\rangle$?).*"
]
},
{
"cell_type": "markdown",
"metadata": {},
Expand Down Expand Up @@ -178,6 +199,13 @@
"}"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"*Can't come up with a solution? See the explained solution in the [Measurements Workbook](./Workbook_Measurements.ipynb#Task-1.4.-$|A\\rangle$-or-$|B\\rangle$?).*"
]
},
{
"cell_type": "markdown",
"metadata": {},
Expand All @@ -202,6 +230,13 @@
"}"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"*Can't come up with a solution? See the explained solution in the [Measurements Workbook](./Workbook_Measurements.ipynb#Task-1.5.-$|00\\rangle$-or-$|11\\rangle$?).*"
]
},
{
"cell_type": "markdown",
"metadata": {},
Expand Down Expand Up @@ -235,6 +270,13 @@
"}"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"*Can't come up with a solution? See the explained solution in the [Measurements Workbook](./Workbook_Measurements.ipynb#Task-1.6.-Distinguish-four-basis-states.).*"
]
},
{
"cell_type": "markdown",
"metadata": {},
Expand Down Expand Up @@ -271,6 +313,13 @@
"}"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"*Can't come up with a solution? See the explained solution in the [Measurements Workbook](./Workbook_Measurements.ipynb#Task-1.7.-Distinguish-two-basis-states-given-by-bit-strings).*"
]
},
{
"cell_type": "markdown",
"metadata": {},
Expand Down
148 changes: 89 additions & 59 deletions Measurements/Workbook_Measurements.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,9 @@
"source": [
"### Solution\n",
"\n",
"When a qubit is measured its superposition state collapses, meaning that the superposition state (a linear combination of basis vectors) collapses to just one of the basis vectors. Since in this task the original state of the qubit is already one of the basis vectors, we know measurement would identify that state exactly. \n",
"[M](https://docs.microsoft.com/en-us/qsharp/api/qsharp/microsoft.quantum.primitive.m) is the measurement gate, it returns true if the qubit is in state 1 and false if the qubit is in state 0.\n",
"Here we evaluate M(q) and test if it is equal to 1. "
"The input qubit is guaranteed to be either in basis state $|0\\rangle$ or $|1\\rangle$. This means that when measuring the qubit in the Pauli $Z$ basis (the computational basis), the measurement will report the input state without any doubt. \n",
"\n",
"In Q# the operation [`M()`](https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.intrinsic.m) can be used to measure a single qubit in the Pauli $Z$ basis. The measurement result is a value of type `Result`: the operation `M` will return `One` if the input qubit was in the $|1\\rangle$ state and `Zero` if the input qubit was in the $|0\\rangle$ state. Since we need to encode the first case as `true` and the second one as `false`, we can return the result of equality comparison between measurement result and `One`."
]
},
{
Expand All @@ -90,6 +90,13 @@
"}"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"[Return to task 1.1 of the Measurements kata.](./Measurements.ipynb#Task-1.1.-$|0\\rangle$-or-$|1\\rangle$?)"
]
},
{
"cell_type": "markdown",
"metadata": {},
Expand All @@ -107,13 +114,11 @@
"source": [
"### Solution\n",
"\n",
"Here we want a method that always returns a qubit in state $|0\\rangle$. \n",
"A fundamental postulate of quantum computing says that when we measure a qubit in a possible superposition state, it will collapse to the state that corresponds to the outcome of the measurement. This means that regardless of the original qubit state, after we measure the qubit in the Pauli $Z$ basis, it will end up in the $|0\\rangle$ or $|1\\rangle$ state. \n",
"\n",
"Regardless of the original qubit state, after we measure the qubit, it will end up in 0 or 1 state, which we then need to convert to the 0 state. Therefore this solution has two possibilities:\n",
"1.\tThe qubit is in state $|0\\rangle$, we don’t need to change anything\n",
"2.\tThe qubit is in state $|1\\rangle$, we need to inverse the state of the qubit\n",
"\n",
"Therefore, if the qubit is in state $|1\\rangle$ we apply the X gate (more information on the X gate in the [BasicGates kata](../BasicGates/BasicGates.ipynb)) to change its state to state $|0\\rangle$."
"After we use the operation `M()` to measure the input qubit in the Pauli $Z$ basis, there are two possibilities:\n",
"1.\tThe qubit collapses to the state $|0\\rangle$ (measurement outcome `Zero`), and we don’t need to change anything.\n",
"2.\tThe qubit collapses to the state $|1\\rangle$ (measurement outcome `One`), and we need to flip the state of the qubit. This can be done with the [**X** gate](../tutorials/SingleQubitGates/SingleQubitGates.ipynb#Pauli-Gates)."
]
},
{
Expand All @@ -131,6 +136,13 @@
"}"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"[Return to task 1.2 of the Measurements kata.](./Measurements.ipynb#Task-1.2.-Set-the-qubit-to-the-$|0\\rangle$-state.)"
]
},
{
"cell_type": "markdown",
"metadata": {},
Expand All @@ -148,12 +160,14 @@
"source": [
"### Solution\n",
"\n",
"The Hadamard gate is used to put the input qubit q in the basis state of the qubit (in other words it puts the qubit in a superposition state), more details on the H gate is explained in the [BasicGates kata](../BasicGates/BasicGates.ipynb). The Hadamard gate converts $|0\\rangle \\longmapsto |+\\rangle$ and $|1\\rangle \\longmapsto |-\\rangle$. Once we have done that the solution is similar to task 1.\n",
"Both input state are superposition states, with equal absolute values of amplitudes of both basis states. This means if the sate is measured in the Pauli $Z$ basis, like we did in the previous task, there is a 50-50 chance of measuring `One` or `Zero`, which won't give us the necessary information. \n",
"\n",
"When we apply the measurement gate M() to a qubit in its basis state it collapses to its corresponding basis vector. \n",
"Since the qubit can be either $|+\\rangle$ (or $H|0\\rangle$) or $|-\\rangle$ (or $H|1\\rangle$) we have two possibilities: \n",
"1. The qubit is $|-\\rangle$, $M(|-\\rangle) = |1\\rangle$, we return `false`.\n",
"2. The qubit is $|+\\rangle$, $M(|+\\rangle) = |0\\rangle$ we return `true`."
"To determine in which state the input qubit is with certainty, we want to transform the qubit into a state where there is no superposition with respect to the basis in which we perform the measurement. \n",
"\n",
"Consider how we can prepare the input states, starting with basis states: $H|0\\rangle = |+\\rangle$ and $H|1\\rangle = |-\\rangle$. \n",
"This transformation can also be undone by applying the **H** gate again (remember that the **H** gate is self-adjoint, i.e., it equals its own inverse): $H|+\\rangle = |0\\rangle$ and $H|-\\rangle = |1\\rangle$.\n",
"\n",
"Once we have the $|0\\rangle$ or $|1\\rangle$ state, we can use the same principle as in task 1.1 to measure the state and report the outcome. Note that in this task return value `true` corresponds to input state $|+\\rangle$, so we compare the measurement result with `Zero`."
]
},
{
Expand All @@ -174,9 +188,9 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Solution 2\n",
"Another possible solution could be to measure in the Pauli $X$ basis (${|+\\rangle, |-\\rangle}$ basis), this means a transformation with the **H** gate before measurement is not needed. Again, measurement result `Zero` would correspond to state $|+\\rangle$.\n",
"\n",
"Pauli measurements allow us to perform a measurement directly in Hadamard basis (meaning that we do not need to perform H(q) before measuring). "
"In Q#, measuring in another Pauli basis can be done with the [`Measure()`](https://docs.microsoft.com/en-us/qsharp/api/qsharp/microsoft.quantum.intrinsic.measure) operation."
]
},
{
Expand All @@ -196,27 +210,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"Pauli measurement is convenient for this task but in general Q# allows only a limited set of measurements so converting to computational basis (as in the first solution) is more universal. However, measurement in terms of Pauli operators can be especially helpful, for example, it is commonly used in the subfield of quantum error correction.\n",
"You can read more on Pauli Measurements here: https://docs.microsoft.com/en-us/quantum/concepts/pauli-measurements?view=qsharp-preview. \n",
"\n",
"The following code is equivalent to `(Measure([PauliX], [q]]) == Zero)`. It uses `within ... apply` to automatically handle the transformation back to the computational basis. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"operation MeasureX (q : Qubit) : Result {\n",
" mutable result = Zero;\n",
" within {\n",
" H(q);\n",
" } apply {\n",
" set result = M(q);\n",
" }\n",
" return result;\n",
"}"
"[Return to task 1.3 of the Measurements kata.](./Measurements.ipynb#Task-1.3.-$|+\\rangle$-or-$|-\\rangle$?)"
]
},
{
Expand All @@ -239,15 +233,17 @@
"source": [
"### Solution\n",
"\n",
"The [Ry](https://docs.microsoft.com/en-us/qsharp/api/qsharp/microsoft.quantum.primitive.ry) gate rotates a single qubit q through an angle $\\alpha$ around the y-axis.\n",
"We take a similar approach to the previous task: figure out a way to prepare the input states from the basis states and apply adjoint of that preparation before measuring the qubit.\n",
"\n",
"To create the input states $|A\\rangle$ and $|B\\rangle$, a [**Ry**](../tutorials/SingleQubitGates/SingleQubitGates.ipynb#Rotation-Gates) gate with $\\theta= 2\\alpha$ was applied to the basis states $|0\\rangle$ and $|1\\rangle$. As a reminder, \n",
"\n",
"$$R_y = \\begin{bmatrix} cos(\\frac{\\theta}{2}) & - sin(\\frac{\\theta}{2}) \\\\ sin(\\frac{\\theta}{2}) & cos(\\frac{\\theta}{2}) \\end{bmatrix}$$\n",
"$$R_y = \\begin{bmatrix} \\cos\\frac{\\theta}{2} & - \\sin\\frac{\\theta}{2} \\\\ \\sin\\frac{\\theta}{2} & \\cos\\frac{\\theta}{2} \\end{bmatrix}$$\n",
"\n",
"In this method we first rotate the qubit q through an angle of $\\alpha$ using the Ry operation.\n",
"We can return the inputs state to the basis sates by applying **Ry** gate with $-2 \\alpha$ as the rotation angle parameter to the input qubit.\n",
"\n",
"Follows two possibilities:\n",
"1. The qubit is measured as $|1\\rangle$, the qubit is in state $|B\\rangle$, we return `false`.\n",
"2. The qubit is measured as $|0\\rangle$, the qubit is in state $|A\\rangle$, we return `true`."
"The measurement in Pauli $Z$ basis gives two possibilities:\n",
"1. The qubit is measured as $|1\\rangle$, the input state was $|B\\rangle$, we return `false`.\n",
"2. The qubit is measured as $|0\\rangle$, the input state was $|A\\rangle$, we return `true`."
]
},
{
Expand All @@ -264,6 +260,13 @@
"}"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"[Return to task 1.4 of the Measurements kata.](./Measurements.ipynb#Task-1.4.-$|A\\rangle$-or-$|B\\rangle$?)"
]
},
{
"cell_type": "markdown",
"metadata": {},
Expand All @@ -281,8 +284,10 @@
"source": [
"### Solution\n",
"\n",
"Both of the qubits stored in the qs array are in the same state ( for $|00\\rangle$ each individual qubit is in state $|0\\rangle$, for $|11\\rangle$ each individual qubit is in state $|1\\rangle$).Therefore, if we measure one qubit we will know the state of the other.\n",
"In other words, if M(qs[0]) measures the first qubit as 1 we know that the qubits in qs are in state $|11\\rangle$ and M(qs[0]) measures the first qubit as 0 we know that the qubits in qs are in state $|00\\rangle$."
"Both qubits in the input array are in the same state: for $|00\\rangle$ each individual qubit is in state $|0\\rangle$, for $|11\\rangle$ each individual qubit is in state $|1\\rangle$. Therefore, if we measure one qubit we will know the state of the other qubit. \n",
"In other words, if the first qubit measures as `One`, we know that the qubits in the input array are in state $|11\\rangle$, and if it measures as `Zero`, we know they are in state $|00\\rangle$.\n",
"\n",
"> `condition ? trueValue | falseValue` is Q#'s ternary operator: it returns `trueValue` if `condition` is true and `falseValue` otherwise."
]
},
{
Expand All @@ -298,6 +303,13 @@
"}"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"[Return to task 1.5 of the Measurements kata.](./Measurements.ipynb#Task-1.5.-$|00\\rangle$-or-$|11\\rangle$?)"
]
},
{
"cell_type": "markdown",
"metadata": {},
Expand All @@ -324,14 +336,15 @@
"source": [
"### Solution\n",
"\n",
"In task 1.5 wrote an operation to measure for the states $|00\\rangle$ and $|11\\rangle$, in this task we need to account for the mix-states $|01\\rangle$ and $|10\\rangle$. This time measuring the first qubit won't give use any information on the second qubit, so we need to measure both qubits. \n",
"m1 store the state of the first qubit and m2 store the state of the second qubit. \n",
"Unlike in the previous task, this time measuring the first qubit won't give us any information on the second qubit, so we need to measure both qubits.\n",
"\n",
"First, we measure both qubits in the input array and store the result in `m1` and `m2`. We can decode these results like this: \n",
"- `m1` is $|0\\rangle$ and `m2` is $|0\\rangle$: we return $0\\cdot2+0 = 0$\n",
"- `m1` is $|0\\rangle$ and `m2` is $|1\\rangle$: we return $0\\cdot2+1 = 1$\n",
"- `m1` is $|1\\rangle$ and `m2` is $|0\\rangle$: we return $1\\cdot2+0 = 2$\n",
"- `m1` is $|1\\rangle$ and `m2` is $|1\\rangle$: we return $1\\cdot2+1 = 3$\n",
"\n",
"Follow 4 possible outputs: \n",
"- m1 is $|0\\rangle$ and m2 is $|0\\rangle$, we return 0*2+0 = 0\n",
"- m1 is $|0\\rangle$ and m2 is $|1\\rangle$, we return 0*2+1 = 1\n",
"- m1 is $|1\\rangle$ and m2 is $|0\\rangle$, we return 1*2+0 = 2\n",
"- m1 is $|1\\rangle$ and m2 is $|1\\rangle$, we return 1*2+1 = 3"
"In other words, we treat the measurement results as the binary notation of the return value in [big endian notation](../tutorials/MultiQubitSystems/MultiQubitSystems.ipynb#Endianness)."
]
},
{
Expand All @@ -350,6 +363,13 @@
"}"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"[Return to task 1.6 of the Measurements kata.](./Measurements.ipynb#Task-1.6.-Distinguish-four-basis-states.)"
]
},
{
"cell_type": "markdown",
"metadata": {},
Expand Down Expand Up @@ -379,7 +399,9 @@
"source": [
"### Solution\n",
"\n",
"Step one is to find first bit strings that differs between bit1 and bit2. For that we use the FindFirstDiff method which loops through booth arrays and return the first value which differs. "
"To solve this task we will use two steps. Like many other programming languages, Q# allows you to write functions to make code more readable and reusable. \n",
"\n",
"The first step is to find first bit that differs between bit strings `bit1` and `bit2`. For that we define a function `FindFirstDiff()` which loops through both `Bool[]`s and returns the first index where the bit strings differ. "
]
},
{
Expand All @@ -388,7 +410,7 @@
"metadata": {},
"outputs": [],
"source": [
"function FindFirstDiff_Reference (bits1 : Bool[], bits2 : Bool[]) : Int {\n",
"function FindFirstDiff (bits1 : Bool[], bits2 : Bool[]) : Int {\n",
" for (i in 0 .. Length(bits1) - 1) {\n",
" if (bits1[i] != bits2[i]) {\n",
" return i;\n",
Expand All @@ -402,11 +424,12 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"Step 2 is the method TwoBitstringsMeasurement, once we have found the first different bit string we check if it is in state $|0\\rangle$ or $|1\\rangle$. If it is in state $|0\\rangle$ `res` takes the value false, if it is in state $|1\\rangle$ it takes the value true. \n",
"`res == bits1[firstDiff] ? 0 | 1` checks if the qubits are in the basis state described by the first or by the second bit string. \n",
"The second step is implementing the main operation: once we have found the first different bit, we measure the qubit in the corresponding position to see whether it is in state $|0\\rangle$ or $|1\\rangle$. If it is in state $|0\\rangle$, `res` takes the value `false`, if it is in state $|1\\rangle$ it takes the value `true`. \n",
"\n",
"`res == bits1[firstDiff]` compares the measurement result with the bit of `bits1` in the differing position. This effectively checks if the qubits are in the basis state described by the first or by the second bit string. \n",
"The two possible outcomes are: \n",
"1. The qubits are in the state described by the first bit string; then `res` will be equal to `bits1[firstDiff]` and the method will return 0. \n",
"2. The qubits are in the state described by the second bit string; then `res` will be not equal to `bits1[firstDiff]` and the method will return 1. "
"1. The qubits are in the state described by the first bit string; then `res` will be equal to `bits1[firstDiff]` and the method will return `0`. \n",
"2. The qubits are in the state described by the second bit string; then `res` will be not equal to `bits1[firstDiff]` (we know it has to be equal to `bits2[firstDiff]` which does not equal `bits1[firstDiff]`), and the method will return `1`. "
]
},
{
Expand All @@ -419,13 +442,20 @@
"\n",
"operation TwoBitstringsMeasurement (qs : Qubit[], bits1 : Bool[], bits2 : Bool[]) : Int {\n",
" // find the first index at which the bit strings are different and measure it\n",
" let firstDiff = FindFirstDiff_Reference(bits1, bits2);\n",
" let firstDiff = FindFirstDiff(bits1, bits2);\n",
" let res = M(qs[firstDiff]) == One;\n",
"\n",
" return res == bits1[firstDiff] ? 0 | 1;\n",
"}"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"[Return to task 1.7 of the Measurements kata.](./Measurements.ipynb#Task-1.7.-Distinguish-two-basis-states-given-by-bit-strings)"
]
},
{
"cell_type": "markdown",
"metadata": {},
Expand Down

0 comments on commit 4988d84

Please sign in to comment.