diff --git a/examples/Images/carry.png b/examples/Images/carry.png new file mode 100644 index 000000000..64baa0190 Binary files /dev/null and b/examples/Images/carry.png differ diff --git a/examples/Images/sum.png b/examples/Images/sum.png new file mode 100644 index 000000000..258db7f5f Binary files /dev/null and b/examples/Images/sum.png differ diff --git a/examples/quantum_adder.ipynb b/examples/quantum_adder.ipynb new file mode 100644 index 000000000..5e0e412ac --- /dev/null +++ b/examples/quantum_adder.ipynb @@ -0,0 +1,157 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Tutorial: Quantum Adder\n", + "An adder has two basic building blocks:\n", + "1. Addition modulo 2\n", + "2. Carry output\n", + "\n", + "For a quantum computer, both blocks can be implemented using CNOT gate." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "from projectq import MainEngine\n", + "from projectq.backends import CircuitDrawer\n", + "from projectq.ops import X, CNOT, Measure, All, ControlledGate\n", + "\n", + "def qsum_(c, a, b):\n", + " CNOT|(a, b) # CNOT (control bit, target bit)\n", + " CNOT|(c, b)\n", + " return b # b -> b' = (a+b+c mod 2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The quantum circuit of qsum_ is:\n", + "" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "def qcarry_(eng, a, b, c):\n", + " ancilla = eng.allocate_qubit()\n", + " ControlledGate(X,2) | (a,b,ancilla) # a,b are control qubits, ancilla is a target qubit\n", + " CNOT|(a,b)\n", + " ControlledGate(X,2) | (c,b,ancilla)\n", + " return (c,a,b,ancilla) # (carry, a, a+b mod 2, next carry)\n", + " # (a+b mod 2) can be uncomputed later using CNOT" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The quantum circuit of qcarry_ is:\n", + "" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Finally we can start to construct a quantum adder:\n", + "1. The input are two n-qubit quantum states, the output is a (n+1)-qubit quantum state which is converted into an integer.\n", + "2. We start from least significant bits $a_0$ and $b_0$, compute the carry $c_0$ and pass it to next bit.\n", + "3. The most significant bit is the carry $c_n$.\n", + "4. We uncompute registers-b, then use qsum_ to get less significant bits." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "def qadd_(eng, qureg_A, qureg_B):\n", + " assert len(qureg_A)==len(qureg_B)\n", + " n=len(qureg_A)\n", + " carries = [None for i in range(n+1)]\n", + " carries[0] = eng.allocate_qubit()\n", + " for i in range(n):\n", + " _, _, _, carries[i+1] = qcarry_(eng,qureg_A[i],qureg_B[i],carries[i])\n", + " CNOT|(qureg_A[i],qureg_B[i]) # uncompute a+b mod 2 to b\n", + " qsum_(carries[i],qureg_A[i],qureg_B[i])\n", + " \n", + " All(Measure)|qureg_B # less significant bits\n", + " Measure|carries[n] # most significant bit\n", + " eng.flush()\n", + " \n", + " result = ''\n", + " for bit in qureg_B:\n", + " result += str(int(bit))\n", + " result += str(int(carries[n]))\n", + " return result[::-1] # reverse" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A sample test run" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(Note: This is the (slow) Python simulator.)\n", + "1011\n" + ] + } + ], + "source": [ + "if __name__ == \"__main__\":\n", + " eng = MainEngine()\n", + " qureg_A=eng.allocate_qureg(3)\n", + " X|qureg_A[0]\n", + " X|qureg_A[1]\n", + " X|qureg_A[2]\n", + " qureg_B=eng.allocate_qureg(3)\n", + " X|qureg_B[2]\n", + " print(qadd_(eng,qureg_A,qureg_B))\n", + "\n", + " del eng" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.2" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +}