Skip to content

Commit

Permalink
Merge pull request #95 from ampolloreno/DJ
Browse files Browse the repository at this point in the history
Deutsch-Jozsa
  • Loading branch information
jotterbach committed Nov 3, 2017
2 parents af0469c + 3abd519 commit ce6ddfc
Show file tree
Hide file tree
Showing 10 changed files with 430 additions and 217 deletions.
59 changes: 53 additions & 6 deletions docs/deutsch_jozsa.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,58 @@ Deutsch-Jozsa Algorithm
Overview
--------

The Deutsch-Jozsa algorithm can determine whether a function mapping all bitstrings
to a single bit is constant or balanced, provided that it is one of the two. A constant
function always maps to either 1 or 0, and a balanced function maps to 1 for half of the inputs and maps to 0
for the other half. Unlike any classical algorithm, the Deutsch-Jozsa Algorithm can solve this problem with
a single iteration, regardless of the input size.
The Deutsch-Jozsa algorithm can determine whether a function mapping all bitstrings to a single bit
is constant or balanced, provided that it is one of the two. A constant function always maps to
either 1 or 0, and a balanced function maps to 1 for half of the inputs and maps to 0 for the other
half. Unlike any deterministic classical algorithm, the Deutsch-Jozsa Algorithm can solve this
problem with a single iteration, regardless of the input size. It was one of the first known quantum
algorithms that showed an exponential speedup, albeit against a deterministic (non-probabilistic)
classical compuetwr, and with access to a blackbox function that can evaluate inputs to the chosen
function.

Algorithm and Details
---------------------

This algorithm takes as input :math:`n` qubits in state :math:`\ket{x}`, an ancillary qubit in state
:math:`\ket{q}`, and additionally a quantum circuit :math:`U_w` that performs the following:

.. math::
U_w: \ket{x}\ket{q}\to\ket{x}\ket{f(x)\oplus q}
In the case of the Deutsch-Jozsa algorithm, the function :math:`f` is some function mapping from
bitstrings to bits:

.. math::
f: \{0,1\}^n\to\{0, 1\}
and is assumed to either be \textit{constant} or \textit{balanced}. Constant means that on all
inputs :math:`f` takes on the same value, and balanced means that on half of the inputs :math:`f`
takes on one value, and on the other half :math:`f` takes on a different value. (Here the value is
restricted to :math:`\{0, 1\}`)

We can then describe the algorithm as follows:

Input:
:math:`n + 1` qubits
Algorithm:
#. Prepare the \textit{ancilla} (:math:`\ket{q}` above) in the :math:`\ket{1}` state by performing
an :math:`X` gate.
#. Perform the :math:`n + 1`-fold Hadamard gate :math:`H^{\otimes n + 1}` on the :math:`n + 1`
qubits.
#. Apply the circuit :math:`U_w`.
#. Apply the :math:`n`-fold Hadamard gate :math:`H^{\otimes n}` on the data qubits, :math:`\ket{x}`.
#. Measure :math:`\ket{x}`. If the result is all zeroes, then the function is constant. Otherwise, it
is balanced.

Implementation Notes
--------------------

The oracle in the :term:`Deutsch-Jozsa` module is not implemented in such a way that calling
`Deutsch_Jozsa.is_constant()` will yield an exponential speedup over classical implementations. To
construct the quantum algorithm that is executing on the QPU we use a Quil `defgate`, which
specifies the circuit :math:`U_w` as its action on the data qubits :math:`\ket{x}`. This matrix is
exponentially large, and thus even generating the program will take exponential time.


Source Code Docs
----------------
Expand All @@ -19,7 +66,7 @@ Here you can find documentation for the different submodules in deutsch-jozsa.
grove.deutsch_jozsa.deutsch_jozsa.py
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. automodule:: grove.alpha.deutsch_jozsa.deutsch_jozsa
.. automodule:: grove.deutsch_jozsa.deutsch_jozsa
:members:
:undoc-members:
:show-inheritance:
140 changes: 140 additions & 0 deletions examples/DeutschJosza.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This Notebook is a brief sketch of how to use the Deutsch-Jozsa algorithm.\n",
"We start by declaring all necessary imports."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"from collections import defaultdict\n",
"from pyquil.api import SyncConnection\n",
"import numpy as np\n",
"from mock import patch\n",
"from itertools import product\n",
"\n",
"from grove.deutsch_jozsa.deutsch_jozsa import DeutschJosza"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The Deutsch-Jozsa Algorithm can be used to determine if a binary-valued function is constant or balanced (returns 0 on exactly half of its inputs)."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"bit_value = '0'\n",
"bit = (\"0\", \"1\")\n",
"constant_bitmap = {}\n",
"\n",
"# We construct the bitmap for the algorithm\n",
"for bitstring in product(bit, repeat=2):\n",
" bitstring = \"\".join(bitstring)\n",
" constant_bitmap[bitstring] = bit_value"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We verify that we have a constant bitmap below."
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"for value in constant_bitmap.values():\n",
" assert value == bit_value, \"The constant_bitmap is not constant with value bit_value.\""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"To use the Deutsch-Jozsa algorithm on a Quantum Hardware we need to define the connection to the QVM or QPU. However we don't have a real connection in this notebook, so we just mock out the response. If you run this notebook, ensure to replace `cxn` with a pyQuil connection object."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"with patch(\"pyquil.api.SyncConnection\") as cxn:\n",
" # Need to mock multiple returns as an iterable\n",
" cxn.run_and_measure.side_effect = [\n",
" (np.asarray([0, 0]))]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now let's run the Deutsch Jozsa algorithm. We instantiate the Deutsch Jozsa object and then call its `is_constant` method with the connection object and the bitmap we defined above. Finally we assert its correctness by checking the output. (The method returns a boolean, so here we just check the returned boolean.)"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"dj = DeutschJosza()\n",
"is_constant = dj.is_constant(cxn, constant_bitmap)\n",
"assert is_constant, \"The algorithm said the function was balanced.\""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"If the assertion succeeded we know the algorithm returned the zero bitstring and successfully recognized the function as constant."
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 2",
"language": "python",
"name": "python2"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.13"
}
},
"nbformat": 4,
"nbformat_minor": 1
}
175 changes: 0 additions & 175 deletions grove/alpha/deutsch_jozsa/deutsch_jozsa.py

This file was deleted.

0 comments on commit ce6ddfc

Please sign in to comment.