From 3e12450ec3764011904d63b52f58e0bcdd3fc48b Mon Sep 17 00:00:00 2001 From: Sai Seshu Chadaram Date: Sun, 9 Jan 2022 12:27:45 +0530 Subject: [PATCH 1/4] Add Workbook for RandomNumberGenerationTutorial --- .../RandomNumberGenerationTutorial.ipynb | 37 +- ...kbook_RandomNumberGenerationTutorial.ipynb | 486 ++++++++++++++++++ 2 files changed, 522 insertions(+), 1 deletion(-) create mode 100644 tutorials/RandomNumberGeneration/Workbook_RandomNumberGenerationTutorial.ipynb diff --git a/tutorials/RandomNumberGeneration/RandomNumberGenerationTutorial.ipynb b/tutorials/RandomNumberGeneration/RandomNumberGenerationTutorial.ipynb index 0c5d9d5b9fa..aecbd6b0b76 100644 --- a/tutorials/RandomNumberGeneration/RandomNumberGenerationTutorial.ipynb +++ b/tutorials/RandomNumberGeneration/RandomNumberGenerationTutorial.ipynb @@ -77,6 +77,13 @@ "}" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "*Can't come up with a solution? See the explained solution in the [Quantum Random Number Generation Workbook](./Workbook_RandomNumberGenerationTutorial#Exercise-1:-Generate-a-single-random-bit).*" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -111,6 +118,13 @@ "}" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "*Can't come up with a solution? See the explained solution in the [Quantum Random Number Generation Workbook](./Workbook_RandomNumberGenerationTutorial#Exercise-2:-Generate-a-random-two-bit-number).*" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -147,6 +161,13 @@ "}" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "*Can't come up with a solution? See the explained solution in the [Quantum Random Number Generation Workbook](./Workbook_RandomNumberGenerationTutorial#Exercise-3:-Generate-a-number-of-arbitrary-size).*" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -182,6 +203,13 @@ "}" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "*Can't come up with a solution? See the explained solution in the [Quantum Random Number Generation Workbook](./Workbook_RandomNumberGenerationTutorial#Exercise-4:-Generate-a-weighted-bit!).*" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -213,6 +241,13 @@ "}" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "*Can't come up with a solution? See the explained solution in the [Quantum Random Number Generation Workbook](./Workbook_RandomNumberGenerationTutorial#Exercise-5:-Generate-a-random-number-between-min-and-max).*" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -228,7 +263,7 @@ "kernelspec": { "display_name": "Q#", "language": "qsharp", - "name": "iqsharp" + "name": "python397jvsc74a57bd014c3e56b66ef9510473afa497f82c7327768413245b0a072dd00e5e2b81ba611" }, "language_info": { "file_extension": ".qs", diff --git a/tutorials/RandomNumberGeneration/Workbook_RandomNumberGenerationTutorial.ipynb b/tutorials/RandomNumberGeneration/Workbook_RandomNumberGenerationTutorial.ipynb new file mode 100644 index 00000000000..b75c86a549c --- /dev/null +++ b/tutorials/RandomNumberGeneration/Workbook_RandomNumberGenerationTutorial.ipynb @@ -0,0 +1,486 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "de2a01f0", + "metadata": {}, + "source": [ + "# Quantum Random Number Generation Workbook\n", + "\n", + "**What is this workbook?**\n", + "A workbook is a collection of problems, accompanied by solutions to them. \n", + "The explanations focus on the logical steps required to solve a problem; they illustrate the concepts that need to be applied to come up with a solution to the problem, explaining the mathematical steps required. \n", + "\n", + "Note that a workbook should not be the primary source of knowledge on the subject matter; it assumes that you've already read a tutorial or a textbook and that you are now seeking to improve your problem-solving skills. You should attempt solving the tasks of the respective kata first, and turn to the workbook only if stuck. While a textbook emphasizes knowledge acquisition, a workbook emphasizes skill acquisition.\n", + "\n", + "This workbook describes the solutions to the problems offered in the [Random Number Generation Tutorial](./RandomNumberGenerationTutorial.ipynb). \n", + "Since the tasks are offered as programming problems, the explanations also cover some elements of Q# that might be non-obvious for a first-time user.\n", + "\n", + "**What you should know for this workbook**\n", + "\n", + "You should be familiar with the following concepts before tackling the Quantum Random Number Generation Tutorial (and this workbook):\n", + "\n", + "1. The concept of qubit and measurement\n", + "2. Single qubit gates" + ] + }, + { + "cell_type": "markdown", + "id": "3a818402", + "metadata": {}, + "source": [ + "## Exercise 1: Generate a single random bit\n", + "\n", + "**Input:** None.\n", + "\n", + "**Goal:** Generate a $0$ or $1$ with equal probability.\n", + "\n", + "
\n", + " Need a hint? Click here\n", + " Use the allocated qubit, apply a quantum gate to it, measure it and use the result to return a $0$ or $1$.\n", + "
\n", + "\n", + "**Stretch goal:** Can you find a different way to implement this operation?\n", + "\n", + "
\n", + " Need a hint? Click here\n", + " What are the different quantum states that produce $0$ and $1$ measurement results with the same probability? How would measuring the qubit in a different basis change the result? \n", + "
\n" + ] + }, + { + "cell_type": "markdown", + "id": "6368dcd7", + "metadata": {}, + "source": [ + "### Solution\n", + "\n", + "The state of single qubit can be represented two-dimensional column vector $\\begin{bmatrix} \\alpha\\\\ \\beta \\end{bmatrix}$. Where $\\alpha$ and $\\beta$ are complex numbers. When we measure the qubit, we get either 0 with probability $|\\alpha|^2$ (or) 1 with probability $|\\beta|^2$. Essentially we can control probablity of measurement outcome by setting right amplitudes of basis states $\\alpha$ and $\\beta$. \n", + "\n", + "When we initilize qubit, amplitudes $\\alpha$ and $\\beta$ are 1 and 0 respectively. Now our goal is set equal amplitudes for $\\alpha$ and $\\beta$ for absolute randomness. We can achieve that by simply applying Hadamard gate on the base state.\n", + "\n", + "$$\n", + "H|0\\rangle=\n", + "\\frac{1}{\\sqrt{2}}\\begin{bmatrix}\n", + " 1 & 1 \\\\\n", + " 1 & -1\n", + " \\end{bmatrix}\n", + " \\begin{bmatrix}\n", + " 1\\\\\n", + " 0\\\\\n", + " \\end{bmatrix}\n", + "=\n", + "\\frac{1}{\\sqrt{2}}\\begin{bmatrix}\n", + " 1 \\cdot 1 + 1 \\cdot 0 \\\\\n", + " 1 \\cdot 1 + (-1) \\cdot 0\n", + " \\end{bmatrix}\n", + "=\n", + " \\frac{1}{\\sqrt{2}}\\begin{bmatrix}\n", + " 1\\\\\n", + " 1\n", + " \\end{bmatrix}\n", + "$$\n", + "\n", + "Now, both 0 and 1 outcomes are with equal probablity of $|\\frac{1}{\\sqrt{2}}|^2 = \\frac{1}{2}$.\n", + "\n", + "> Note: Since probablity is mod squared of amplitude, we will get same randomness by applying Hadamard gate on $|1\\rangle$. Try it out as optional exercise." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "f41d8e8c", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Testing one random bit generation...\n", + "Test passed\n" + ] + }, + { + "data": { + "application/x-qsharp-data": "\"Success!\"", + "text/plain": [ + "Success!" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%kata T1_RandomBit\n", + "\n", + "operation RandomBit () : Int {\n", + " // Allocate single qubit\n", + " use q = Qubit();\n", + " \n", + " // Set qubit in superposition state\n", + " H(q);\n", + " \n", + " // Measuring state of qubit and return integer value of result\n", + " return (M(q) == Zero) ? 0 | 1;\n", + "}" + ] + }, + { + "cell_type": "markdown", + "id": "32591a36", + "metadata": {}, + "source": [ + "## Exercise 2: Generate a random two-bit number\n", + "\n", + "Now that you can generate a single random bit, you can use that logic to create random multi-bit numbers. Let's try first to make a two-bit number by combining two randomly generated bits.\n", + "\n", + "**Input:** None.\n", + "\n", + "**Goal:** Generate a random number in the range $[0, 3]$ with an equal probability of getting each of the four numbers.\n", + "\n", + "**Stretch goal:** Can you do this without allocating qubits in this operation?\n", + "\n", + "
\n", + " Need a hint? Click here\n", + " Remember that you can use the previously defined operations.\n", + "
" + ] + }, + { + "cell_type": "markdown", + "id": "e9d4f69c", + "metadata": {}, + "source": [ + "### Solution\n", + "\n", + "Reusing `RandomBit` operation from [Exercise 1](#Exercise-1:-Generate-a-single-random-bit), calling twice to generate random two-bit number." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "46368ef1", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Expecting only one Q# operation in code. Using the first one\n", + "Testing two random bits generation...\n", + "Unexpected number generated. Expected values from 0 to 3, generated -1\n", + "Unexpected number generated. Expected values from 0 to 3, generated -1\n", + "Unexpected number generated. Expected values from 0 to 3, generated -1\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Failed to generate sufficiently random integer\n", + "Try again!\n" + ] + } + ], + "source": [ + "%kata T2_RandomTwoBits\n", + "\n", + "operation RandomBit () : Int {\n", + " // Allocate single qubit\n", + " use q = Qubit();\n", + " \n", + " // Set qubit in superposition state\n", + " H(q);\n", + " \n", + " // Measuring state of qubit and return integer value of result\n", + " return (M(q) == Zero) ? 0 | 1;\n", + "}\n", + "\n", + "operation RandomTwoBits () : Int {\n", + " return 2 * RandomBit() + RandomBit();\n", + "}" + ] + }, + { + "cell_type": "markdown", + "id": "69315416", + "metadata": {}, + "source": [ + "## Exercise 3: Generate a number of arbitrary size\n", + "\n", + "Let's take it a step further and generate an $N$-bit number. \n", + "\n", + "> Remember that you can use previously defined operations in your solution.\n", + "\n", + "**Input:** An integer $N$ ($1 \\le N \\le 10$).\n", + "\n", + "**Goal:** Generate a random number in the range $[0, 2^N - 1]$ with an equal probability of getting each of the numbers in this range.\n", + "\n", + "> Useful Q# documentation: \n", + "> * [`for` loops](https://docs.microsoft.com/azure/quantum/user-guide/language/statements/iterations), \n", + "> * [mutable variables](https://docs.microsoft.com/azure/quantum/user-guide/language/typesystem/immutability), \n", + "> * [exponents](https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math.powi)." + ] + }, + { + "cell_type": "markdown", + "id": "0b6ca4ea", + "metadata": {}, + "source": [ + "### Solution\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "2d7c6758", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Expecting only one Q# operation in code. Using the first one\n", + "Testing N = 1...\n", + "Unexpected number generated. Expected values from 0 to 1, generated -1\n", + "Unexpected number generated. Expected values from 0 to 1, generated -1\n", + "Unexpected number generated. Expected values from 0 to 1, generated -1\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Failed to generate sufficiently random integer\n", + "Try again!\n" + ] + } + ], + "source": [ + "%kata T3_RandomNBits \n", + "\n", + "open Microsoft.Quantum.Math;\n", + "\n", + "operation RandomBit () : Int {\n", + " // Allocate single qubit\n", + " use q = Qubit();\n", + " \n", + " // Set qubit in superposition state\n", + " H(q);\n", + " \n", + " // Measuring state of qubit and return integer value of result\n", + " return (M(q) == Zero) ? 0 | 1;\n", + "}\n", + "\n", + "operation RandomNBits (N : Int) : Int {\n", + " // Set max as 2 ^ N - 1\n", + " let max = PowI(2, N) - 1;\n", + "\n", + " // Declare result variable with mutable binding\n", + " mutable result = 0;\n", + "\n", + " repeat {\n", + " set result = 0;\n", + "\n", + " for index in 1 .. N {\n", + " set result = (result * 2) + RandomBit();\n", + " }\n", + " } until (result <= max);\n", + "\n", + " return result;\n", + "}" + ] + }, + { + "cell_type": "markdown", + "id": "e0363ec2", + "metadata": {}, + "source": [ + "## Exercise 4: Generate a weighted bit!\n", + "\n", + "In each of the above exercises, all generated numbers were equally likely. Now let's create an operation that will return a random bit with different probabilities of outcomes. \n", + "\n", + "> Remember that by setting amplitudes of basis states $\\alpha$ and $\\beta$, we can control the probability of getting measurement outcomes $0$ and $1$ when the qubit is measured.\n", + "\n", + "**Input:** \n", + "A floating-point number $x$, $0 \\le x \\le 1$. \n", + "\n", + "**Goal:** Generate $0$ or $1$ with probability of $0$ equal to $x$ and probability of $1$ equal to $1 - x$.\n", + "\n", + "> Useful Q# documentation: \n", + "> * [`Math` namespace](https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math)\n", + "> * [`ArcCos` function](https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math.arccos)\n", + "> * [`Sqrt` function](https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math.sqrt)\n" + ] + }, + { + "cell_type": "markdown", + "id": "8656006c", + "metadata": {}, + "source": [ + "### Solution\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "fcb1799c", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Testing generating zero with 0% probability...\n", + "Test passed for generating zero with 0% probability\n", + "Testing generating zero with 25% probability...\n", + "Test passed for generating zero with 25% probability\n", + "Testing generating zero with 50% probability...\n", + "Test passed for generating zero with 50% probability\n", + "Testing generating zero with 75% probability...\n", + "Test passed for generating zero with 75% probability\n", + "Testing generating zero with 100% probability...\n", + "Test passed for generating zero with 100% probability\n" + ] + }, + { + "data": { + "application/x-qsharp-data": "\"Success!\"", + "text/plain": [ + "Success!" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%kata T4_WeightedRandomBit\n", + "\n", + "open Microsoft.Quantum.Math;\n", + "\n", + "operation WeightedRandomBit (x : Double) : Int {\n", + " // Set theta as \n", + " let theta = 2.0 * ArcCos(Sqrt(x));\n", + "\n", + " // Allocate single qubit\n", + " use q = Qubit();\n", + "\n", + " // Set qubit in superposition state which aligns with given probabilities\n", + " Ry(theta, q);\n", + "\n", + " // Measuring state of qubit and return integer value of result\n", + " return M(q) == Zero ? 0 | 1;\n", + "}" + ] + }, + { + "cell_type": "markdown", + "id": "82e05283", + "metadata": {}, + "source": [ + "## Exercise 5: Generate a random number between min and max\n", + "\n", + "In exercise 3, we generated numbers in the range $[0, 2^N-1]$ $(1 \\leq N \\leq 10)$. Now let's create an operation that will return a random number in the range $[min, max]$. \n", + "\n", + "**Input:** \n", + "Two integers $min$ and $max$ ($0 \\leq min \\leq max \\leq 2^{10}-1$).\n", + "\n", + "**Goal:** Generate a random number in the range $[min, max]$ with an equal probability of getting each of the numbers in this range.\n", + "\n", + "> Useful Q# documentation: \n", + "> * [`BitSizeI` function](https://docs.microsoft.com/en-us/qsharp/api/qsharp/microsoft.quantum.math.bitsizei)" + ] + }, + { + "cell_type": "markdown", + "id": "663bc636", + "metadata": {}, + "source": [ + "### Solution\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "9dba8758", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Expecting only one Q# operation in code. Using the first one\n", + "Testing for min = 1 and max = 3...\n", + "Unexpected number generated. Expected values from 1 to 3, generated -1\n", + "Unexpected number generated. Expected values from 1 to 3, generated -1\n", + "Unexpected number generated. Expected values from 1 to 3, generated -1\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Failed to generate sufficiently random integer\n", + "Try again!\n" + ] + } + ], + "source": [ + "%kata T5_RandomNumberInRange\n", + "\n", + "open Microsoft.Quantum.Math;\n", + "\n", + "operation RandomBit () : Int {\n", + " // Allocate single qubit\n", + " use q = Qubit();\n", + " \n", + " // Set qubit in superposition state\n", + " H(q);\n", + " \n", + " // Measuring state of qubit and return integer value of result\n", + " return (M(q) == Zero) ? 0 | 1;\n", + "}\n", + "\n", + "operation RandomNumberInRange (min : Int, max : Int) : Int {\n", + " // Set N as bitsize of max\n", + " let N = BitSizeI(max);\n", + "\n", + " // Declare result variable with mutable binding\n", + " mutable result = 0;\n", + " \n", + " repeat {\n", + " set result = 0;\n", + "\n", + " for index in 1 .. N {\n", + " set result = (result * 2) + RandomBit();\n", + " }\n", + " } until (result >= min and result <= max);\n", + "\n", + " return result;\n", + "}" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Q#", + "language": "qsharp", + "name": "python397jvsc74a57bd014c3e56b66ef9510473afa497f82c7327768413245b0a072dd00e5e2b81ba611" + }, + "language_info": { + "file_extension": ".qs", + "mimetype": "text/x-qsharp", + "name": "qsharp", + "version": "0.14" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From c8f180b6056acba5a5fd89d50f10ea775fe6125e Mon Sep 17 00:00:00 2001 From: Sai Seshu Chadaram Date: Sun, 9 Jan 2022 21:37:17 +0530 Subject: [PATCH 2/4] Update Workbook for RandomNumberGenerationTutorial --- .../RandomNumberGenerationTutorial.ipynb | 2 +- ...kbook_RandomNumberGenerationTutorial.ipynb | 214 +++++------------- 2 files changed, 55 insertions(+), 161 deletions(-) diff --git a/tutorials/RandomNumberGeneration/RandomNumberGenerationTutorial.ipynb b/tutorials/RandomNumberGeneration/RandomNumberGenerationTutorial.ipynb index aecbd6b0b76..cc9bc3bd2ff 100644 --- a/tutorials/RandomNumberGeneration/RandomNumberGenerationTutorial.ipynb +++ b/tutorials/RandomNumberGeneration/RandomNumberGenerationTutorial.ipynb @@ -263,7 +263,7 @@ "kernelspec": { "display_name": "Q#", "language": "qsharp", - "name": "python397jvsc74a57bd014c3e56b66ef9510473afa497f82c7327768413245b0a072dd00e5e2b81ba611" + "name": "iqsharp" }, "language_info": { "file_extension": ".qs", diff --git a/tutorials/RandomNumberGeneration/Workbook_RandomNumberGenerationTutorial.ipynb b/tutorials/RandomNumberGeneration/Workbook_RandomNumberGenerationTutorial.ipynb index b75c86a549c..a62533f1b30 100644 --- a/tutorials/RandomNumberGeneration/Workbook_RandomNumberGenerationTutorial.ipynb +++ b/tutorials/RandomNumberGeneration/Workbook_RandomNumberGenerationTutorial.ipynb @@ -57,7 +57,7 @@ "\n", "The state of single qubit can be represented two-dimensional column vector $\\begin{bmatrix} \\alpha\\\\ \\beta \\end{bmatrix}$. Where $\\alpha$ and $\\beta$ are complex numbers. When we measure the qubit, we get either 0 with probability $|\\alpha|^2$ (or) 1 with probability $|\\beta|^2$. Essentially we can control probablity of measurement outcome by setting right amplitudes of basis states $\\alpha$ and $\\beta$. \n", "\n", - "When we initilize qubit, amplitudes $\\alpha$ and $\\beta$ are 1 and 0 respectively. Now our goal is set equal amplitudes for $\\alpha$ and $\\beta$ for absolute randomness. We can achieve that by simply applying Hadamard gate on the base state.\n", + "When we initilize qubit, amplitudes $\\alpha$ and $\\beta$ are 1 and 0 respectively. Now our goal is set equal amplitudes for $\\alpha$ and $\\beta$ for absolute randomness. We can achieve that by simply applying Hadamard gate on initial state $|0\\rangle$.\n", "\n", "$$\n", "H|0\\rangle=\n", @@ -83,35 +83,15 @@ "\n", "Now, both 0 and 1 outcomes are with equal probablity of $|\\frac{1}{\\sqrt{2}}|^2 = \\frac{1}{2}$.\n", "\n", - "> Note: Since probablity is mod squared of amplitude, we will get same randomness by applying Hadamard gate on $|1\\rangle$. Try it out as optional exercise." + "> Note: Since probablity is mod squared of amplitude, we will get same randomness by applying Hadamard gate on base state $|1\\rangle$. Try it out as optional exercise." ] }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "id": "f41d8e8c", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Testing one random bit generation...\n", - "Test passed\n" - ] - }, - { - "data": { - "application/x-qsharp-data": "\"Success!\"", - "text/plain": [ - "Success!" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "%kata T1_RandomBit\n", "\n", @@ -155,49 +135,20 @@ "source": [ "### Solution\n", "\n", - "Reusing `RandomBit` operation from [Exercise 1](#Exercise-1:-Generate-a-single-random-bit), calling twice to generate random two-bit number." + "Reusing `RandomBit` operation from [Exercise 1](#Exercise-1:-Generate-a-single-random-bit). \n", + "\n", + "Generate two random bits by calling `RandomBit` operation twice. Multiple most significant bit with 2 and add second random bit to generate random two-bit number." ] }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "id": "46368ef1", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Expecting only one Q# operation in code. Using the first one\n", - "Testing two random bits generation...\n", - "Unexpected number generated. Expected values from 0 to 3, generated -1\n", - "Unexpected number generated. Expected values from 0 to 3, generated -1\n", - "Unexpected number generated. Expected values from 0 to 3, generated -1\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Failed to generate sufficiently random integer\n", - "Try again!\n" - ] - } - ], + "outputs": [], "source": [ "%kata T2_RandomTwoBits\n", "\n", - "operation RandomBit () : Int {\n", - " // Allocate single qubit\n", - " use q = Qubit();\n", - " \n", - " // Set qubit in superposition state\n", - " H(q);\n", - " \n", - " // Measuring state of qubit and return integer value of result\n", - " return (M(q) == Zero) ? 0 | 1;\n", - "}\n", - "\n", "operation RandomTwoBits () : Int {\n", " return 2 * RandomBit() + RandomBit();\n", "}" @@ -230,51 +181,23 @@ "metadata": {}, "source": [ "### Solution\n", - "\n" + "\n", + "Reusing `RandomBit` operation from [Exercise 1](#Exercise-1:-Generate-a-single-random-bit).\n", + "\n", + "Generate N random bits by calling `RandomBit` operation N times. Multiple resulted bit array with 2 powers to convert it into integer. Repeat this process until $result <= max$, where max equal to $2^N - 1$." ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "id": "2d7c6758", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Expecting only one Q# operation in code. Using the first one\n", - "Testing N = 1...\n", - "Unexpected number generated. Expected values from 0 to 1, generated -1\n", - "Unexpected number generated. Expected values from 0 to 1, generated -1\n", - "Unexpected number generated. Expected values from 0 to 1, generated -1\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Failed to generate sufficiently random integer\n", - "Try again!\n" - ] - } - ], + "outputs": [], "source": [ "%kata T3_RandomNBits \n", "\n", "open Microsoft.Quantum.Math;\n", "\n", - "operation RandomBit () : Int {\n", - " // Allocate single qubit\n", - " use q = Qubit();\n", - " \n", - " // Set qubit in superposition state\n", - " H(q);\n", - " \n", - " // Measuring state of qubit and return integer value of result\n", - " return (M(q) == Zero) ? 0 | 1;\n", - "}\n", - "\n", "operation RandomNBits (N : Int) : Int {\n", " // Set max as 2 ^ N - 1\n", " let max = PowI(2, N) - 1;\n", @@ -322,51 +245,50 @@ "metadata": {}, "source": [ "### Solution\n", - "\n" + "\n", + "We already learnt how to generate random bit with equal probability in exercise 1, in this exercise we need to generate random bit with weighted probability.\n", + "\n", + "It is known that arbitrary single qubit state can be written as:\n", + "\n", + "$$\n", + "|\\psi\\rangle =\n", + " \\cos \\frac{\\theta}{2} |0 \\rangle \\, + \\, e^{i\\phi} \\sin \\frac{\\theta}{2} |1\\rangle\n", + "$$\n", + "\n", + "Where $\\theta$ is angle between state vector and $z-axis$, and $\\phi$ is longitude angle with respect to $x-axis$.\n", + "\n", + "Our goal is to generate 0 or 1 with probability equals to $x$ and probability of 1 equal to (1 - $x$), which means qubit state should look like\n", + "\n", + "$$\n", + "|\\psi\\rangle =\n", + " \\sqrt x |0 \\rangle \\, + \\sqrt (1 - x) |1\\rangle\n", + "$$\n", + "\n", + "By comparing state $|0 \\rangle$ on both equations\n", + "\n", + "$$\n", + "\\Rightarrow \\sqrt x = \\cos \\frac{\\theta}{2} \\\\ \\Rightarrow \\theta = 2 * \\arccos(\\sqrt x)\n", + "$$\n", + "\n", + "Since $\\theta$ is angle between state vector and $z-axis$, we need to apply [$Ry$](https://docs.microsoft.com/en-us/qsharp/api/qsharp/microsoft.quantum.intrinsic.ry) gate with caculated $\\theta$ on base state $|0 \\rangle$ to get desired qubit state.\n", + "\n", + "$Ry$ operation applies a given rotation about $y-axis$ (i.e. $zx-plane$), hence $\\phi$ is always equal to $0^{\\circ}$, which means $e^{i\\phi}$ value doesn't have any impact on qubit state." ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "id": "fcb1799c", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Testing generating zero with 0% probability...\n", - "Test passed for generating zero with 0% probability\n", - "Testing generating zero with 25% probability...\n", - "Test passed for generating zero with 25% probability\n", - "Testing generating zero with 50% probability...\n", - "Test passed for generating zero with 50% probability\n", - "Testing generating zero with 75% probability...\n", - "Test passed for generating zero with 75% probability\n", - "Testing generating zero with 100% probability...\n", - "Test passed for generating zero with 100% probability\n" - ] - }, - { - "data": { - "application/x-qsharp-data": "\"Success!\"", - "text/plain": [ - "Success!" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "%kata T4_WeightedRandomBit\n", "\n", "open Microsoft.Quantum.Math;\n", "\n", "operation WeightedRandomBit (x : Double) : Int {\n", - " // Set theta as \n", - " let theta = 2.0 * ArcCos(Sqrt(x));\n", + " // Calculate theta value\n", + " let theta = 2.0 * ArcCos(Sqrt(x)); // (or) 2.0 * ArcSin(Sqrt(1.0 - x));\n", "\n", " // Allocate single qubit\n", " use q = Qubit();\n", @@ -403,51 +325,23 @@ "metadata": {}, "source": [ "### Solution\n", - "\n" + "\n", + "Reusing `RandomBit` operation from [Exercise 1](#Exercise-1:-Generate-a-single-random-bit).\n", + "\n", + "Generate N random bits by calling `RandomBit` operation N times, where N is bitsize of max. Multiple resulted bit array with 2 powers to convert it into integer. Repeat this process until $min <= result <= max$." ] }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "id": "9dba8758", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Expecting only one Q# operation in code. Using the first one\n", - "Testing for min = 1 and max = 3...\n", - "Unexpected number generated. Expected values from 1 to 3, generated -1\n", - "Unexpected number generated. Expected values from 1 to 3, generated -1\n", - "Unexpected number generated. Expected values from 1 to 3, generated -1\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Failed to generate sufficiently random integer\n", - "Try again!\n" - ] - } - ], + "outputs": [], "source": [ "%kata T5_RandomNumberInRange\n", "\n", "open Microsoft.Quantum.Math;\n", "\n", - "operation RandomBit () : Int {\n", - " // Allocate single qubit\n", - " use q = Qubit();\n", - " \n", - " // Set qubit in superposition state\n", - " H(q);\n", - " \n", - " // Measuring state of qubit and return integer value of result\n", - " return (M(q) == Zero) ? 0 | 1;\n", - "}\n", - "\n", "operation RandomNumberInRange (min : Int, max : Int) : Int {\n", " // Set N as bitsize of max\n", " let N = BitSizeI(max);\n", @@ -472,7 +366,7 @@ "kernelspec": { "display_name": "Q#", "language": "qsharp", - "name": "python397jvsc74a57bd014c3e56b66ef9510473afa497f82c7327768413245b0a072dd00e5e2b81ba611" + "name": "python397jvsc74a57bd03e9cfe3d963c99b47f4bef33d8f4894f84aa18ba42c00cfbe95b5fec776fa20c" }, "language_info": { "file_extension": ".qs", From 709593f7d0170d85d79eea5056460e262e205949 Mon Sep 17 00:00:00 2001 From: Sai Seshu Chadaram Date: Tue, 11 Jan 2022 15:40:41 +0530 Subject: [PATCH 3/4] Fixing markdown formatting --- .../Workbook_RandomNumberGenerationTutorial.ipynb | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tutorials/RandomNumberGeneration/Workbook_RandomNumberGenerationTutorial.ipynb b/tutorials/RandomNumberGeneration/Workbook_RandomNumberGenerationTutorial.ipynb index a62533f1b30..bacb6ac0c92 100644 --- a/tutorials/RandomNumberGeneration/Workbook_RandomNumberGenerationTutorial.ipynb +++ b/tutorials/RandomNumberGeneration/Workbook_RandomNumberGenerationTutorial.ipynb @@ -55,7 +55,7 @@ "source": [ "### Solution\n", "\n", - "The state of single qubit can be represented two-dimensional column vector $\\begin{bmatrix} \\alpha\\\\ \\beta \\end{bmatrix}$. Where $\\alpha$ and $\\beta$ are complex numbers. When we measure the qubit, we get either 0 with probability $|\\alpha|^2$ (or) 1 with probability $|\\beta|^2$. Essentially we can control probablity of measurement outcome by setting right amplitudes of basis states $\\alpha$ and $\\beta$. \n", + "The state of single qubit can be represented two-dimensional column vector $\\begin{bmatrix} \\alpha\\\\ \\beta \\end{bmatrix}$. Where $\\alpha$ and $\\beta$ are complex numbers. When we measure the qubit, we get either 0 with probability $|\\alpha|^2$ (or) 1 with probability $|\\beta|^2$. Essentially we can control probablity of measurement outcome by setting right amplitudes of basis states. \n", "\n", "When we initilize qubit, amplitudes $\\alpha$ and $\\beta$ are 1 and 0 respectively. Now our goal is set equal amplitudes for $\\alpha$ and $\\beta$ for absolute randomness. We can achieve that by simply applying Hadamard gate on initial state $|0\\rangle$.\n", "\n", @@ -272,7 +272,9 @@ "\n", "Since $\\theta$ is angle between state vector and $z-axis$, we need to apply [$Ry$](https://docs.microsoft.com/en-us/qsharp/api/qsharp/microsoft.quantum.intrinsic.ry) gate with caculated $\\theta$ on base state $|0 \\rangle$ to get desired qubit state.\n", "\n", - "$Ry$ operation applies a given rotation about $y-axis$ (i.e. $zx-plane$), hence $\\phi$ is always equal to $0^{\\circ}$, which means $e^{i\\phi}$ value doesn't have any impact on qubit state." + "$Ry$ operation applies a given rotation about $y-axis$ (i.e. $zx-plane$), hence $\\phi$ (longitude angle with respect to $x-axis$) value is always equal to $0^{\\circ}$, which means $e^{i\\phi}$ value doesn't have any impact on resultant qubit state.\n", + "\n", + "> We can also calculate ${\\theta}$ by comparing state $|1 \\rangle$ on both equations, which is $2.0 * \\arcsin(\\sqrt(1.0 - x))$" ] }, { @@ -366,7 +368,7 @@ "kernelspec": { "display_name": "Q#", "language": "qsharp", - "name": "python397jvsc74a57bd03e9cfe3d963c99b47f4bef33d8f4894f84aa18ba42c00cfbe95b5fec776fa20c" + "name": "iqsharp" }, "language_info": { "file_extension": ".qs", From c15553e449419cf23687bccd7e973950e9b22e66 Mon Sep 17 00:00:00 2001 From: Mariia Mykhailova Date: Fri, 14 Jan 2022 18:17:34 -0800 Subject: [PATCH 4/4] A bit of polish --- .../RandomNumberGenerationTutorial.ipynb | 10 +- ...kbook_RandomNumberGenerationTutorial.ipynb | 155 ++++++++---------- 2 files changed, 70 insertions(+), 95 deletions(-) diff --git a/tutorials/RandomNumberGeneration/RandomNumberGenerationTutorial.ipynb b/tutorials/RandomNumberGeneration/RandomNumberGenerationTutorial.ipynb index cc9bc3bd2ff..448ae0a372a 100644 --- a/tutorials/RandomNumberGeneration/RandomNumberGenerationTutorial.ipynb +++ b/tutorials/RandomNumberGeneration/RandomNumberGenerationTutorial.ipynb @@ -81,7 +81,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "*Can't come up with a solution? See the explained solution in the [Quantum Random Number Generation Workbook](./Workbook_RandomNumberGenerationTutorial#Exercise-1:-Generate-a-single-random-bit).*" + "*Can't come up with a solution? See the explained solution in the [Quantum Random Number Generation Workbook](./Workbook_RandomNumberGenerationTutorial.ipynb#Exercise-1:-Generate-a-single-random-bit).*" ] }, { @@ -122,7 +122,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "*Can't come up with a solution? See the explained solution in the [Quantum Random Number Generation Workbook](./Workbook_RandomNumberGenerationTutorial#Exercise-2:-Generate-a-random-two-bit-number).*" + "*Can't come up with a solution? See the explained solution in the [Quantum Random Number Generation Workbook](./Workbook_RandomNumberGenerationTutorial.ipynb#Exercise-2:-Generate-a-random-two-bit-number).*" ] }, { @@ -165,7 +165,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "*Can't come up with a solution? See the explained solution in the [Quantum Random Number Generation Workbook](./Workbook_RandomNumberGenerationTutorial#Exercise-3:-Generate-a-number-of-arbitrary-size).*" + "*Can't come up with a solution? See the explained solution in the [Quantum Random Number Generation Workbook](./Workbook_RandomNumberGenerationTutorial.ipynb#Exercise-3:-Generate-a-number-of-arbitrary-size).*" ] }, { @@ -207,7 +207,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "*Can't come up with a solution? See the explained solution in the [Quantum Random Number Generation Workbook](./Workbook_RandomNumberGenerationTutorial#Exercise-4:-Generate-a-weighted-bit!).*" + "*Can't come up with a solution? See the explained solution in the [Quantum Random Number Generation Workbook](./Workbook_RandomNumberGenerationTutorial.ipynb#Exercise-4:-Generate-a-weighted-bit!).*" ] }, { @@ -245,7 +245,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "*Can't come up with a solution? See the explained solution in the [Quantum Random Number Generation Workbook](./Workbook_RandomNumberGenerationTutorial#Exercise-5:-Generate-a-random-number-between-min-and-max).*" + "*Can't come up with a solution? See the explained solution in the [Quantum Random Number Generation Workbook](./Workbook_RandomNumberGenerationTutorial.ipynb#Exercise-5:-Generate-a-random-number-between-min-and-max).*" ] }, { diff --git a/tutorials/RandomNumberGeneration/Workbook_RandomNumberGenerationTutorial.ipynb b/tutorials/RandomNumberGeneration/Workbook_RandomNumberGenerationTutorial.ipynb index bacb6ac0c92..e5047dcd54b 100644 --- a/tutorials/RandomNumberGeneration/Workbook_RandomNumberGenerationTutorial.ipynb +++ b/tutorials/RandomNumberGeneration/Workbook_RandomNumberGenerationTutorial.ipynb @@ -2,7 +2,6 @@ "cells": [ { "cell_type": "markdown", - "id": "de2a01f0", "metadata": {}, "source": [ "# Quantum Random Number Generation Workbook\n", @@ -21,12 +20,11 @@ "You should be familiar with the following concepts before tackling the Quantum Random Number Generation Tutorial (and this workbook):\n", "\n", "1. The concept of qubit and measurement\n", - "2. Single qubit gates" + "2. Single-qubit gates" ] }, { "cell_type": "markdown", - "id": "3a818402", "metadata": {}, "source": [ "## Exercise 1: Generate a single random bit\n", @@ -35,29 +33,18 @@ "\n", "**Goal:** Generate a $0$ or $1$ with equal probability.\n", "\n", - "
\n", - " Need a hint? Click here\n", - " Use the allocated qubit, apply a quantum gate to it, measure it and use the result to return a $0$ or $1$.\n", - "
\n", - "\n", - "**Stretch goal:** Can you find a different way to implement this operation?\n", - "\n", - "
\n", - " Need a hint? Click here\n", - " What are the different quantum states that produce $0$ and $1$ measurement results with the same probability? How would measuring the qubit in a different basis change the result? \n", - "
\n" + "**Stretch goal:** Can you find a different way to implement this operation?" ] }, { "cell_type": "markdown", - "id": "6368dcd7", "metadata": {}, "source": [ "### Solution\n", "\n", - "The state of single qubit can be represented two-dimensional column vector $\\begin{bmatrix} \\alpha\\\\ \\beta \\end{bmatrix}$. Where $\\alpha$ and $\\beta$ are complex numbers. When we measure the qubit, we get either 0 with probability $|\\alpha|^2$ (or) 1 with probability $|\\beta|^2$. Essentially we can control probablity of measurement outcome by setting right amplitudes of basis states. \n", + "The state of single qubit can be represented as a two-dimensional column vector $\\begin{bmatrix} \\alpha\\\\ \\beta \\end{bmatrix}$, where $\\alpha$ and $\\beta$ are complex numbers that satisfy $|\\alpha|^2 + |\\beta|^2 = 1$. When we measure the qubit, we get either 0 with probability $|\\alpha|^2$ or 1 with probability $|\\beta|^2$. Essentially we can control probablity of measurement outcome by setting the right amplitudes of basis states. \n", "\n", - "When we initilize qubit, amplitudes $\\alpha$ and $\\beta$ are 1 and 0 respectively. Now our goal is set equal amplitudes for $\\alpha$ and $\\beta$ for absolute randomness. We can achieve that by simply applying Hadamard gate on initial state $|0\\rangle$.\n", + "When we allocate the qubit in Q#, amplitudes $\\alpha$ and $\\beta$ are 1 and 0, respectively. Now our goal is set equal amplitudes for $\\alpha$ and $\\beta$ for absolute randomness. We can achieve that by simply applying Hadamard gate to the initial state $|0\\rangle$:\n", "\n", "$$\n", "H|0\\rangle=\n", @@ -81,15 +68,14 @@ " \\end{bmatrix}\n", "$$\n", "\n", - "Now, both 0 and 1 outcomes are with equal probablity of $|\\frac{1}{\\sqrt{2}}|^2 = \\frac{1}{2}$.\n", + "Now, both 0 and 1 measurement outcomes occur with equal probablity of $|\\frac{1}{\\sqrt{2}}|^2 = \\frac{1}{2}$.\n", "\n", - "> Note: Since probablity is mod squared of amplitude, we will get same randomness by applying Hadamard gate on base state $|1\\rangle$. Try it out as optional exercise." + "> Note: Since probablity is the square of the absolute value of amplitude, we will get the same randomness by applying Hadamard gate on base state $|1\\rangle$. Try it out as an exercise!" ] }, { "cell_type": "code", "execution_count": null, - "id": "f41d8e8c", "metadata": {}, "outputs": [], "source": [ @@ -109,7 +95,13 @@ }, { "cell_type": "markdown", - "id": "32591a36", + "metadata": {}, + "source": [ + "[Return to exercise 1 of the Quantum Random Number Generation tutorial.](./RandomNumberGenerationTutorial.ipynb#Exercise-1:-Generate-a-single-random-bit)" + ] + }, + { + "cell_type": "markdown", "metadata": {}, "source": [ "## Exercise 2: Generate a random two-bit number\n", @@ -130,20 +122,17 @@ }, { "cell_type": "markdown", - "id": "e9d4f69c", "metadata": {}, "source": [ "### Solution\n", "\n", - "Reusing `RandomBit` operation from [Exercise 1](#Exercise-1:-Generate-a-single-random-bit). \n", - "\n", - "Generate two random bits by calling `RandomBit` operation twice. Multiple most significant bit with 2 and add second random bit to generate random two-bit number." + "Let's reuse `RandomBit` operation from [Exercise 1](#Exercise-1:-Generate-a-single-random-bit).\n", + "We can generate two random bits by calling `RandomBit` operation twice, multiply the most significant bit by 2 and add the second random bit to generate a random two-bit number." ] }, { "cell_type": "code", "execution_count": null, - "id": "46368ef1", "metadata": {}, "outputs": [], "source": [ @@ -156,70 +145,59 @@ }, { "cell_type": "markdown", - "id": "69315416", + "metadata": {}, + "source": [ + "[Return to exercise 2 of the Quantum Random Number Generation tutorial.](./RandomNumberGenerationTutorial.ipynb#Exercise-2:-Generate-a-random-two-bit-number)" + ] + }, + { + "cell_type": "markdown", "metadata": {}, "source": [ "## Exercise 3: Generate a number of arbitrary size\n", "\n", - "Let's take it a step further and generate an $N$-bit number. \n", - "\n", - "> Remember that you can use previously defined operations in your solution.\n", - "\n", "**Input:** An integer $N$ ($1 \\le N \\le 10$).\n", "\n", - "**Goal:** Generate a random number in the range $[0, 2^N - 1]$ with an equal probability of getting each of the numbers in this range.\n", - "\n", - "> Useful Q# documentation: \n", - "> * [`for` loops](https://docs.microsoft.com/azure/quantum/user-guide/language/statements/iterations), \n", - "> * [mutable variables](https://docs.microsoft.com/azure/quantum/user-guide/language/typesystem/immutability), \n", - "> * [exponents](https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math.powi)." + "**Goal:** Generate a random number in the range $[0, 2^N - 1]$ with an equal probability of getting each of the numbers in this range." ] }, { "cell_type": "markdown", - "id": "0b6ca4ea", "metadata": {}, "source": [ "### Solution\n", "\n", - "Reusing `RandomBit` operation from [Exercise 1](#Exercise-1:-Generate-a-single-random-bit).\n", - "\n", - "Generate N random bits by calling `RandomBit` operation N times. Multiple resulted bit array with 2 powers to convert it into integer. Repeat this process until $result <= max$, where max equal to $2^N - 1$." + "Let's reuse `RandomBit` operation from [Exercise 1](#Exercise-1:-Generate-a-single-random-bit) again.\n", + "We'll generate N random bits by calling `RandomBit` operation N times, and treat the result as a binary notation to convert it into an integer.\n", + "Since the maximum value of the number written with N bits is $2^N - 1$, we don't need to do any extra checks to ensure that the result is within the given range." ] }, { "cell_type": "code", "execution_count": null, - "id": "2d7c6758", "metadata": {}, "outputs": [], "source": [ "%kata T3_RandomNBits \n", "\n", - "open Microsoft.Quantum.Math;\n", - "\n", "operation RandomNBits (N : Int) : Int {\n", - " // Set max as 2 ^ N - 1\n", - " let max = PowI(2, N) - 1;\n", - "\n", - " // Declare result variable with mutable binding\n", " mutable result = 0;\n", - "\n", - " repeat {\n", - " set result = 0;\n", - "\n", - " for index in 1 .. N {\n", - " set result = (result * 2) + RandomBit();\n", - " }\n", - " } until (result <= max);\n", - "\n", + " for i in 0 .. N - 1 {\n", + " set result = result * 2 + RandomBit();\n", + " }\n", " return result;\n", "}" ] }, { "cell_type": "markdown", - "id": "e0363ec2", + "metadata": {}, + "source": [ + "[Return to exercise 3 of the Quantum Random Number Generation tutorial.](./RandomNumberGenerationTutorial.ipynb#Exercise-3:-Generate-a-number-of-arbitrary-size)" + ] + }, + { + "cell_type": "markdown", "metadata": {}, "source": [ "## Exercise 4: Generate a weighted bit!\n", @@ -231,56 +209,49 @@ "**Input:** \n", "A floating-point number $x$, $0 \\le x \\le 1$. \n", "\n", - "**Goal:** Generate $0$ or $1$ with probability of $0$ equal to $x$ and probability of $1$ equal to $1 - x$.\n", - "\n", - "> Useful Q# documentation: \n", - "> * [`Math` namespace](https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math)\n", - "> * [`ArcCos` function](https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math.arccos)\n", - "> * [`Sqrt` function](https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math.sqrt)\n" + "**Goal:** Generate $0$ or $1$ with probability of $0$ equal to $x$ and probability of $1$ equal to $1 - x$." ] }, { "cell_type": "markdown", - "id": "8656006c", "metadata": {}, "source": [ "### Solution\n", "\n", "We already learnt how to generate random bit with equal probability in exercise 1, in this exercise we need to generate random bit with weighted probability.\n", "\n", - "It is known that arbitrary single qubit state can be written as:\n", + "An arbitrary single-qubit state can be written as:\n", "\n", "$$\n", "|\\psi\\rangle =\n", " \\cos \\frac{\\theta}{2} |0 \\rangle \\, + \\, e^{i\\phi} \\sin \\frac{\\theta}{2} |1\\rangle\n", "$$\n", "\n", - "Where $\\theta$ is angle between state vector and $z-axis$, and $\\phi$ is longitude angle with respect to $x-axis$.\n", + "Here $\\theta$ is angle between state vector and $Z$-axis, and $\\phi$ is longitude angle with respect to $X$-axis on the Bloch sphere.\n", "\n", - "Our goal is to generate 0 or 1 with probability equals to $x$ and probability of 1 equal to (1 - $x$), which means qubit state should look like\n", + "Our goal is to generate 0 or 1 with probability of 0 equal to $x$ and probability of 1 equal to $1 - x$, which means the qubit state should look like\n", "\n", "$$\n", "|\\psi\\rangle =\n", - " \\sqrt x |0 \\rangle \\, + \\sqrt (1 - x) |1\\rangle\n", + " \\sqrt x |0 \\rangle + \\sqrt{1 - x} |1\\rangle\n", "$$\n", "\n", - "By comparing state $|0 \\rangle$ on both equations\n", + "By comparing the amplitudes of the state $|0 \\rangle$ on both equations we get\n", "\n", "$$\n", - "\\Rightarrow \\sqrt x = \\cos \\frac{\\theta}{2} \\\\ \\Rightarrow \\theta = 2 * \\arccos(\\sqrt x)\n", + "\\sqrt x = \\cos \\frac{\\theta}{2} \\Rightarrow \\theta = 2 \\arccos\\sqrt x\n", "$$\n", "\n", - "Since $\\theta$ is angle between state vector and $z-axis$, we need to apply [$Ry$](https://docs.microsoft.com/en-us/qsharp/api/qsharp/microsoft.quantum.intrinsic.ry) gate with caculated $\\theta$ on base state $|0 \\rangle$ to get desired qubit state.\n", + "Since $\\theta$ is angle between state vector and the $Z$-axis, we need to apply the [Ry](https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.intrinsic.ry) gate with caculated $\\theta$ to the starting state $|0 \\rangle$ to get the desired qubit state.\n", "\n", - "$Ry$ operation applies a given rotation about $y-axis$ (i.e. $zx-plane$), hence $\\phi$ (longitude angle with respect to $x-axis$) value is always equal to $0^{\\circ}$, which means $e^{i\\phi}$ value doesn't have any impact on resultant qubit state.\n", + "Ry operation applies a given rotation about $Y$-axis (i.e., in the $ZX$-plane), hence $\\phi$ (longitude angle with respect to $X$-axis) is always equal to $0^{\\circ}$, which means that the relative phase $e^{i\\phi}$ doesn't have any impact on resulting qubit state.\n", "\n", - "> We can also calculate ${\\theta}$ by comparing state $|1 \\rangle$ on both equations, which is $2.0 * \\arcsin(\\sqrt(1.0 - x))$" + "> We can also calculate ${\\theta}$ by comparing the amplitudes of the state $|1 \\rangle$ on both equations, which is $2 \\arcsin\\sqrt{1.0 - x}$" ] }, { "cell_type": "code", "execution_count": null, - "id": "fcb1799c", "metadata": {}, "outputs": [], "source": [ @@ -305,7 +276,13 @@ }, { "cell_type": "markdown", - "id": "82e05283", + "metadata": {}, + "source": [ + "[Return to exercise 4 of the Quantum Random Number Generation tutorial.](./RandomNumberGenerationTutorial.ipynb#Exercise-4:-Generate-a-weighted-bit!)" + ] + }, + { + "cell_type": "markdown", "metadata": {}, "source": [ "## Exercise 5: Generate a random number between min and max\n", @@ -315,28 +292,23 @@ "**Input:** \n", "Two integers $min$ and $max$ ($0 \\leq min \\leq max \\leq 2^{10}-1$).\n", "\n", - "**Goal:** Generate a random number in the range $[min, max]$ with an equal probability of getting each of the numbers in this range.\n", - "\n", - "> Useful Q# documentation: \n", - "> * [`BitSizeI` function](https://docs.microsoft.com/en-us/qsharp/api/qsharp/microsoft.quantum.math.bitsizei)" + "**Goal:** Generate a random number in the range $[min, max]$ with an equal probability of getting each of the numbers in this range." ] }, { "cell_type": "markdown", - "id": "663bc636", "metadata": {}, "source": [ "### Solution\n", "\n", - "Reusing `RandomBit` operation from [Exercise 1](#Exercise-1:-Generate-a-single-random-bit).\n", + "We can reuse `RandomNBits` operation from [Exercise 3](#Exercise-3:-Generate-a-number-of-arbitrary-size).\n", "\n", - "Generate N random bits by calling `RandomBit` operation N times, where N is bitsize of max. Multiple resulted bit array with 2 powers to convert it into integer. Repeat this process until $min <= result <= max$." + "We'll generate an N-bit random number by calling `RandomNBits` operation, where N is the bitsize of $max$. We can repeat this process until the result is within the given range of numbers: $min <= result <= max$." ] }, { "cell_type": "code", "execution_count": null, - "id": "9dba8758", "metadata": {}, "outputs": [], "source": [ @@ -352,16 +324,19 @@ " mutable result = 0;\n", " \n", " repeat {\n", - " set result = 0;\n", - "\n", - " for index in 1 .. N {\n", - " set result = (result * 2) + RandomBit();\n", - " }\n", - " } until (result >= min and result <= max);\n", + " set result = RandomNBits(N);\n", + " } until result >= min and result <= max;\n", "\n", " return result;\n", "}" ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "[Return to exercise 5 of the Quantum Random Number Generation tutorial.](./RandomNumberGenerationTutorial.ipynb#Exercise-5:-Generate-a-random-number-between-min-and-max)" + ] } ], "metadata": {