forked from microsoft/QuantumKatas
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[RippleCaryAdder] Add workbook for tasks 1.1-1.3 (microsoft#794)
- Loading branch information
1 parent
f690df5
commit 1865043
Showing
2 changed files
with
287 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,266 @@ | ||
{ | ||
"cells": [ | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"# Ripple Carry Adder Workbok\n", | ||
"**What is this workbook?** \n", | ||
"A workbook is a collection of problems, accompanied by solutions to them. 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 or for reinforcement. While a textbook emphasizes knowledge acquisition, a workbook emphasizes skill acquisition.\n", | ||
"\n", | ||
"This workbook describes the solutions to the problems offered in the [Ripple Carry Adder Kata](./RippleCarryAdder.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 novice." | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"**What you should know for this workbook**\n", | ||
"\n", | ||
"You should be familiar with the following concepts and associated techniques **prior to** beginning work on the Basic Gates Quantum Kata.\n", | ||
"\n", | ||
"1. [Basic Gates Kata](../BasicGates/BasicGates.ipynb). \n", | ||
"2. [Single-qubit gates](../tutorials/SingleQubitGates/SingleQubitGates.ipynb).\n", | ||
"3. List of basic gates available in Q# can be found at [Microsoft.Quantum.Intrinsic](https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.intrinsic).\n", | ||
"4. [Syntax of flow control statements in Q#](https://docs.microsoft.com/azure/quantum/user-guide/language/statements/iterations) \n", | ||
"5. [Q# conditional branching](https://docs.microsoft.com/azure/quantum/user-guide/language/statements/conditionalbranching) documentation.\n", | ||
"\n", | ||
"You can also consult the [complete Quantum Katas learning path](https://github.com/microsoft/QuantumKatas#learning-path)." | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"## Part I. Simple Adder Outputting to Empty Qubits\n", | ||
"\n", | ||
"\n", | ||
"### Theory\n", | ||
"\n", | ||
"* [Classical binary adder on Wikipedia](https://en.wikipedia.org/wiki/Adder_(electronics)).\n", | ||
"* Part 2 of the [paper on quantum binary addition](https://arxiv.org/pdf/quant-ph/0008033.pdf) by Thomas G. Draper explains how to adapt the classical adder to a quantum environment." | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"### Task 1.1. Summation of two bits\n", | ||
"\n", | ||
"**Inputs:**\n", | ||
"\n", | ||
" 1. qubit `a` in an arbitrary state $|\\phi\\rangle$, \n", | ||
" 2. qubit `b` in an arbitrary state $|\\psi\\rangle$, \n", | ||
" 3. qubit `sum` in state $|0\\rangle$.\n", | ||
"\n", | ||
"**Goal:** Transform the `sum` qubit into the lowest bit of the binary sum of $\\phi$ and $\\psi$.\n", | ||
"\n", | ||
"* $|0\\rangle + |0\\rangle \\to |0\\rangle$\n", | ||
"* $|0\\rangle + |1\\rangle \\to |1\\rangle$\n", | ||
"* $|1\\rangle + |0\\rangle \\to |1\\rangle$\n", | ||
"* $|1\\rangle + |1\\rangle \\to |0\\rangle$\n", | ||
"\n", | ||
"Any superposition should map appropriately. \n", | ||
"\n", | ||
"**Example:** (Recall that $|+\\rangle = \\frac{1}{\\sqrt{2}}(|0\\rangle + |1\\rangle)$, $|-\\rangle = \\frac{1}{\\sqrt{2}}(|0\\rangle - |1\\rangle)$)\n", | ||
"\n", | ||
"$|+\\rangle \\otimes |-\\rangle \\otimes |0\\rangle \\to \\frac{1}{2}(|000\\rangle + |101\\rangle - |011\\rangle - |110\\rangle)$" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"### Solution\n", | ||
"\n", | ||
"> In this workbook we will reason about the computations acting on basis states, as opposed to arbitrary superposition states. \n", | ||
"> (Since all computations will be implemented using quantum gates, they'll be linear, and behave correctly on superpositions if they are correct on all basis states.) \n", | ||
"> This will allow us to use qubit states and the classical values stored in them interchangeably.\n", | ||
"\n", | ||
"Clearly, the expression we're looking for is $a \\oplus b$ - sum of bits $a$ and $b$ modulo 2.\n", | ||
"\n", | ||
"If we apply $CNOT(a,sum)$, then $a=a$, $b=b$, and $sum$ becomes $0 \\oplus a = a$.\n", | ||
"\n", | ||
"Again applying $CNOT(b,sum)$, we get $a=a$, $b=b$, and $sum$ becomes $sum \\oplus b = a \\oplus b$. That's exactly what we're looking for!" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"%kata T11_LowestBitSum\n", | ||
"\n", | ||
"operation LowestBitSum (a : Qubit, b : Qubit, sum : Qubit) : Unit is Adj {\n", | ||
" CNOT(a, sum);\n", | ||
" CNOT(b, sum);\n", | ||
"}" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"### Alternate Solution\n", | ||
"\n", | ||
"If we apply $CNOT(a,b)$ , then $a = a$, $b = a \\oplus b$, and $sum = 0$.\n", | ||
"\n", | ||
"Again applying $CNOT(b,sum)$, we get $a = a$, $b = a \\oplus b$, and $sum = sum \\oplus b = a \\oplus b$.\n", | ||
"\n", | ||
"Now by applying $CNOT(a,b)$, we get $a = a$, $b = a \\oplus (a \\oplus b) = b$, $sum = a \\oplus b$, and thus we will restore the previous value of $b$." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"%kata T11_LowestBitSum\n", | ||
"\n", | ||
"operation LowestBitSum (a : Qubit, b : Qubit, sum : Qubit) : Unit is Adj {\n", | ||
" CNOT(a, b);\n", | ||
" CNOT(b, sum);\n", | ||
" CNOT(a, b);\n", | ||
"}" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"[Return to Task 1.1 of the Ripple Carry Adder kata.](./RippleCarryAdder.ipynb#Task-1.1.-Summation-of-two-bits)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"### Task 1.2. Carry of two bits\n", | ||
"\n", | ||
"**Inputs:**\n", | ||
"\n", | ||
" 1. qubit `a` in an arbitrary state $|\\phi\\rangle$,\n", | ||
" 2. qubit `b` in an arbitrary state $|\\psi\\rangle$,\n", | ||
" 3. qubit `carry` in state $|0\\rangle$.\n", | ||
"\n", | ||
"**Goal:** Set the `carry` qubit to $|1\\rangle$ if the binary sum of $\\phi$ and $\\psi$ produces a carry.\n", | ||
"\n", | ||
"* $|0\\rangle$ and $|0\\rangle \\to |0\\rangle$\n", | ||
"* $|0\\rangle$ and $|1\\rangle \\to |0\\rangle$\n", | ||
"* $|1\\rangle$ and $|0\\rangle \\to |0\\rangle$\n", | ||
"* $|1\\rangle$ and $|1\\rangle \\to |1\\rangle$\n", | ||
"\n", | ||
"Any superposition should map appropriately. \n", | ||
"\n", | ||
"**Example:**\n", | ||
"\n", | ||
"$|+\\rangle \\otimes |-\\rangle \\otimes |0\\rangle \\to \\frac{1}{2}(|000\\rangle + |100\\rangle - |010\\rangle - |111\\rangle)$" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"### Solution\n", | ||
"Clearly, $carry = a \\text{ AND } b$.\n", | ||
"\n", | ||
"If we apply $CCNOT(a, b, carry)$, then $a=a$, $b=b$, and $carry$ becomes $(a \\text{ AND } b) \\oplus carry = (a \\text{ AND } b) \\oplus 0 = (a \\text{ AND } b)$." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"%kata T12_LowestBitCarry\n", | ||
"\n", | ||
"operation LowestBitCarry (a : Qubit, b : Qubit, carry : Qubit) : Unit is Adj {\n", | ||
" CCNOT(a, b, carry);\n", | ||
"}" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"[Return to Task 1.2 of the Ripple Carry Adder kata.](./RippleCarryAdder.ipynb#Task-1.2.-Carry-of-two-bits)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"### Task 1.3. One-bit adder\n", | ||
"\n", | ||
"**Inputs:**\n", | ||
"\n", | ||
" 1. qubit `a` in an arbitrary state $|\\phi\\rangle$,\n", | ||
" 2. qubit `b` in an arbitrary state $|\\psi\\rangle$,\n", | ||
" 3. two qubits `sum` and `carry` in state $|0\\rangle$.\n", | ||
"\n", | ||
"**Goals:**\n", | ||
"\n", | ||
"* Transform the `sum` qubit into the lowest bit of the binary sum of $\\phi$ and $\\psi$.\n", | ||
"* Transform the `carry` qubit into the carry bit produced by that sum." | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"### Solution\n", | ||
"This task is just a combination of the two previous ones. Using [task 1.1](./Workbook_RippleCarryAdder.ipynb#Task-1.1.-Summation-of-two-bits) and [task 1.2](./Workbook_RippleCarryAdder.ipynb#Task-1.2.-Carry-of-two-bits), \n", | ||
"we can get the solution below." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"%kata T13_OneBitAdder\n", | ||
"\n", | ||
"operation OneBitAdder (a : Qubit, b : Qubit, sum : Qubit, carry : Qubit) : Unit is Adj {\n", | ||
" LowestBitSum(a, b, sum);\n", | ||
" LowestBitCarry(a, b, carry);\n", | ||
"}" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"[Return to Task 1.3 of the Ripple Carry Adder kata.](./RippleCarryAdder.ipynb#Task-1.3.-One-bit-adder)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"More solutions comming soon.." | ||
] | ||
} | ||
], | ||
"metadata": { | ||
"kernelspec": { | ||
"display_name": "Q#", | ||
"language": "qsharp", | ||
"name": "iqsharp" | ||
}, | ||
"language_info": { | ||
"file_extension": ".qs", | ||
"mimetype": "text/x-qsharp", | ||
"name": "qsharp", | ||
"version": "0.14" | ||
} | ||
}, | ||
"nbformat": 4, | ||
"nbformat_minor": 2 | ||
} |