Skip to content

Commit

Permalink
ProjectQ v0.4
Browse files Browse the repository at this point in the history
  • Loading branch information
thomashaener committed Jul 23, 2018
2 parents fa484fe + a72fd63 commit bba67f2
Show file tree
Hide file tree
Showing 127 changed files with 8,233 additions and 1,246 deletions.
10 changes: 6 additions & 4 deletions .travis.yml
Expand Up @@ -7,28 +7,28 @@ matrix:
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['gcc-4.9', 'g++-4.9']
packages: ['gcc-4.9', 'g++-4.9', 'gcc-7', 'g++-7']
env: CC=gcc-4.9 CXX=g++-4.9 PYTHON=2.7
- os: linux
python: "3.4"
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['gcc-4.9', 'g++-4.9']
packages: ['gcc-4.9', 'g++-4.9', 'gcc-7', 'g++-7']
env: CC=gcc-4.9 CXX=g++-4.9 PYTHON=3.4
- os: linux
python: "3.5"
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['gcc-4.9', 'g++-4.9']
packages: ['gcc-4.9', 'g++-4.9', 'gcc-7', 'g++-7']
env: CC=gcc-4.9 CXX=g++-4.9 PYTHON=3.5
- os: linux
python: "3.6"
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['gcc-4.9', 'g++-4.9']
packages: ['gcc-4.9', 'g++-4.9', 'gcc-7', 'g++-7']
env: CC=gcc-4.9 CXX=g++-4.9 PYTHON=3.6

install:
Expand All @@ -38,6 +38,8 @@ install:
- pip$PY install -r requirements.txt
- pip$PY install pytest-cov
- pip$PY install coveralls
- CC=g++-7 pip$PY install revkit
- if [ "${PYTHON:0:1}" = "3" ]; then pip$PY install dormouse; fi
- pip$PY install -e .

# command to run tests
Expand Down
117 changes: 114 additions & 3 deletions README.rst
Expand Up @@ -32,6 +32,114 @@ This allows users to
- export quantum programs as circuits (using TikZ)
- get resource estimates

Examples
--------

**First quantum program**

.. code-block:: python
from projectq import MainEngine # import the main compiler engine
from projectq.ops import H, Measure # import the operations we want to perform (Hadamard and measurement)
eng = MainEngine() # create a default compiler (the back-end is a simulator)
qubit = eng.allocate_qubit() # allocate a quantum register with 1 qubit
H | qubit # apply a Hadamard gate
Measure | qubit # measure the qubit
eng.flush() # flush all gates (and execute measurements)
print("Measured {}".format(int(qubit))) # converting a qubit to int or bool gives access to the measurement result
ProjectQ features a lean syntax which is close to the mathematical notation used in quantum physics. For example, a rotation of a qubit around the x-axis is usually specified as:

.. image:: docs/images/braket_notation.svg
:alt: Rx(theta)|qubit>
:width: 100px

The same statement in ProjectQ's syntax is:

.. code-block:: python
Rx(theta) | qubit
The **|**-operator separates the specification of the gate operation (left-hand side) from the quantum bits to which the operation is applied (right-hand side).

**Changing the compiler and using a resource counter as a back-end**

Instead of simulating a quantum program, one can use our resource counter (as a back-end) to determine how many operations it would take on a future quantum computer with a given architecture. Suppose the qubits are arranged on a linear chain and the architecture supports any single-qubit gate as well as the two-qubit CNOT and Swap operations:

.. code-block:: python
from projectq import MainEngine
from projectq.backends import ResourceCounter
from projectq.ops import QFT
from projectq.setups import linear
compiler_engines = linear.get_engine_list(num_qubits=16,
one_qubit_gates='any',
two_qubit_gates=(CNOT, Swap))
resource_counter = ResourceCounter()
eng = MainEngine(backend=resource_counter, engine_list=compiler_engines)
qureg = eng.allocate_qureg(16)
QFT | qureg
eng.flush()
print(resource_counter)
# This will output, among other information,
# how many operations are needed to perform
# this quantum fourier transform (QFT), i.e.,
# Gate class counts:
# AllocateQubitGate : 16
# CXGate : 240
# HGate : 16
# R : 120
# Rz : 240
# SwapGate : 262
**Running a quantum program on IBM's QE chips**

To run a program on the IBM Quantum Experience chips, all one has to do is choose the `IBMBackend` and the corresponding compiler:

.. code-block:: python
compiler_engines = projectq.setups.ibm16.get_engine_list()
eng = MainEngine(IBMBackend(use_hardware=True, num_runs=1024,
verbose=False, device='ibmqx5'),
engine_list=compiler_engines)
**Classically simulate a quantum program**

ProjectQ has a high-performance simulator which allows simulating up to about 30 qubits on a regular laptop. See the `simulator tutorial <https://github.com/ProjectQ-Framework/ProjectQ/blob/feature/update-readme/examples/simulator_tutorial.ipynb>`__ for more information. Using the emulation features of our simulator (fast classical shortcuts), one can easily emulate Shor's algorithm for problem sizes for which a quantum computer would require above 50 qubits, see our `example codes <http://projectq.readthedocs.io/en/latest/examples.html#shor-s-algorithm-for-factoring>`__.


The advanced features of the simulator are also particularly useful to investigate algorithms for the simulation of quantum systems. For example, the simulator can evolve a quantum system in time (without Trotter errors) and it gives direct access to expectation values of Hamiltonians leading to extremely fast simulations of VQE type algorithms:

.. code-block:: python
from projectq import MainEngine
from projectq.ops import All, Measure, QubitOperator, TimeEvolution
eng = MainEngine()
wavefunction = eng.allocate_qureg(2)
# Specify a Hamiltonian in terms of Pauli operators:
hamiltonian = QubitOperator("X0 X1") + 0.5 * QubitOperator("Y0 Y1")
# Apply exp(-i * Hamiltonian * time) (without Trotter error)
TimeEvolution(time=1, hamiltonian=hamiltonian) | wavefunction
# Measure the expection value using the simulator shortcut:
eng.flush()
value = eng.backend.get_expectation_value(hamiltonian, wavefunction)
# Last operation in any program should be measuring all qubits
All(Measure) | qureg
eng.flush()
Getting started
---------------

Expand All @@ -54,10 +162,11 @@ When using ProjectQ for research projects, please cite

- Damian S. Steiger, Thomas Häner, and Matthias Troyer "ProjectQ: An
Open Source Software Framework for Quantum Computing"
`[arxiv:1612.08091] <https://arxiv.org/abs/1612.08091>`__
`Quantum 2, 49 (2018) <https://doi.org/10.22331/q-2018-01-31-49>`__
(published on `arXiv <https://arxiv.org/abs/1612.08091>`__ on 23 Dec 2016)
- Thomas Häner, Damian S. Steiger, Krysta M. Svore, and Matthias Troyer
"A Software Methodology for Compiling Quantum Programs"
`[arxiv:1604.01401] <http://arxiv.org/abs/1604.01401>`__
"A Software Methodology for Compiling Quantum Programs" `Quantum Sci. Technol. 3 (2018) 020501 <https://doi.org/10.1088/2058-9565/aaa5cc>`__
(published on `arXiv <http://arxiv.org/abs/1604.01401>`__ on 5 Apr 2016)

Authors
-------
Expand All @@ -70,6 +179,8 @@ in the group of `Prof. Dr. Matthias
Troyer <http://www.comp.phys.ethz.ch/people/troyer.html>`__ at ETH
Zurich.

ProjectQ is constantly growing and `many other people <https://github.com/ProjectQ-Framework/ProjectQ/graphs/contributors>`__ have already contributed to it in the meantime.

License
-------

Expand Down
73 changes: 70 additions & 3 deletions docs/conf.py
Expand Up @@ -33,9 +33,12 @@
import sphinx_rtd_theme

extensions = [
'sphinx.ext.autodoc', 'sphinx.ext.napoleon', 'sphinx.ext.mathjax'
'sphinx.ext.autodoc', 'sphinx.ext.napoleon', 'sphinx.ext.mathjax',
'sphinx.ext.autosummary', 'sphinx.ext.linkcode',
]

autosummary_generate = True

# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']

Expand Down Expand Up @@ -89,7 +92,7 @@
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This patterns also effect to html_static_path and html_extra_path
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store', 'README.rst']

# The reST default role (used for this markup: `text`) to use for all
# documents.
Expand Down Expand Up @@ -162,7 +165,7 @@
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
# html_static_path = ['_static']

# Add any extra paths that contain custom files (such as robots.txt or
# .htaccess) here, relative to this directory. These files are copied
Expand Down Expand Up @@ -345,3 +348,67 @@
# If true, do not generate a @detailmenu in the "Top" node's menu.
#
# texinfo_no_detailmenu = False

# -- Options for sphinx.ext.linkcode --------------------------------------
import inspect
import projectq


def linkcode_resolve(domain, info):
# Copyright 2018 ProjectQ (www.projectq.ch), all rights reserved.
on_rtd = os.environ.get('READTHEDOCS') == 'True'
github_url = "https://github.com/ProjectQ-Framework/ProjectQ/tree/"
if on_rtd:
rtd_tag = os.environ.get('READTHEDOCS_VERSION')
if rtd_tag == 'latest':
github_tag = 'develop'
elif rtd_tag == 'stable':
github_tag = 'master'
else:
# RTD changes "/" in branch name to "-"
# As we use branches like fix/cool-feature, this is a
# problem -> as a fix we require that all branch names
# which contain a '-' must first contain one '/':
if list(rtd_tag).count('-'):
github_tag = list(rtd_tag)
github_tag[github_tag.index('-')] = '/'
github_tag = ''.join(github_tag)
else:
github_tag = rtd_tag
else:
github_tag = 'v' + __version__
if domain != 'py':
return None
else:
try:
obj = eval(info['module'] + '.' + info['fullname'])
except AttributeError:
# Object might be a non-static attribute of a class, e.g.,
# self.num_qubits, which would only exist after init was called.
# For the moment we don't need a link for that as there is a link
# for the class already
return None
try:
filepath = inspect.getsourcefile(obj)
line_number = inspect.getsourcelines(obj)[1]
except:
# obj might be a property or a static class variable, e.g.,
# loop_tag_id in which case obj is an int and inspect will fail
try:
# load obj one hierarchy higher (either class or module)
new_higher_name = info['fullname'].split('.')
if len(new_higher_name) <= 1:
obj = eval(info['module'])
else:
obj = eval(info['module'] + '.' +
'.'.join(new_higher_name[:-1]))
filepath = inspect.getsourcefile(obj)
line_number = inspect.getsourcelines(obj)[1]
except:
return None
# Only require relative path projectq/relative_path
projectq_path = inspect.getsourcefile(projectq)[:-11]
relative_path = os.path.relpath(filepath, projectq_path)
url = (github_url + github_tag + "/projectq/" + relative_path + "#L" +
str(line_number))
return url
14 changes: 7 additions & 7 deletions docs/examples.rst
Expand Up @@ -61,7 +61,7 @@ What she can do is use quantum teleportation to achieve this task. Yet, this onl
They can create a Bell-pair using a very simple circuit which first applies a Hadamard gate to the first qubit, and then flips the second qubit conditional on the first qubit being in :math:`|1\rangle`. The circuit diagram can be generated by calling the function

.. literalinclude:: ../examples/teleport.py
:lines: 7,19-25
:lines: 6,18-25
:tab-width: 2

with a main compiler engine which has a CircuitDrawer back-end, i.e.,
Expand All @@ -88,7 +88,7 @@ The complete example looks as follows:

.. literalinclude:: ../examples/teleport.py
:linenos:
:lines: 1-7,19-28,45-100
:lines: 1-6,18-27,44-100
:tab-width: 2

and the corresponding circuit can be generated using
Expand Down Expand Up @@ -162,9 +162,9 @@ As a third example, consider Shor's algorithm for factoring, which for a given (
Simulating Shor's algorithm at the level of single-qubit gates and CNOTs already takes quite a bit of time for larger numbers than 15. To turn on our **emulation feature**, which does not decompose the modular arithmetic to low-level gates, but carries it out directly instead, we can change the line

.. literalinclude:: ../examples/shor.py
:lineno-start: 91
:lines: 91-102
:emphasize-lines: 9
:lineno-start: 86
:lines: 86-99
:emphasize-lines: 8
:linenos:
:tab-width: 2

Expand All @@ -173,8 +173,8 @@ As a third example, consider Shor's algorithm for factoring, which for a given (
The most important part of the code is

.. literalinclude:: ../examples/shor.py
:lines: 56-74
:lineno-start: 56
:lines: 50-69
:lineno-start: 50
:linenos:
:dedent: 1
:tab-width: 2
Expand Down

0 comments on commit bba67f2

Please sign in to comment.