ProjectQ¶
ProjectQ is an opensource software framework for quantum computing. It aims at providing tools which facilitate inventing, implementing, testing, debugging, and running quantum algorithms using either classical hardware or actual quantum devices.
The four core principles of this opensource effort are
 Open & Free: ProjectQ is released under the Apache 2 license
 Simple learning curve: It is implemented in Python and has an intuitive syntax
 Easily extensible: Anyone can contribute to the compiler, the embedded domainspecific language, and libraries
 Code quality: Code reviews, continuous integration testing (unit and functional tests)
 Please cite
 Damian S. Steiger, Thomas Häner, and Matthias Troyer “ProjectQ: An Open Source Software Framework for Quantum Computing” [arxiv:1612.08091]
 Thomas Häner, Damian S. Steiger, Krysta M. Svore, and Matthias Troyer “A Software Methodology for Compiling Quantum Programs” [arxiv:1604.01401]
 Contents
 Tutorial: Tutorial containing instructions on how to get started with ProjectQ.
 Examples: Example implementations of few quantum algorithms
 Code Documentation: The code documentation of ProjectQ.
Tutorial¶
Getting started¶
To start using ProjectQ, simply run
python m pip install user projectq
or, alternatively, clone/download this repo (e.g., to your /home directory) and run
cd /home/projectq
python m pip install user .
ProjectQ comes with a highperformance quantum simulator written in C++. Please see the detailed OS specific installation instructions below to make sure that you are installing the fastest version.
Note
The setup will try to build a C++Simulator, which is much faster than the Python implementation. If it fails, you may use the –withoutcppsimulator parameter, i.e.,
python m pip install user globaloption=withoutcppsimulator .
and the framework will use the slow Python simulator instead. Note that this only works if the installation has been tried once without the –withoutcppsimulator parameter and hence all requirements are now installed. See the instructions below if you want to run larger simulations. The Python simulator works perfectly fine for the small examples (e.g., running Shor’s algorithm for factoring 15 or 21).
Note
If building the C++Simulator does not work out of the box, consider specifying a different compiler. For example:
env CC=g++5 python m pip install user projectq
Please note that the compiler you specify must support C++11!
Note
Please use pip version v6.1.0 or higher as this ensures that dependencies are installed in the correct order.
Note
ProjectQ should be installed on each computer individually as the C++ simulator compilation creates binaries which are optimized for the specific hardware on which it is being installed (potentially using our AVX version and march=native). Therefore, sharing the same ProjectQ installation across different hardware can cause problems.
Detailed instructions and OSspecific hints¶
Ubuntu:
After having installed the build tools (for g++):
sudo aptget install buildessentialYou only need to install Python (and the package manager). For version 3, run
sudo aptget install python3 python3pipWhen you then run
sudo pip3 install user projectqall dependencies (such as numpy and pybind11) should be installed automatically.
Windows:
It is easiest to install a precompiled version of Python, including numpy and many more useful packages. One way to do so is using, e.g., the Python3.5 installers from python.org or ANACONDA. Installing ProjectQ right away will succeed for the (slow) Python simulator (i.e., with the –withoutcppsimulator flag). For a compiled version of the simulator, install the Visual C++ Build Tools and the Microsoft Windows SDK prior to doing a pip install. The built simulator will not support multithreading due to the limited OpenMP support of msvc.
Should you want to run multithreaded simulations, you can install a compiler which supports newer OpenMP versions, such as MinGW GCC and then manually build the C++ simulator with OpenMP enabled.
macOS:
These are the steps to install ProjectQ on a new Mac:
In order to install the fast C++ simulator, we require that your system has a C++ compiler (see option 3 below on how to only install the slower Python simulator via the –withoutcppsimulator parameter)
Below you will find two options to install the fast C++ simulator. The first one is the easiest and requires only the standard compiler which Apple distributes with XCode. The second option uses macports to install the simulator with additional support for multithreading by using OpenMP, which makes it slightly faster. We show how to install the required C++ compiler (clang) which supports OpenMP and additionally, we show how to install a newer python version.
Note
Depending on your system you might need to use sudo for the installation.
Installation using XCode and the default python:
Install XCode by opening a terminal and running the following command:
xcodeselect install
Next, you will need to install Python and pip. See option 2 for information on how to install a newer python version with macports. Here, we are using the standard python which is preinstalled with macOS. Pip can be installed by:
sudo easy_install pip
Now, you can install ProjectQ with the C++ simulator using the standard command:
python m pip install user projectq
Installation using macports:
Either use the standard python and install pip as shown in option 1 or better use macports to install a newer python version, e.g., Python 3.5 and the corresponding pip. Visit macports.org and install the latest version (afterwards open a new terminal). Then, use macports to install Python 3.5 by
sudo port install python35
It might show a warning that if you intend to use python from the terminal, you should also install
sudo port install py35readline
Install pip by
sudo port install py35pip
Next, we can install ProjectQ with the high performance simulator written in C++. First, we will need to install a suitable compiler with support for C++11, OpenMP, and instrinsics. The best option is to install clang 3.9 also using macports (note: gcc installed via macports does not work)
sudo port install clang3.9
ProjectQ is now installed by:
env CC=clangmp3.9 env CXX=clang++mp3.9 python3.5 m pip install user projectq
Installation with only the slow Python simulator:
While this simulator works fine for small examples, it is suggested to install the high performance simulator written in C++.
If you just want to install ProjectQ with the (slow) Python simulator and no compiler, then first try to install ProjectQ with the default compiler
python m pip install user projectq
which most likely will fail. Then, try again with the flag
withoutcppsimulator
:python m pip install user globaloption=withoutcppsimulator projectq
The ProjectQ syntax¶
Our goal is to have an intuitive syntax in order to enable an easy learning curve. Therefore, ProjectQ features a lean syntax which is close to the mathematical notation used in physics.
For example, consider applying an xrotation by an angle theta to a qubit. In ProjectQ, this looks as follows:
Rx(theta)  qubit
whereas the corresponding notation in physics would be
\(R_x(\theta) \; \text{qubit}\rangle\)
Moreover, the operator separates the classical arguments (on the left) from the quantum arguments (on the right). Next, you will see a basic quantum program using this syntax. Further examples can be found in the docs (Examples in the panel on the left) and in the ProjectQ examples folder on GitHub.
Basic quantum program¶
To check out the ProjectQ syntax in action and to see whether the installation worked, try to run the following basic example
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 backend is a simulator)
qubit = eng.allocate_qubit() # allocate 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))) # output measurement result
Which creates random bits (0 or 1).
Examples¶
All of these example codes and more can be found on GitHub.
Quantum Random Numbers¶
The most basic example is a quantum random number generator (QRNG). It can be found in the examplesfolder of ProjectQ. The code looks as follows
from projectq.ops import H, Measure
from projectq import MainEngine
# create a main compiler engine
eng = MainEngine()
# allocate one qubit
q1 = eng.allocate_qubit()
# put it in superposition
H  q1
# measure
Measure  q1
eng.flush()
# print the result:
print("Measured: {}".format(int(q1)))
Running this code three times may yield, e.g.,
$ python examples/quantum_random_numbers.py
Measured: 0
$ python examples/quantum_random_numbers.py
Measured: 0
$ python examples/quantum_random_numbers.py
Measured: 1
These values are obtained by simulating this quantum algorithm classically. By changing three lines of code, we can run an actual quantum random number generator using the IBM Quantum Experience backend:
$ python examples/quantum_random_numbers_ibm.py
Measured: 1
$ python examples/quantum_random_numbers_ibm.py
Measured: 0
All you need to do is:
 Create an account for IBM’s Quantum Experience
 And perform these minor changes:
 ../examples/quantum_random_numbers.py +++ ../examples/quantum_random_numbers_ibm.py @@ 1,8 +1,10 @@ +import projectq.setups.ibm from projectq.ops import H, Measure from projectq import MainEngine +from projectq.backends import IBMBackend # create a main compiler engine eng = MainEngine() +eng = MainEngine(IBMBackend()) # allocate one qubit q1 = eng.allocate_qubit()
Quantum Teleportation¶
Alice has a qubit in some interesting state \(\psi\rangle\), which she would like to show to Bob. This does not really make sense, since Bob would not be able to look at the qubit without collapsing the superposition; but let’s just assume Alice wants to send her state to Bob for some reason. What she can do is use quantum teleportation to achieve this task. Yet, this only works if Alice and Bob share a Bellpair (which luckily happens to be the case). A Bellpair is a pair of qubits in the state
They can create a Bellpair 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 \(1\rangle\). The circuit diagram can be generated by calling the function
def create_bell_pair(eng):
b1 = eng.allocate_qubit()
b2 = eng.allocate_qubit()
H  b1
CNOT  (b1, b2)
return b1, b2
with a main compiler engine which has a CircuitDrawer backend, i.e.,
from projectq import MainEngine
from projectq.backends import CircuitDrawer
from teleport import create_bell_pair
# create a main compiler engine
drawing_engine = CircuitDrawer()
eng = MainEngine(drawing_engine)
create_bell_pair(eng)
eng.flush()
print(drawing_engine.get_latex())
The resulting LaTeX code can be compiled to produce the circuit diagram:
$ python examples/bellpair_circuit.py > bellpair_circuit.tex
$ pdflatex bellpair_circuit.tex
The output looks as follows:
Now, this Bellpair can be used to achieve the quantum teleportation: Alice entangles her qubit with her share of the Bellpair. Then, she measures both qubits; one in the Zbasis (Measure) and one in the Hadamard basis (Hadamard, then Measure). She then sends her measurement results to Bob who, depending on these outcomes, applies a PauliX or Z gate.
The complete example looks as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73  import projectq.setups.default
from projectq.ops import H, X, Z, Rz, CNOT, Measure
from projectq import MainEngine
from projectq.meta import Dagger, Control
def create_bell_pair(eng):
b1 = eng.allocate_qubit()
b2 = eng.allocate_qubit()
H  b1
CNOT  (b1, b2)
return b1, b2
def run_teleport(eng, state_creation_function, verbose=False):
# make a Bellpair
b1, b2 = create_bell_pair(eng)
# Alice creates a nice state to send
psi = eng.allocate_qubit()
if verbose:
print("Alice is creating her state from scratch, i.e., 0>.")
state_creation_function(eng, psi)
# entangle it with Alice's b1
CNOT  (psi, b1)
if verbose:
print("Alice entangled her qubit with her share of the Bellpair.")
# measure two values (once in Hadamard basis) and send the bits to Bob
H  psi
Measure  (psi, b1)
msg_to_bob = [int(psi), int(b1)]
if verbose:
print("Alice is sending the message {} to Bob.".format(msg_to_bob))
# Bob may have to apply up to two operation depending on the message sent
# by Alice:
with Control(eng, b1):
X  b2
with Control(eng, psi):
Z  b2
# try to uncompute the psi state
if verbose:
print("Bob is trying to uncompute the state.")
with Dagger(eng):
state_creation_function(eng, b2)
# check whether the uncompute was successful. The simulator only allows to
# delete qubits which are in a computational basis state.
del b2
eng.flush()
if verbose:
print("Bob successfully arrived at 0>")
if __name__ == "__main__":
# create a main compiler engine with a simulator backend:
eng = MainEngine()
# define our statecreation routine, which transforms a 0> to the state
# we would like to send. Bob can then try to uncompute it and, if he
# arrives back at 0>, we know that the teleportation worked.
def create_state(eng, qb):
H  qb
Rz(1.21)  qb
# run the teleport and then, let Bob try to uncompute his qubit:
run_teleport(eng, create_state, verbose=True)

and the corresponding circuit can be generated using
$ python examples/teleport_circuit.py > teleport_circuit.tex
$ pdflatex teleport_circuit.tex
which produces (after renaming of the qubits inside the texfile):
Shor’s algorithm for factoring¶
As a third example, consider Shor’s algorithm for factoring, which for a given (large) number \(N\) determines the two prime factor \(p_1\) and \(p_2\) such that \(p_1\cdot p_2 = N\) in polynomial time! This is a superpolynomial speedup over the best known classical algorithm (which is the number field sieve) and enables the breaking of modern encryption schemes such as RSA on a future quantum computer.
 A tiny bit of number theory
There is a small amount of number theory involved, which reduces the problem of factoring to periodfinding of the function
\[f(x) = a^x\operatorname{mod} N\]for some a (relative prime to N, otherwise we get a factor right away anyway by calling gcd(a,N)). The period r for a function f(x) is the number for which \(f(x) = f(x+r)\forall x\) holds. In this case, this means that \(a^x = a^{x+r}\;\; (\operatorname{mod} N)\;\forall x\). Therefore, \(a^r = 1 + qN\) for some integer q and hence, \(a^r  1 = (a^{r/2}  1)(a^{r/2}+1) = qN\). This suggests that using the gcd on N and \(a^{r/2} \pm 1\) we may find a factor of N!
 Factoring on a quantum computer: An example
At the heart of Shor’s algorithm lies modular exponentiation of a classically known constant (denoted by a in the code) by a quantum superposition of numbers \(x\), i.e.,
\[x\rangle0\rangle \mapsto x\ranglea^x\operatorname{mod} N\rangle\]Using \(N=15\) and \(a=2\), and applying this operation to the uniform superposition over all \(x\) leads to the superposition (modulo renormalization)
\[0\rangle1\rangle + 1\rangle2\rangle + 2\rangle4\rangle + 3\rangle8\rangle + 4\rangle1\rangle + 5\rangle2\rangle + 6\rangle4\rangle + \cdots\]In Shor’s algorithm, the second register will not be touched again before the end of the quantum program, which means it might as well be measured now. Let’s assume we measure 2; this collapses the state above to
\[1\rangle2\rangle + 5\rangle2\rangle + 9\rangle2\rangle + \cdots\]The period of a modulo N can now be read off. On a quantum computer, this information can be accessed by applying an inverse quantum Fourier transform to the xregister, followed by a measurement of x.
 Implementation
There is an implementation of Shor’s algorithm in the examples folder. It uses the implementation by Beauregard, arxiv:0205095 to factor an nbit number using 2n+3 qubits. In this implementation, the modular exponentiation is carried out using modular multiplication and shift. Furthermore it uses the semiclassical quantum Fourier transform [see arxiv:9511007]: Pulling the final measurement of the xregister through the final inverse quantum Fourier transform allows to run the 2n modular multiplications serially, which keeps one from having to store the 2n qubits of x.
Let’s run it using the ProjectQ simulator:
$ python3 examples/shor.py projectq  Implementation of Shor's algorithm. Number to factor: 15 Factoring N = 15: 00000001 Factors found :) : 3 * 5 = 15
Simulating Shor’s algorithm at the level of singlequbit 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 lowlevel gates, but carries it out directly instead, we can change the line
91 92 93 94 95 96 97 98 99 100 101 102
# return the (potential) period return r # Filter function, which defines the gate set for the first optimization # (don't decompose QFTs and iQFTs to make cancellation easier) def high_level_gates(eng, cmd): g = cmd.gate if g == QFT or get_inverse(g) == QFT or g == Swap: return True if isinstance(g, BasicMathGate):
in examples/shor.py to return True. This allows to factor, e.g. \(N=4,028,033\) in under 3 minutes on a regular laptop!
The most important part of the code is
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
measurements = [0] * (2 * n) # will hold the 2n measurement results ctrl_qubit = eng.allocate_qubit() for k in range(2 * n): current_a = pow(a, 1 << (2 * n  1  k), N) # one iteration of 1qubit QPE H  ctrl_qubit with Control(eng, ctrl_qubit): MultiplyByConstantModN(current_a, N)  x # perform inverse QFT > Rotations conditioned on previous outcomes for i in range(k): if measurements[i]: R(math.pi/(1 << (k  i)))  ctrl_qubit H  ctrl_qubit # and measure Measure  ctrl_qubit
which executes the 2n modular multiplications conditioned on a control qubit ctrl_qubit in a uniform superposition of 0 and 1. The control qubit is then measured after performing the semiclassical inverse quantum Fourier transform and the measurement outcome is saved in the list measurements, followed by a reset of the control qubit to state 0.
Code Documentation¶
Welcome to the package documentation of ProjectQ. You may now browse through the entire documentation and discover the capabilities of the ProjectQ framework.
For a detailed documentation of a subpackage or module, click on its name below:
backends¶
Module contents¶
Contains backends for ProjectQ.
This includes:
 a debugging tool to print all received commands (CommandPrinter)
 a circuit drawing engine (which can be used anywhere within the compilation chain)
 a simulator with emulation capabilities
 a resource counter (counts gates and keeps track of the maximal width of the circuit)
 an interface to the IBM Quantum Experience chip (and simulator).

class
projectq.backends.
CircuitDrawer
(accept_input=False, default_measure=0)¶ CircuitDrawer is a compiler engine which generates TikZ code for drawing quantum circuits.
The circuit can be modified by editing the settings.json file which is generated upon first execution. This includes adjusting the gate width, height, shadowing, line thickness, and many more options.
After initializing the CircuitDrawer, it can also be given the mapping from qubit IDs to wire location (via the
set_qubit_locations()
function):circuit_backend = CircuitDrawer() circuit_backend.set_qubit_locations({0: 1, 1: 0}) # swap lines 0 and 1 eng = MainEngine(circuit_backend) ... # run quantum algorithm on this main engine print(circuit_backend.get_latex()) # prints LaTeX code
To see the qubit IDs in the generated circuit, simply set the draw_id option in the settings.json file under “gates”:”AllocateQubitGate” to True:
"gates": { "AllocateQubitGate": { "draw_id": True, "height": 0.15, "width": 0.2, "pre_offset": 0.1, "offset": 0.1 }, ...
The settings.json file has the following structure:
{ "control": { # settings for control "circle" "shadow": false, "size": 0.1 }, "gate_shadow": true, # enable/disable shadows for all gates "gates": { "GateClassString": { GATE_PROPERTIES } "GateClassString2": { ... }, "lines": { # settings for qubit lines "double_classical": true, # draw doublelines for # classical bits "double_lines_sep": 0.04, # gap between the two lines # for double lines "init_quantum": true, # start out with quantum bits "style": "very thin" # line style } }
All gates (except for the ones requiring special treatment) support the following properties:
"GateClassString": { "height": GATE_HEIGHT, "width": GATE_WIDTH "pre_offset": OFFSET_BEFORE_PLACEMENT, "offset": OFFSET_AFTER_PLACEMENT, },

__init__
(accept_input=False, default_measure=0)¶ Initialize a circuit drawing engine.
The TikZ code generator uses a settings file (settings.json), which can be altered by the user. It contains gate widths, heights, offsets, etc.
Parameters:  accept_input (bool) – If accept_input is true, the printer queries the user to input measurement results if the CircuitDrawer is the last engine. Otherwise, all measurements yield the result default_measure (0 or 1).
 default_measure (bool) – Default value to use as measurement results if accept_input is False and there is no underlying backend to register real measurement results.

get_latex
()¶ Return the latex document string representing the circuit.
Simply write this string into a texfile or, alternatively, pipe the output directly to, e.g., pdflatex:
python3 my_circuit.py  pdflatex
where my_circuit.py calls this function and prints it to the terminal.

is_available
(cmd)¶ Specialized implementation of is_available: Returns True if the CircuitDrawer is the last engine (since it can print any command).
Parameters: cmd (Command) – Command for which to check availability (all Commands can be printed). Returns: True, unless the next engine cannot handle the Command (if there is a next engine). Return type: availability (bool)

receive
(command_list)¶ Receive a list of commands from the previous engine, print the commands, and then send them on to the next engine.
Parameters: command_list (list<Command>) – List of Commands to print (and potentially send on to the next engine).

set_qubit_locations
(id_to_loc)¶ Sets the qubit lines to use for the qubits explicitly.
To figure out the qubit IDs, simply use the setting draw_id in the settings file. It is located in “gates”:”AllocateQubitGate”. If draw_id is True, the qubit IDs are drawn in red.
Parameters: id_to_loc (dict) – Dictionary mapping qubit ids to qubit line numbers. Raises: RuntimeError
– If the mapping has already begun (this function needs be called before any gates have been received).


class
projectq.backends.
ClassicalSimulator
¶ A simple introspective simulator that only permits classical operations.
Allows allocation, deallocation, measuring (noop), flushing (noop), controls, NOTs, and any BasicMathGate. Supports reading/writing directly from/to bits and registers of bits.

read_bit
(qubit)¶ Reads a bit.
Parameters: qubit (projectq.types.Qubit) – The bit to read. Returns: 0 if the target bit is off, 1 if it’s on. Return type: int

read_register
(qureg)¶ Reads a group of bits as a littleendian integer.
Parameters: qureg (projectq.types.Qureg) – The group of bits to read, in littleendian order. Returns: Littleendian register value. Return type: int

write_bit
(qubit, value)¶ Resets/sets a bit to the given value.
Parameters:  qubit (projectq.types.Qubit) – The bit to write.
 value (boolint) – Writes 1 if this value is truthy, else 0.

write_register
(qureg, value)¶ Sets a group of bits to store a littleendian integer value.
Parameters:  qureg (projectq.types.Qureg) – The bits to write, in littleendian order.
 value (int) – The integer value to store. Must fit in the register.


class
projectq.backends.
CommandPrinter
(accept_input=True, default_measure=False, in_place=False)¶ CommandPrinter is a compiler engine which prints commands to stdout prior to sending them on to the next compiler engine.

__init__
(accept_input=True, default_measure=False, in_place=False)¶ Initialize a CommandPrinter.
Parameters:  accept_input (bool) – If accept_input is true, the printer queries the user to input measurement results if the CommandPrinter is the last engine. Otherwise, all measurements yield default_measure.
 default_measure (bool) – Default measurement result (if accept_input is False).
 in_place (bool) – If in_place is true, all output is written on the same line of the terminal.

is_available
(cmd)¶ Specialized implementation of is_available: Returns True if the CommandPrinter is the last engine (since it can print any command).
Parameters: cmd (Command) – Command of which to check availability (all Commands can be printed). Returns:  True, unless the next engine cannot handle
 the Command (if there is a next engine).
Return type: availability (bool)

receive
(command_list)¶ Receive a list of commands from the previous engine, print the commands, and then send them on to the next engine.
Parameters: command_list (list<Command>) – List of Commands to print (and potentially send on to the next engine).


class
projectq.backends.
IBMBackend
(use_hardware=False, num_runs=1024, verbose=False, user=None, password=None, device='ibmqx2')¶ The IBM Backend class, which stores the circuit, transforms it to JSON QASM, and sends the circuit through the IBM API.

__init__
(use_hardware=False, num_runs=1024, verbose=False, user=None, password=None, device='ibmqx2')¶ Initialize the Backend object.
Parameters:  use_hardware (bool) – If True, the code is run on the IBM quantum chip (instead of using the IBM simulator)
 num_runs (int) – Number of runs to collect statistics. (default is 1024)
 verbose (bool) – If True, statistics are printed, in addition to the measurement result being registered (at the end of the circuit).
 user (string) – IBM Quantum Experience user name
 password (string) – IBM Quantum Experience password
 device (string) – Device to use (‘ibmqx2’ or ‘ibmqx4’) if use_hardware is set to True. Default is ibmqx2.

get_probabilities
(qureg)¶ Return the list of basis states with corresponding probabilities.
The measured bits are ordered according to the supplied quantum register, i.e., the leftmost bit in the statestring corresponds to the first qubit in the supplied quantum register.
Warning
Only call this function after the circuit has been executed!
Parameters: qureg (list<Qubit>) – Quantum register determining the order of the qubits. Returns: Dictionary mapping nbit strings to probabilities. Return type: probability_dict (dict) Raises: RuntimeError
– If no data is available (i.e., if the circuit has not been executed). Or if a qubit was supplied which was not present in the circuit (might have gotten optimized away).

is_available
(cmd)¶ Return true if the command can be executed.
The IBM quantum chip can do X, Y, Z, T, Tdag, S, Sdag, and CX / CNOT.
Parameters: cmd (Command) – Command for which to check availability

receive
(command_list)¶ Receives a command list and, for each command, stores it until completion.
Parameters: command_list – List of commands to execute


class
projectq.backends.
ResourceCounter
¶ ResourceCounter is a compiler engine which counts the number of gates and max. number of active qubits.

gate_counts
¶ dict – Dictionary of gate counts. The keys are string representations of the gate.

max_width
¶ int – Maximal width (=max. number of active qubits at any given point).

__init__
()¶ Initialize a resource counter engine.
Sets all statistics to zero.

is_available
(cmd)¶ Specialized implementation of is_available: Returns True if the ResourceCounter is the last engine (since it can count any command).
Parameters: cmd (Command) – Command for which to check availability (all Commands can be counted). Returns:  True, unless the next engine cannot handle
 the Command (if there is a next engine).
Return type: availability (bool)

receive
(command_list)¶ Receive a list of commands from the previous engine, print the commands, and then send them on to the next engine.
Parameters: command_list (list<Command>) – List of commands to receive (and count).


class
projectq.backends.
Simulator
(gate_fusion=False, rnd_seed=None)¶ Simulator is a compiler engine which simulates a quantum computer using C++based kernels.
OpenMP is enabled and the number of threads can be controlled using the OMP_NUM_THREADS environment variable, i.e.
export OMP_NUM_THREADS=4 # use 4 threads export OMP_PROC_BIND=spread # bind threads to processors by spreading

__init__
(gate_fusion=False, rnd_seed=None)¶ Construct the C++/Pythonsimulator object and initialize it with a random seed.
Parameters:  gate_fusion (bool) – If True, gates are cached and only executed once a certain gatesize has been reached (only has an effect for the c++ simulator).
 rnd_seed (int) – Random seed (uses random.randint(0, 1024) by default).
Example of gate_fusion: Instead of applying a Hadamard gate to 5 qubits, the simulator calculates the kronecker product of the 1qubit matrices and then applies 1 5qubit gate. This increases operational intensity and keeps the simulator from having to iterate through the state vector multiple times. Depending on the system (and, especially, number of threads), this may or may not be beneficial.
Note
If the C++ Simulator extension was not built or cannot be found, the Simulator defaults to a Python implementation of the kernels. While this is much slower, it is still good enough to run basic quantum algorithms.
If you need to run large simulations, check out the tutorial in the docs which gives futher hints on how to build the C++ extension.

apply_qubit_operator
(qubit_operator, qureg)¶ Apply a (possibly nonunitary) qubit_operator to the current wave function represented by the supplied quantum register.
Parameters:  qubit_operator (projectq.ops.QubitOperator) – Operator to apply.
 qureg (list[Qubit],Qureg) – Quantum bits to which to apply the operator.
Warning
This function allows applying nonunitary gates and it will not renormalize the wave function! It is for numerical experiments only and should not be used for other purposes.
Note
Make sure all previous commands (especially allocations) have passed through the compilation chain (call main_engine.flush() to make sure).
Raises: Exception
– If qubit_operator acts on more qubits than present in the qureg argument.

cheat
()¶ Access the ordering of the qubits and the state vector directly.
This is a cheat function which enables, e.g., more efficient evaluation of expectation values and debugging.
Returns: A tuple where the first entry is a dictionary mapping qubit indices to bitlocations and the second entry is the corresponding state vector. Note
Make sure all previous commands have passed through the compilation chain (call main_engine.flush() to make sure).

collapse_wavefunction
(qureg, values)¶ Collapse a quantum register onto a classical basis state.
Parameters:  qureg (Qureglist[Qubit]) – Qubits to collapse.
 values (list[bool]) – Measurement outcome for each of the qubits in qureg.
Raises: RuntimeError
– If an outcome has probability (approximately) 0 or if unknown qubits are provided (see note).Note
Make sure all previous commands have passed through the compilation chain (call main_engine.flush() to make sure).

get_amplitude
(bit_string, qureg)¶ Return the probability amplitude of the supplied bit_string. The ordering is given by the quantum register qureg, which must contain all allocated qubits.
Parameters:  bit_string (list[boolint]string[01]) – Computational basis state
 qureg (Qureglist[Qubit]) – Quantum register determining the ordering. Must contain all allocated qubits.
Returns: Probability amplitude of the provided bit string.
Note
Make sure all previous commands (especially allocations) have passed through the compilation chain (call main_engine.flush() to make sure).

get_expectation_value
(qubit_operator, qureg)¶ Get the expectation value of qubit_operator w.r.t. the current wave function represented by the supplied quantum register.
Parameters:  qubit_operator (projectq.ops.QubitOperator) – Operator to measure.
 qureg (list[Qubit],Qureg) – Quantum bits to measure.
Returns: Expectation value
Note
Make sure all previous commands (especially allocations) have passed through the compilation chain (call main_engine.flush() to make sure).
Raises: Exception
– If qubit_operator acts on more qubits than present in the qureg argument.

get_probability
(bit_string, qureg)¶ Return the probability of the outcome bit_string when measuring the quantum register qureg.
Parameters:  bit_string (list[boolint]string[01]) – Measurement outcome.
 qureg (Qureglist[Qubit]) – Quantum register.
Returns: Probability of measuring the provided bit string.
Note
Make sure all previous commands (especially allocations) have passed through the compilation chain (call main_engine.flush() to make sure).

is_available
(cmd)¶ Specialized implementation of is_available: The simulator can deal with all arbitrarilycontrolled singlequbit gates which provide a gatematrix (via gate.matrix).
Parameters: cmd (Command) – Command for which to check availability (single qubit gate, arbitrary controls) Returns: True if it can be simulated and False otherwise.

receive
(command_list)¶ Receive a list of commands from the previous engine and handle them (simulate them classically) prior to sending them on to the next engine.
Parameters: command_list (list<Command>) – List of commands to execute on the simulator.

set_wavefunction
(wavefunction, qureg)¶ Set the wavefunction and the qubit ordering of the simulator.
The simulator will adopt the ordering of qureg (instead of reordering the wavefunction).
Parameters:  wavefunction (list[complex]) – Array of complex amplitudes describing the wavefunction (must be normalized).
 qureg (Qureglist[Qubit]) – Quantum register determining the ordering. Must contain all allocated qubits.
Note
Make sure all previous commands (especially allocations) have passed through the compilation chain (call main_engine.flush() to make sure).

cengines¶
The ProjectQ compiler engines package.
Module contents¶

class
projectq.cengines.
AutoReplacer
(decompositionRuleSet, decomposition_chooser=<function AutoReplacer.<lambda>>)¶ The AutoReplacer is a compiler engine which uses engine.is_available in order to determine which commands need to be replaced/decomposed/compiled further. The loaded setup is used to find decomposition rules appropriate for each command (e.g., setups.default).

__init__
(decompositionRuleSet, decomposition_chooser=<function AutoReplacer.<lambda>>)¶ Initialize an AutoReplacer.
Parameters: decomposition_chooser (function) – A function which, given the Command to decompose and a list of potential Decomposition objects, determines (and then returns) the ‘best’ decomposition. The default decomposition chooser simply returns the first list element, i.e., calling
repl = AutoReplacer()
Amounts to
def decomposition_chooser(cmd, decomp_list): return decomp_list[0] repl = AutoReplacer(decomposition_chooser)

receive
(command_list)¶ Receive a list of commands from the previous compiler engine and, if necessary, replace/decompose the gates according to the decomposition rules in the loaded setup.
Parameters: command_list (list<Command>) – List of commands to handle.


class
projectq.cengines.
BasicEngine
¶ Basic compiler engine: All compiler engines are derived from this class. It provides basic functionality such as qubit allocation/deallocation and functions that provide information about the engine’s position (e.g., next engine).
This information is provided by the MainEngine, which initializes all further engines.

next_engine
¶ BasicEngine – Next compiler engine (or the backend).

main_engine
¶ MainEngine – Reference to the main compiler engine.

is_last_engine
¶ bool – True for the last engine, which is the backend.

__init__
()¶ Initialize the basic engine.
Initializes local variables such as _next_engine, _main_engine, etc. to None.

allocate_qubit
(dirty=False)¶ Return a new qubit as a list containing 1 qubit object (quantum register of size 1).
Allocates a new qubit by getting a (new) qubit id from the MainEngine, creating the qubit object, and then sending an AllocateQubit command down the pipeline. If dirty=True, the fresh qubit can be replaced by a preallocated one (in an unknown, dirty, initial state). Dirty qubits must be returned to their initial states before they are deallocated / freed.
All allocated qubits are added to the MainEngine’s set of active qubits as weak references. This allows proper cleanup at the end of the Python program (using atexit), deallocating all qubits which are still alive. Qubit ids of dirty qubits are registered in MainEngine’s dirty_qubits set.
Parameters: dirty (bool) – If True, indicates that the allocated qubit may be dirty (i.e., in an arbitrary initial state). Returns: Qureg of length 1, where the first entry is the allocated qubit.

allocate_qureg
(n)¶ Allocate n qubits and return them as a quantum register, which is a list of qubit objects.
Parameters: n (int) – Number of qubits to allocate Returns: Qureg of length n, a list of n newly allocated qubits.

deallocate_qubit
(qubit)¶ Deallocate a qubit (and sends the deallocation command down the pipeline). If the qubit was allocated as a dirty qubit, add DirtyQubitTag() to Deallocate command.
Parameters: qubit (BasicQubit) – Qubit to deallocate. Raises: ValueError
– Qubit already deallocated. Caller likely has a bug.

is_available
(cmd)¶ Default implementation of is_available: Ask the next engine whether a command is available, i.e., whether it can be executed by the next engine(s).
Parameters: cmd (Command) – Command for which to check availability. Returns: True if the command can be executed. Raises: LastEngineException
– If is_last_engine is True but is_available is not implemented.

is_meta_tag_supported
(meta_tag)¶ Check if there is a compiler engine handling the meta tag
Parameters:  engine – First engine to check (then iteratively calls getNextEngine)
 meta_tag – Meta tag class for which to check support
Returns: True if one of the further compiler engines is a meta tag handler, i.e., engine.is_meta_tag_handler(meta_tag) returns True.
Return type: supported (bool)

send
(command_list)¶ Forward the list of commands to the next engine in the pipeline.


class
projectq.cengines.
CommandModifier
(cmd_mod_fun)¶ CommandModifier is a compiler engine which applies a function to all incoming commands, sending on the resulting command instead of the original one.

__init__
(cmd_mod_fun)¶ Initialize the CommandModifier.
Parameters: cmd_mod_fun (function) – Function which, given a command cmd, returns the command it should send instead. Example
def cmd_mod_fun(cmd): cmd.tags += [MyOwnTag()] compiler_engine = CommandModifier(cmd_mod_fun) ...

receive
(command_list)¶ Receive a list of commands from the previous engine, modify all commands, and send them on to the next engine.
Parameters: command_list (list<Command>) – List of commands to receive and then (after modification) send on.


class
projectq.cengines.
CompareEngine
¶ CompareEngine is an engine which saves all commands. It is only intended for testing purposes. Two CompareEngine backends can be compared and return True if they contain the same commmands.

class
projectq.cengines.
DecompositionRule
(gate_class, gate_decomposer, gate_recognizer=<function DecompositionRule.<lambda>>)¶ A rule for breaking down specific gates into sequences of simpler gates.

__init__
(gate_class, gate_decomposer, gate_recognizer=<function DecompositionRule.<lambda>>)¶ Parameters:  gate_class (type) –
The type of gate that this rule decomposes.
The gate class is redundant information used to make lookups faster when iterating over a circuit and deciding “which rules apply to this gate?” again and again.
Note that this parameter is a gate type, not a gate instance. You supply gate_class=MyGate or gate_class=MyGate().__class__, not gate_class=MyGate().
 gate_decomposer (function[projectq.ops.Command]) – Function which, given the command to decompose, applies a sequence of gates corresponding to the highlevel function of a gate of type gate_class.
 (function[projectq.ops.Command] (gate_recognizer) –
boolean): A predicate that determines if the decomposition applies to the given command (on top of the filtering by gate_class).
For example, a decomposition rule may only to apply rotation gates that rotate by a specific angle.
If no gate_recognizer is given, the decomposition applies to all gates matching the gate_class.
 gate_class (type) –


class
projectq.cengines.
DecompositionRuleSet
(rules=None, modules=None)¶ A collection of indexed decomposition rules.

__init__
(rules=None, modules=None)¶ Parameters:  list[DecompositionRule] (rules) – Initial decomposition rules.
 modules (iterable[ModuleWithDecompositionRuleSet]) – A list of things with an “all_defined_decomposition_rules” property containing decomposition rules to add to the rule set.

add_decomposition_rule
(rule)¶ Add a decomposition rule to the rule set.
Parameters: rule (DecompositionRuleGate) – The decomposition rule to add.


class
projectq.cengines.
DummyEngine
(save_commands=False)¶ DummyEngine used for testing.
The DummyEngine forwards all commands directly to next engine. If self.is_last_engine == True it just discards all gates. By setting save_commands == True all commands get saved as a list in self.received_commands. Elements are appended to this list so they are ordered according to when they are received.

__init__
(save_commands=False)¶ Initialize DummyEngine
Parameters: save_commands (default = False) – If True, commands are saved in self.received_commands.


class
projectq.cengines.
ForwarderEngine
(engine, cmd_mod_fun=None)¶ A ForwarderEngine is a trivial engine which forwards all commands to the next engine.
It is mainly used as a substitute for the MainEngine at lower levels such that meta operations still work (e.g., with Compute).

__init__
(engine, cmd_mod_fun=None)¶ Initialize a ForwarderEngine.
Parameters:  engine (BasicEngine) – Engine to forward all commands to.
 cmd_mod_fun (function) – Function which is called before sending a command. Each command cmd is replaced by the command it returns when getting called with cmd.

receive
(command_list)¶ Forward all commands to the next engine.


class
projectq.cengines.
IBMCNOTMapper
¶ CNOT mapper for the IBM backend.
Maps a given circuit to the IBM Quantum Experience chip. If necessary, it will flip around the CNOT gate by first applying Hadamard gates to both qubits, then CNOT with swapped control and target qubit, and finally Hadamard gates to both qubits. Furthermore, it adds QubitPlacementTags to Allocate gate commands.
Note
The mapper has to be run once on the entire circuit.
Warning
If the provided circuit cannot be mapped to the hardware layout without performing Swaps, the mapping procedure raises an Exception.

__init__
()¶ Initialize an IBM CNOT Mapper compiler engine.
Resets the mapping.

is_available
(cmd)¶ Check if the IBM backend can perform the Command cmd and return True if so.
Parameters: cmd (Command) – The command to check

receive
(command_list)¶ Receives a command list and, for each command, stores it until completion.
Parameters: command_list (list of Command objects) – list of commands to receive. Raises: Exception
– If mapping the CNOT gates to 1 qubit would require Swaps. The current version only supports remapping of CNOT gates without performing any Swaps due to the large costs associated with Swapping given the CNOT constraints.


class
projectq.cengines.
InstructionFilter
(filterfun)¶ The InstructionFilter is a compiler engine which changes the behavior of is_available according to a filter function. All commands are passed to this function, which then returns whether this command can be executed (True) or needs replacement (False).

__init__
(filterfun)¶ Initializer: The provided filterfun returns True for all commands which do not need replacement and False for commands that do.
Parameters: filterfun (function) – Filter function which returns True for available commands, and False otherwise. filterfun will be called as filterfun(self, cmd).

is_available
(cmd)¶ Specialized implementation of BasicBackend.is_available: Forwards this call to the filter function given to the constructor.
Parameters: cmd (Command) – Command for which to check availability.

receive
(command_list)¶ Forward all commands to the next engine.
Parameters: command_list (list<Command>) – List of commands to receive.


exception
projectq.cengines.
LastEngineException
(engine)¶ Exception thrown when the last engine tries to access the next one. (Next engine does not exist)
The default implementation of isAvailable simply asks the next engine whether the command is available. An engine which legally may be the last engine, this behavior needs to be adapted (see BasicEngine.isAvailable).

class
projectq.cengines.
LocalOptimizer
(m=5)¶ LocalOptimizer is a compiler engine which optimizes locally (merging rotations, cancelling gates with their inverse) in a local window of user defined size.
It stores all commands in a list of lists, where each qubit has its own gate pipeline. After adding a gate, it tries to merge / cancel successive gates using the get_merged and get_inverse functions of the gate (if available). For examples, see BasicRotationGate. Once a list corresponding to a qubit contains >=m gates, the pipeline is sent on to the next engine.

__init__
(m=5)¶ Initialize a LocalOptimizer object.
Parameters: m (int) – Number of gates to cache per qubit, before sending on the first gate.

receive
(command_list)¶ Receive commands from the previous engine and cache them. If a flush gate arrives, the entire buffer is sent on.


class
projectq.cengines.
MainEngine
(backend=None, engine_list=None)¶ The MainEngine class provides all functionality of the main compiler engine.
It initializes all further compiler engines (calls, e.g., .next_engine=...) and keeps track of measurement results and active qubits (and their IDs).

next_engine
¶ BasicEngine – Next compiler engine (or the backend).

main_engine
¶ MainEngine – Self.

active_qubits
¶ WeakSet – WeakSet containing all active qubits

dirty_qubits
¶ Set – Containing all dirty qubit ids

backend
¶ BasicEngine – Access the backend.

__init__
(backend=None, engine_list=None)¶ Initialize the main compiler engine and all compiler engines.
Sets ‘next_engine’ and ‘main_engine’attributes of all compiler engines and adds the backend as the last engine.
Parameters:  backend (BasicEngine) – Backend to send the circuit to.
 engine_list (list<BasicEngine>) – List of engines / backends to use as compiler engines.
Example
from projectq import MainEngine eng = MainEngine() # uses default setup and the Simulator
Alternatively, one can specify all compiler engines explicitly, e.g.,
Example
from projectq.cengines import (TagRemover, AutoReplacer, LocalOptimizer, DecompositionRuleSet) from projectq.backends import Simulator from projectq import MainEngine rule_set = DecompositionRuleSet() engines = [AutoReplacer(rule_set), TagRemover(), LocalOptimizer(3)] eng = MainEngine(Simulator(), engines)

flush
(deallocate_qubits=False)¶ Flush the entire circuit down the pipeline, clearing potential buffers (of, e.g., optimizers).
Parameters: deallocate_qubits (bool) – If True, deallocates all qubits that are still alive (invalidating references to them by setting their id to 1).

get_measurement_result
(qubit)¶ Return the classical value of a measured qubit, given that an engine registered this result previously (see setMeasurementResult).
Parameters: qubit (BasicQubit) – Qubit of which to get the measurement result. Example
from projectq.ops import H, Measure from projectq import MainEngine eng = MainEngine() qubit = eng.allocate_qubit() # quantum register of size 1 H  qubit Measure  qubit eng.get_measurement_result(qubit[0]) == int(qubit)

get_new_qubit_id
()¶ Returns a unique qubit id to be used for the next qubit allocation.
Returns: New unique qubit id. Return type: new_qubit_id (int)

receive
(command_list)¶ Forward the list of commands to the first engine.
Parameters: command_list (list<Command>) – List of commands to receive (and then send on)

set_measurement_result
(qubit, value)¶ Register a measurement result
The engine being responsible for measurement results needs to register these results with the master engine such that they are available when the user calls an int() or bool() conversion operator on a measured qubit.
Parameters:  qubit (BasicQubit) – Qubit for which to register the measurement result.
 value (bool) – Boolean value of the measurement outcome (True / False = 1 / 0 respectively).


class
projectq.cengines.
TagRemover
(tags=[<class 'projectq.meta._compute.ComputeTag'>, <class 'projectq.meta._compute.UncomputeTag'>])¶ TagRemover is a compiler engine which removes temporary command tags (see the tag classes such as LoopTag in projectq.meta._loop).
Removing tags is important (after having handled them if necessary) in order to enable optimizations across metafunction boundaries (compute/ action/uncompute or loops after unrolling)

__init__
(tags=[<class 'projectq.meta._compute.ComputeTag'>, <class 'projectq.meta._compute.UncomputeTag'>])¶ Construct the TagRemover.
Parameters: tags – A list of meta tag classes (e.g., [ComputeTag, UncomputeTag]) denoting the tags to remove

receive
(command_list)¶ Receive a list of commands from the previous engine, remove all tags which are an instance of at least one of the meta tags provided in the constructor, and then send them on to the next compiler engine.
Parameters: command_list (list<Command>) – List of commands to receive and then (after removing tags) send on.

libs¶
The library collection of ProjectQ which, for now, only consists of a tiny math library. Soon, more libraries will be added.
Subpackages¶
math¶
A tiny math library which will be extended thoughout the next weeks. Right now, it only contains the math functions necessary to run Beauregard’s implementation of Shor’s algorithm.
Module contents¶

class
projectq.libs.math.
AddConstant
(a)¶ Add a constant to a quantum number represented by a quantum register, stored from low to highbit.
Example
qunum = eng.allocate_qureg(5) # 5qubit number X  qunum[1] # qunum is now equal to 2 AddConstant(3)  qunum # qunum is now equal to 5

__init__
(a)¶ Initializes the gate to the number to add.
Parameters: a (int) – Number to add to a quantum register. It also initializes its base class, BasicMathGate, with the corresponding function, so it can be emulated efficiently.

get_inverse
()¶ Return the inverse gate (subtraction of the same constant).


class
projectq.libs.math.
AddConstantModN
(a, N)¶ Add a constant to a quantum number represented by a quantum register modulo N.
The number is stored from low to highbit, i.e., qunum[0] is the LSB.
Example
qunum = eng.allocate_qureg(5) # 5qubit number X  qunum[1] # qunum is now equal to 2 AddConstantModN(3, 4)  qunum # qunum is now equal to 1

__init__
(a, N)¶ Initializes the gate to the number to add modulo N.
Parameters:  a (int) – Number to add to a quantum register (0 <= a < N).
 N (int) – Number modulo which the addition is carried out.
It also initializes its base class, BasicMathGate, with the corresponding function, so it can be emulated efficiently.

get_inverse
()¶ Return the inverse gate (subtraction of the same number a modulo the same number N).


class
projectq.libs.math.
MultiplyByConstantModN
(a, N)¶ Multiply a quantum number represented by a quantum register by a constant modulo N.
The number is stored from low to highbit, i.e., qunum[0] is the LSB.
Example
qunum = eng.allocate_qureg(5) # 5qubit number X  qunum[2] # qunum is now equal to 4 MultiplyByConstantModN(3,5)  qunum # qunum is now 2.

__init__
(a, N)¶ Initializes the gate to the number to multiply with modulo N.
Parameters:  a (int) – Number by which to multiply a quantum register (0 <= a < N).
 N (int) – Number modulo which the multiplication is carried out.
It also initializes its base class, BasicMathGate, with the corresponding function, so it can be emulated efficiently.


projectq.libs.math.
SubConstant
(a)¶ Subtract a constant from a quantum number represented by a quantum register, stored from low to highbit.
Parameters: a (int) – Constant to subtract Example
qunum = eng.allocate_qureg(5) # 5qubit number X  qunum[2] # qunum is now equal to 4 SubConstant(3)  qunum # qunum is now equal to 1

projectq.libs.math.
SubConstantModN
(a, N)¶ Subtract a constant from a quantum number represented by a quantum register modulo N.
The number is stored from low to highbit, i.e., qunum[0] is the LSB.
Parameters:  a (int) – Constant to add
 N (int) – Constant modulo which the addition of a should be carried out.
Example
qunum = eng.allocate_qureg(3) # 3qubit number X  qunum[1] # qunum is now equal to 2 SubConstantModN(4,5)  qunum # qunum is now 2 = 6 = 1 (mod 5)
Module contents¶
meta¶
Contains meta statements which allow more optimal code while making it easier for users to write their code. Examples are with Compute, followed by an automatic uncompute or with Control, which allows the user to condition an entire code block upon the state of a qubit.
Module contents¶
The projectq.meta package features meta instructions which help both the user and the compiler in writing/producing efficient code. It includes, e.g.,
 Loop (with Loop(eng): ...)
 Compute/Uncompute (with Compute(eng): ..., [...], Uncompute(eng))
 Control (with Control(eng, ctrl_qubits): ...)
 Dagger (with Dagger(eng): ...)

class
projectq.meta.
Compute
(engine)¶ Start a computesection.
Example
with Compute(eng): do_something(qubits) action(qubits) Uncompute(eng) # runs inverse of the compute section
Warning
If qubits are allocated within the compute section, they must either be uncomputed and deallocated within that section or, alternatively, uncomputed and deallocated in the following uncompute section.
This means that the following examples are valid:
with Compute(eng): anc = eng.allocate_qubit() do_something_with_ancilla(anc) ... uncompute_ancilla(anc) del anc do_something_else(qubits) Uncompute(eng) # will allocate a new ancilla (with a different id) # and then deallocate it again
with Compute(eng): anc = eng.allocate_qubit() do_something_with_ancilla(anc) ... do_something_else(qubits) Uncompute(eng) # will deallocate the ancilla!
After the uncompute section, ancilla qubits allocated within the compute section will be invalid (and deallocated). The same holds when using CustomUncompute.
Failure to comply with these rules results in an exception being thrown.

__init__
(engine)¶ Initialize a Compute context.
Parameters: engine (BasicEngine) – Engine which is the first to receive all commands (normally: MainEngine).


class
projectq.meta.
ComputeTag
¶ Compute meta tag.

class
projectq.meta.
Control
(engine, qubits)¶ Condition an entire code block on the value of qubits being 1.
Example
with Control(eng, ctrlqubits): do_something(otherqubits)

__init__
(engine, qubits)¶ Enter a controlled section.
Parameters:  engine – Engine which handles the commands (usually MainEngine)
 qubits (list of Qubit objects) – Qubits to condition on
Enter the section using a withstatement:
with Control(eng, ctrlqubits): ...


class
projectq.meta.
CustomUncompute
(engine)¶ Start a custom uncomputesection.
Example
with Compute(eng): do_something(qubits) action(qubits) with CustomUncompute(eng): do_something_inverse(qubits)
Raises: QubitManagementError
– If qubits are allocated within Compute or within CustomUncompute context but are not deallocated.
__init__
(engine)¶ Initialize a CustomUncompute context.
Parameters: engine (BasicEngine) – Engine which is the first to receive all commands (normally: MainEngine).


class
projectq.meta.
Dagger
(engine)¶ Invert an entire code block.
Use it with a withstatement, i.e.,
with Dagger(eng): [code to invert]
Warning
If the code to invert contains allocation of qubits, those qubits have to be deleted prior to exiting the ‘with Dagger()’ context.
This code is NOT VALID:
with Dagger(eng): qb = eng.allocate_qubit() H  qb # qb is still available!!!
The correct way of handling qubit (de)allocation is as follows:
with Dagger(eng): qb = eng.allocate_qubit() ... del qb # sends deallocate gate (which becomes an allocate)

__init__
(engine)¶ Enter an inverted section.
Parameters: engine – Engine which handles the commands (usually MainEngine) Example (executes an inverse QFT):
with Dagger(eng): QFT  qubits


class
projectq.meta.
DirtyQubitTag
¶ Dirty qubit meta tag

class
projectq.meta.
Loop
(engine, num)¶ Loop n times over an entire code block.
Example
with Loop(eng, 4): # [quantum gates to be executed 4 times]
Warning
If the code in the loop contains allocation of qubits, those qubits have to be deleted prior to exiting the ‘with Loop()’ context.
This code is NOT VALID:
with Loop(eng, 4): qb = eng.allocate_qubit() H  qb # qb is still available!!!
The correct way of handling qubit (de)allocation is as follows:
with Loop(eng, 4): qb = eng.allocate_qubit() ... del qb # sends deallocate gate

__init__
(engine, num)¶ Enter a looped section.
Parameters:  engine – Engine handling the commands (usually MainEngine)
 num (int) – Number of loop iterations
Example
with Loop(eng, 4): H  qb Rz(M_PI/3.)  qb
Raises: TypeError
– If number of iterations (num) is not an integerValueError
– If number of iterations (num) is not >= 0


projectq.meta.
Uncompute
(engine)¶ Uncompute automatically.
Example
with Compute(eng): do_something(qubits) action(qubits) Uncompute(eng) # runs inverse of the compute section

class
projectq.meta.
UncomputeTag
¶ Uncompute meta tag.

projectq.meta.
drop_engine_after
(prev_engine)¶ Removes an engine from the singlylinked list of engines.
Parameters: prev_engine (projectq.cengines.BasicEngine) – The engine just before the engine to drop. Returns: The dropped engine. Return type: Engine

projectq.meta.
get_control_count
(cmd)¶ Return the number of control qubits of the command object cmd

projectq.meta.
insert_engine
(prev_engine, engine_to_insert)¶ Inserts an engine into the singlylinked list of engines.
It also sets the correct main_engine for engine_to_insert.
Parameters:  prev_engine (projectq.cengines.BasicEngine) – The engine just before the insertion point.
 engine_to_insert (projectq.cengines.BasicEngine) – The engine to insert at the insertion point.
ops¶
The operations collection consists of various default gates and is a workinprogress, as users start to work with ProjectQ.
Module contents¶

class
projectq.ops.
AllocateDirtyQubitGate
¶ Dirty qubit allocation gate class

class
projectq.ops.
AllocateQubitGate
¶ Qubit allocation gate class

class
projectq.ops.
BasicGate
¶ Base class of all gates.

__init__
()¶ Initialize a basic gate.
Note
Set interchangeable qubit indices! (gate.interchangeable_qubit_indices)
As an example, consider
ExampleGate  (a,b,c,d,e)
where a and b are interchangeable. Then, call this function as follows:
self.set_interchangeable_qubit_indices([[0,1]])
As another example, consider
ExampleGate2  (a,b,c,d,e)
where a and b are interchangeable and, in addition, c, d, and e are interchangeable among themselves. Then, call this function as
self.set_interchangeable_qubit_indices([[0,1],[2,3,4]])

__or__
(qubits)¶ Operator overload which enables the syntax Gate  qubits.
Example
 Gate  qubit
 Gate  [qubit0, qubit1]
 Gate  qureg
 Gate  (qubit, )
 Gate  (qureg, qubit)
Parameters: qubits – a Qubit object, a list of Qubit objects, a Qureg object, or a tuple of Qubit or Qureg objects (can be mixed).

generate_command
(qubits)¶ Helper function to generate a command consisting of the gate and the qubits being acted upon.
Parameters: qubits – see BasicGate.make_tuple_of_qureg(qubits) Returns: A Command object containing the gate and the qubits.

get_inverse
()¶ Return the inverse gate.
Standard implementation of get_inverse:
Raises: NotInvertible
– inverse is not implemented

get_merged
(other)¶ Return this gate merged with another gate.
Standard implementation of get_merged:
Raises: NotMergeable
– merging is not implemented

static
make_tuple_of_qureg
(qubits)¶ Convert quantum input of “gate  quantum input” to internal formatting.
A Command object only accepts tuples of Quregs (list of Qubit objects) as qubits input parameter. However, with this function we allow the user to use a more flexible syntax:
 Gate  qubit
 Gate  [qubit0, qubit1]
 Gate  qureg
 Gate  (qubit, )
 Gate  (qureg, qubit)
where qubit is a Qubit object and qureg is a Qureg object. This function takes the right hand side of  and transforms it to the correct input parameter of a Command object which is:
 > Gate  ([qubit], )
 > Gate  ([qubit0, qubit1], )
 > Gate  (qureg, )
 > Gate  ([qubit], )
 > Gate  (qureg, [qubit])
Parameters: qubits – a Qubit object, a list of Qubit objects, a Qureg object, or a tuple of Qubit or Qureg objects (can be mixed). Returns: A tuple containing Qureg (or list of Qubits) objects. Return type: Canonical representation (tuple<qureg>)


class
projectq.ops.
BasicMathGate
(math_fun)¶ Base class for all math gates.
It allows efficient emulation by providing a mathematical representation which is given by the concrete gate which derives from this base class. The AddConstant gate, for example, registers a function of the form
def add(x): return (x+a,)
upon initialization. More generally, the function takes integers as parameters and returns a tuple / list of outputs, each entry corresponding to the function input. As an example, consider outofplace multiplication, which takes two input registers and adds the result into a third, i.e., (a,b,c) > (a,b,c+a*b). The corresponding function then is
def multiply(a,b,c) return (a,b,c+a*b)

__init__
(math_fun)¶ Initialize a BasicMathGate by providing the mathematical function that it implements.
Parameters: math_fun (function) – Function which takes as many int values as input, as the gate takes registers. For each of these values, it then returns the output (i.e., it returns a list/tuple of output values). Example
def add(a,b): return (a,a+b) BasicMathGate.__init__(self, add)
If the gate acts on, e.g., fixed point numbers, the number of bits per register is also required in order to describe the action of such a mathematical gate. For this reason, there is
BasicMathGate.get_math_function(qubits)
which can be overwritten by the gate deriving from BasicMathGate.
Example
def get_math_function(self, qubits): n = len(qubits[0]) scal = 2.**n def math_fun(a): return (int(scal * (math.sin(math.pi * a / scal))),) return math_fun

get_math_function
(qubits)¶ Return the math function which corresponds to the action of this math gate, given the input to the gate (a tuple of quantum registers).
Parameters: qubits (tuple<Qureg>) – Qubits to which the math gate is being applied. Returns: Python function describing the action of this gate. (See BasicMathGate.__init__ for an example). Return type: math_fun (function)


class
projectq.ops.
BasicPhaseGate
(angle)¶ Defines a base class of a phase gate.
A phase gate has a continuous parameter (the angle), labeled ‘angle’ / self._angle. Its inverse is the same gate with the negated argument. Phase gates of the same class can be merged by adding the angles. The continuous parameter is modulo 2 * pi, self._angle is in the interval [0, 2 * pi).

__init__
(angle)¶ Initialize a basic rotation gate.
Parameters: angle (float) – Angle of rotation (saved modulo 2 * pi)

get_inverse
()¶ Return the inverse of this rotation gate (negate the angle, return new object).

get_merged
(other)¶ Return self merged with another gate.
Default implementation handles rotation gate of the same type, where angles are simply added.
Parameters: other – Rotation gate of same type. Raises: NotMergeable
– For nonrotation gates or rotation gates of different type.Returns: New object representing the merged gates.

tex_str
()¶ Return the Latex string representation of a BasicRotationGate.
Returns the class name and the angle as a subscript, i.e.
[CLASSNAME]$_[ANGLE]$


class
projectq.ops.
BasicRotationGate
(angle)¶ Defines a base class of a rotation gate.
A rotation gate has a continuous parameter (the angle), labeled ‘angle’ / self._angle. Its inverse is the same gate with the negated argument. Rotation gates of the same class can be merged by adding the angles. The continuous parameter is modulo 4 * pi, self._angle is in the interval [0, 4 * pi).

__init__
(angle)¶ Initialize a basic rotation gate.
Parameters: angle (float) – Angle of rotation (saved modulo 4 * pi)

get_inverse
()¶ Return the inverse of this rotation gate (negate the angle, return new object).

get_merged
(other)¶ Return self merged with another gate.
Default implementation handles rotation gate of the same type, where angles are simply added.
Parameters: other – Rotation gate of same type. Raises: NotMergeable
– For nonrotation gates or rotation gates of different type.Returns: New object representing the merged gates.

tex_str
()¶ Return the Latex string representation of a BasicRotationGate.
Returns the class name and the angle as a subscript, i.e.
[CLASSNAME]$_[ANGLE]$


projectq.ops.
C
(gate, n=1)¶ Return ncontrolled version of the provided gate.
Parameters:  gate – Gate to turn into its controlled version
 n – Number of controls (default: 1)
Example
C(NOT)  (c, q) # equivalent to CNOT  (c, q)

class
projectq.ops.
ClassicalInstructionGate
¶ Classical instruction gate.
Base class for all gates which are not quantum gates in the typical sense, e.g., measurement, allocation/deallocation, ...

class
projectq.ops.
Command
(engine, gate, qubits, controls=(), tags=())¶ Class used as a container to store commands. If a gate is applied to qubits, then the gate and qubits are saved in a command object. Qubits are copied into WeakQubitRefs in order to allow early deallocation (would be kept alive otherwise). WeakQubitRef qubits don’t send deallocate gate when destructed.

gate
¶ The gate to execute

qubits
¶ Tuple of qubit lists (e.g. Quregs). Interchangeable qubits are stored in a unique order

control_qubits
¶ The Qureg of control qubits in a unique order

engine
¶ The engine (usually: MainEngine)
The list of tag objects associated with this command (e.g., ComputeTag, UncomputeTag, LoopTag, ...). tag objects need to support ==, != (__eq__ and __ne__) for comparison as used in e.g. TagRemover. New tags should always be added to the end of the list. This means that if there are e.g. two LoopTags in a command, tag[0] is from the inner scope while tag[1] is from the other scope as the other scope receives the command after the inner scope LoopEngine and hence adds its LoopTag to the end.

all_qubits
¶ A tuple of control_qubits + qubits

__init__
(engine, gate, qubits, controls=(), tags=())¶ Initialize a Command object.
Note
control qubits (Command.control_qubits) are stored as a list of qubits, and command tags (Command.tags) as a list of tag objects. All functions within this class also work if WeakQubitRefs are supplied instead of normal Qubit objects (see WeakQubitRef).
Parameters:  engine (projectq.cengines.BasicEngine) – engine which created the qubit (mostly the MainEngine)
 gate (projectq.ops.Gate) – Gate to be executed
 qubits (tuple[Qureg]) – Tuple of quantum registers (to which the gate is applied)
 controls (Qureglist[Qubit]) – Qubits that condition the command.
 tags (list[object]) – Tags associated with the command.

add_control_qubits
(qubits)¶ Add (additional) control qubits to this command object.
They are sorted to ensure a canonical order. Also Qubit objects are converted to WeakQubitRef objects to allow garbage collection and thus early deallocation of qubits.
Parameters: qubits (list of Qubit objects) – List of qubits which control this gate, i.e., the gate is only executed if all qubits are in state 1.

all_qubits
Get all qubits (gate and control qubits).
Returns a tuple T where T[0] is a quantum register (a list of WeakQubitRef objects) containing the control qubits and T[1:] contains the quantum registers to which the gate is applied.

control_qubits
Returns Qureg of control qubits.

engine
Return engine to which the qubits belong / on which the gates are executed.

get_inverse
()¶ Get the command object corresponding to the inverse of this command.
Inverts the gate (if possible) and creates a new command object from the result.
Raises: NotInvertible
– If the gate does not provide an inverse (see BasicGate.get_inverse)

get_merged
(other)¶ Merge this command with another one and return the merged command object.
Parameters: other – Other command to merge with this one (self) Raises: NotMergeable
– if the gates don’t supply a get_merged()function or can’t be merged for other reasons.

interchangeable_qubit_indices
¶ Return nested list of qubit indices which are interchangeable.
Certain qubits can be interchanged (e.g., the qubit order for a Swap gate). To ensure that only those are sorted when determining the ordering (see _order_qubits), self.interchangeable_qubit_indices is used. .. rubric:: Example
If we can interchange qubits 0,1 and qubits 3,4,5, then this function returns [[0,1],[3,4,5]]


class
projectq.ops.
ControlledGate
(gate, n=1)¶ Controlled version of a gate.
Note
Use the meta function
C()
to create a controlled gateA wrapper class which enables (multi) controlled gates. It overloads the __or__operator, using the first qubits provided as control qubits. The n controlqubits need to be the first n qubits. They can be in separate quregs.
Example
ControlledGate(gate, 2)  (qb0, qb2, qb3) # qb0 & qb2 are controls C(gate, 2)  (qb0, qb2, qb3) # This is much nicer. C(gate, 2)  ([qb0,qb2], qb3) # Is equivalent

__init__
(gate, n=1)¶ Initialize a ControlledGate object.
Parameters:  gate – Gate to wrap.
 n (int) – Number of control qubits.

__or__
(qubits)¶ Apply the controlled gate to qubits, using the first n qubits as controls.
 Note: The control qubits can be split across the first quregs.
 However, the nth control qubit needs to be the last qubit in a qureg. The following quregs belong to the gate.
Parameters: qubits (tuple of lists of Qubit objects) – qubits to which to apply the gate.

get_inverse
()¶ Return inverse of a controlled gate, which is the controlled inverse gate.


class
projectq.ops.
DaggeredGate
(gate)¶ Wrapper class allowing to execute the inverse of a gate, even when it does not define one.
If there is a replacement available, then there is also one for the inverse, namely the replacement function run in reverse, while inverting all gates. This class enables using this emulation automatically.
A DaggeredGate is returned automatically when employing the get_inverse function on a gate which does not provide a get_inverse() member function.
Example
with Dagger(eng): MySpecialGate  qubits
will create a DaggeredGate if MySpecialGate does not implement get_inverse. If there is a decomposition function available, an auto replacer engine can automatically replace the inverted gate by a call to the decomposition function inside a “with Dagger”statement.

__init__
(gate)¶ Initialize a DaggeredGate representing the inverse of the gate ‘gate’.
Parameters: gate – Any gate object of which to represent the inverse.

get_inverse
()¶ Return the inverse gate (the inverse of the inverse of a gate is the gate itself).

tex_str
()¶ Return the Latex string representation of a Daggered gate.


class
projectq.ops.
DeallocateQubitGate
¶ Qubit deallocation gate class

class
projectq.ops.
EntangleGate
¶ Entangle gate (Hadamard on first qubit, followed by CNOTs applied to all other qubits).

class
projectq.ops.
FastForwardingGate
¶ Base class for classical instruction gates which require a fastforward through compiler engines that cache / buffer gates. Examples include Measure and Deallocate, which both should be executed asap, such that Measurement results are available and resources are freed, respectively.
Note
The only requirement is that FlushGate commands run the entire circuit. FastForwardingGate objects can be used but the user cannot expect a measurement result to be available for all backends when calling only Measure. E.g., for the IBM Quantum Experience backend, sending the circuit for each Measuregate would be too inefficient, which is why a final
is required before the circuit gets sent through the API.

class
projectq.ops.
FlushGate
¶ Flush gate (denotes the end of the circuit).
Note
All compiler engines (cengines) which cache/buffer gates are obligated to flush and send all gates to the next compiler engine (followed by the flush command).
Note
This gate is sent when calling
eng.flush()
on the MainEngine eng.

class
projectq.ops.
HGate
¶ Hadamard gate class

class
projectq.ops.
MeasureGate
¶ Measurement gate class

exception
projectq.ops.
NotInvertible
¶ Exception thrown when trying to invert a gate which is not invertable (or where the inverse is not implemented (yet)).

exception
projectq.ops.
NotMergeable
¶ Exception thrown when trying to merge two gates which are not mergeable (or where it is not implemented (yet)).

class
projectq.ops.
Ph
(angle)¶ Phase gate (global phase)

class
projectq.ops.
QubitOperator
(term=None, coefficient=1.0)¶ A sum of terms acting on qubits, e.g., 0.5 * ‘X0 X5’ + 0.3 * ‘Z1 Z2’.
A term is an operator acting on n qubits and can be represented as:
coefficent * local_operator[0] x ... x local_operator[n1]
where x is the tensor product. A local operator is a Pauli operator (‘I’, ‘X’, ‘Y’, or ‘Z’) which acts on one qubit. In math notation a term is, for example, 0.5 * ‘X0 X5’, which means that a Pauli X operator acts on qubit 0 and 5, while the identity operator acts on all other qubits.
A QubitOperator represents a sum of terms acting on qubits and overloads operations for easy manipulation of these objects by the user.
Note for a QubitOperator to be a Hamiltonian which is a hermitian operator, the coefficients of all terms must be real.
hamiltonian = 0.5 * QubitOperator('X0 X5') + 0.3 * QubitOperator('Z0')

terms
¶ dict – key: A term represented by a tuple containing all nontrivial local Pauli operators (‘X’, ‘Y’, or ‘Z’). A nontrivial local Pauli operator is specified by a tuple with the first element being an integer indicating the qubit on which a nontrivial local operator acts and the second element being a string, either ‘X’, ‘Y’, or ‘Z’, indicating which nontrivial Pauli operator acts on that qubit. Examples: ((1, ‘X’),) or ((1, ‘X’), (4,’Z’)) or the identity (). The tuples representing the nontrivial local terms are sorted according to the qubit number they act on, starting from 0. value: Coefficient of this term as a (complex) float

__init__
(term=None, coefficient=1.0)¶ Inits a QubitOperator.
The init function only allows to initialize one term. Additional terms have to be added using += (which is fast) or using + of two QubitOperator objects:
Example
ham = ((QubitOperator('X0 Y3', 0.5) + 0.6 * QubitOperator('X0 Y3'))) # Equivalently ham2 = QubitOperator('X0 Y3', 0.5) ham2 += 0.6 * QubitOperator('X0 Y3')
Note
Adding terms to QubitOperator is faster using += (as this is done by inplace addition). Specifying the coefficient in the __init__ is faster than by multiplying a QubitOperator with a scalar as calls an outofplace multiplication.
Parameters:  coefficient (complex float, optional) – The coefficient of the first term of this QubitOperator. Default is 1.0.
 term (optional, empy tuple, a tuple of tuples, or a string) –
 Default is None which means there are no terms in the QubitOperator hence it is the “zero” Operator
 An empty tuple means there are no nontrivial Pauli operators acting on the qubits hence only identities with a coefficient (which by default is 1.0).
 A sorted tuple of tuples. The first element of each tuple is an integer indicating the qubit on which a nontrivial local operator acts, starting from zero. The second element of each tuple is a string, either ‘X’, ‘Y’ or ‘Z’, indicating which local operator acts on that qubit.
 A string of the form ‘X0 Z2 Y5’, indicating an X on qubit 0, Z on qubit 2, and Y on qubit 5. The string should be sorted by the qubit number. ‘’ is the identity.
Raises: QubitOperatorError
– Invalid operators provided to QubitOperator.

compress
(abs_tol=1e12)¶ Eliminates all terms with coefficients close to zero and removes imaginary parts of coefficients that are close to zero.
Parameters: abs_tol (float) – Absolute tolerance, must be at least 0.0

isclose
(other, rel_tol=1e12, abs_tol=1e12)¶ Returns True if other (QubitOperator) is close to self.
Comparison is done for each term individually. Return True if the difference between each term in self and other is less than the relative tolerance w.r.t. either other or self (symmetric test) or if the difference is less than the absolute tolerance.
Parameters:  other (QubitOperator) – QubitOperator to compare against.
 rel_tol (float) – Relative tolerance, must be greater than 0.0
 abs_tol (float) – Absolute tolerance, must be at least 0.0


class
projectq.ops.
R
(angle)¶ Phaseshift gate (equivalent to Rz up to a global phase)

class
projectq.ops.
Rx
(angle)¶ RotationX gate class

class
projectq.ops.
Ry
(angle)¶ RotationX gate class

class
projectq.ops.
Rz
(angle)¶ RotationZ gate class

class
projectq.ops.
SGate
¶ S gate class

class
projectq.ops.
SelfInverseGate
¶ Selfinverse basic gate class.
Automatic implementation of the get_inversemember function for self inverse gates.
Example
# get_inverse(H) == H, it is a selfinverse gate: get_inverse(H)  qubit

class
projectq.ops.
SwapGate
¶ Swap gate class (swaps 2 qubits)

class
projectq.ops.
TGate
¶ T gate class

class
projectq.ops.
Tensor
(gate)¶ Wrapper class allowing to apply a (singlequbit) gate to every qubit in a quantum register. Allowed syntax is to supply either a qureg or a tuple which contains only one qureg.
Example
Tensor(H)  x # applies H to every qubit in the list of qubits x Tensor(H)  (x,) # alternative to be consistent with other syntax

__init__
(gate)¶ Initialize a Tensor object for the gate.

__or__
(qubits)¶ Applies the gate to every qubit in the quantum register qubits.

get_inverse
()¶ Return the inverse of this tensored gate (which is the tensored inverse of the gate).


class
projectq.ops.
TimeEvolution
(time, hamiltonian)¶ Gate for time evolution under a Hamiltonian (QubitOperator object).
This gate is the unitary time evolution propagator: exp(i * H * t), where H is the Hamiltonian of the system and t is the time. Note that i factor is stored implicitely.
Example
wavefunction = eng.allocate_qureg(5) hamiltonian = 0.5 * QubitOperator("X0 Z1 Y5") # Apply exp(i * H * t) to the wavefunction: TimeEvolution(time=2.0, hamiltonian=hamiltonian)  wavefunction

time
¶ float, int – time t

hamiltonian
¶ QubitOperator – hamiltonaian H

__init__
(time, hamiltonian)¶ Initialize time evolution gate.
Note
The hamiltonian must be hermitian and therefore only terms with real coefficients are allowed. Coefficients are internally converted to float.
Parameters:  time (float, or int) – time to evolve under (can be negative).
 hamiltonian (QubitOperator) – hamiltonian to evolve under.
Raises: TypeError
– If time is not a numeric type and hamiltonian is not a QubitOperator.NotHermitianOperatorError
– If the input hamiltonian is not hermitian (only real coefficients).

__or__
(qubits)¶ Operator overload which enables the following syntax:
TimeEvolution(...)  qureg TimeEvolution(...)  (qureg,) TimeEvolution(...)  qubit TimeEvolution(...)  (qubit,)
Unlike other gates, this gate is only allowed to be applied to one quantum register or one qubit.
Example:
wavefunction = eng.allocate_qureg(5) hamiltonian = QubitOperator("X1 Y3", 0.5) TimeEvolution(time=2.0, hamiltonian=hamiltonian)  wavefunction
While in the above example the TimeEvolution gate is applied to 5 qubits, the hamiltonian of this TimeEvolution gate acts only nontrivially on the two qubits wavefunction[1] and wavefunction[3]. Therefore, the operator will rescale the indices in the hamiltonian and sends the equivalent of the following new gate to the MainEngine:
h = QubitOperator("X0 Y1", 0.5) TimeEvolution(2.0, h)  [wavefunction[1], wavefunction[3]]
which is only a two qubit gate.
Parameters: qubits – one Qubit object, one list of Qubit objects, one Qureg object, or a tuple of the former three cases.

get_inverse
()¶ Return the inverse gate.

get_merged
(other)¶ Return self merged with another TimeEvolution gate if possible.
 Two TimeEvolution gates are merged if:
 both have the same terms
 the proportionality factor for each of the terms must have relative error <= 1e9 compared to the proportionality factors of the other terms.
Note
While one could merge gates for which both hamiltonians commute, we are not doing this as in general the resulting gate would have to be decomposed again.
Note
We are not comparing if terms are proportional to each other with an absolute tolerance. It is up to the user to remove terms close to zero because we cannot choose a suitable absolute error which works for everyone. Use, e.g., a decomposition rule for that.
Parameters: other – TimeEvolution gate Raises: NotMergeable
– If the other gate is not a TimeEvolution gate or hamiltonians are not suitable for merging.Returns: New TimeEvolution gate equivalent to the two merged gates.


class
projectq.ops.
XGate
¶ PauliX gate class

class
projectq.ops.
YGate
¶ PauliY gate class

class
projectq.ops.
ZGate
¶ PauliZ gate class

projectq.ops.
apply_command
(cmd)¶ Apply a command.
Extracts the qubitsowning (target) engine from the Command object and sends the Command to it.
Parameters: cmd (Command) – Command to apply

projectq.ops.
get_inverse
(gate)¶ Return the inverse of a gate.
Tries to call gate.get_inverse and, upon failure, creates a DaggeredGate instead.
Parameters: gate – Gate of which to get the inverse Example
get_inverse(H) # returns a Hadamard gate (HGate object)
setups¶
The setups package contains a collection of setups which can be loaded using an import statement. Each setup then loads its own set of decomposition rules and default compiler engines.
Subpackages¶
decompositions¶
The decomposition package is a collection of gate decomposition / replacement rules which can be used by, e.g., the AutoReplacer engine.
Submodules¶
projectq.setups.decompositions.crz2cxandrz module¶
Registers a decomposition for controlled zrotation gates.
It uses 2 zrotations and 2 C^n NOT gates to achieve this gate.
projectq.setups.decompositions.entangle module¶
Registers a decomposition for the Entangle gate.
Applies a Hadamard gate to the first qubit and then, conditioned on this first qubit, CNOT gates to all others.
projectq.setups.decompositions.globalphase module¶
Registers a decomposition rule for global phases.
Deletes global phase gates (which can be ignored).
projectq.setups.decompositions.ph2r module¶
Registers a decomposition for the controlled global phase gate.
Turns the controlled global phase gate into a (controlled) phaseshift gate. Each time this rule is applied, one control can be shaved off.
projectq.setups.decompositions.qft2crandhadamard module¶
Registers a decomposition rule for the quantum Fourier transform.
Decomposes the QFT gate into Hadamard and controlled phaseshift gates (R).
Warning
The final Swaps are not included, as those are simply a reindexing of quantum registers.
projectq.setups.decompositions.r2rzandph module¶
Registers a decomposition rule for the phaseshift gate.
Decomposes the (controlled) phaseshift gate using zrotation and a global phase gate.
projectq.setups.decompositions.swap2cnot module¶
Registers a decomposition to achieve a Swap gate.
Decomposes a Swap gate using 3 CNOT gates, where the one in the middle features as many control qubits as the Swap gate has control qubits.
projectq.setups.decompositions.toffoli2cnotandtgate module¶
Registers a decomposition rule for the Toffoli gate.
Decomposes the Toffoli gate using Hadamard, T, Tdag, and CNOT gates.
Module contents¶
ibm¶
The IBM Setup imports the default IBM decomposition rules, compiler engines (featuring a CNOTMapper), and the IBM backend (IBMBackend).
Module contents¶
Registers a variety of useful gate decompositions, specifically for the IBM quantum experience backend. Among others it includes:
 Controlled zrotations –> Controlled NOTs and singlequbit rotations
 Toffoli gate –> CNOT and singlequbit gates
 mControlled global phases –> (m1)controlled phaseshifts
 Global phases –> ignore
 (controlled) Swap gates –> CNOTs and Toffolis

class
projectq.setups.ibm.
AutoReplacer
(decompositionRuleSet, decomposition_chooser=<function AutoReplacer.<lambda>>)¶ The AutoReplacer is a compiler engine which uses engine.is_available in order to determine which commands need to be replaced/decomposed/compiled further. The loaded setup is used to find decomposition rules appropriate for each command (e.g., setups.default).

__init__
(decompositionRuleSet, decomposition_chooser=<function AutoReplacer.<lambda>>)¶ Initialize an AutoReplacer.
Parameters: decomposition_chooser (function) – A function which, given the Command to decompose and a list of potential Decomposition objects, determines (and then returns) the ‘best’ decomposition. The default decomposition chooser simply returns the first list element, i.e., calling
repl = AutoReplacer()
Amounts to
def decomposition_chooser(cmd, decomp_list): return decomp_list[0] repl = AutoReplacer(decomposition_chooser)

receive
(command_list)¶ Receive a list of commands from the previous compiler engine and, if necessary, replace/decompose the gates according to the decomposition rules in the loaded setup.
Parameters: command_list (list<Command>) – List of commands to handle.


class
projectq.setups.ibm.
DecompositionRuleSet
(rules=None, modules=None)¶ A collection of indexed decomposition rules.

__init__
(rules=None, modules=None)¶ Parameters:  list[DecompositionRule] (rules) – Initial decomposition rules.
 modules (iterable[ModuleWithDecompositionRuleSet]) – A list of things with an “all_defined_decomposition_rules” property containing decomposition rules to add to the rule set.

add_decomposition_rule
(rule)¶ Add a decomposition rule to the rule set.
Parameters: rule (DecompositionRuleGate) – The decomposition rule to add.


class
projectq.setups.ibm.
IBMCNOTMapper
¶ CNOT mapper for the IBM backend.
Maps a given circuit to the IBM Quantum Experience chip. If necessary, it will flip around the CNOT gate by first applying Hadamard gates to both qubits, then CNOT with swapped control and target qubit, and finally Hadamard gates to both qubits. Furthermore, it adds QubitPlacementTags to Allocate gate commands.
Note
The mapper has to be run once on the entire circuit.
Warning
If the provided circuit cannot be mapped to the hardware layout without performing Swaps, the mapping procedure raises an Exception.

__init__
()¶ Initialize an IBM CNOT Mapper compiler engine.
Resets the mapping.

is_available
(cmd)¶ Check if the IBM backend can perform the Command cmd and return True if so.
Parameters: cmd (Command) – The command to check

receive
(command_list)¶ Receives a command list and, for each command, stores it until completion.
Parameters: command_list (list of Command objects) – list of commands to receive. Raises: Exception
– If mapping the CNOT gates to 1 qubit would require Swaps. The current version only supports remapping of CNOT gates without performing any Swaps due to the large costs associated with Swapping given the CNOT constraints.


class
projectq.setups.ibm.
LocalOptimizer
(m=5)¶ LocalOptimizer is a compiler engine which optimizes locally (merging rotations, cancelling gates with their inverse) in a local window of user defined size.
It stores all commands in a list of lists, where each qubit has its own gate pipeline. After adding a gate, it tries to merge / cancel successive gates using the get_merged and get_inverse functions of the gate (if available). For examples, see BasicRotationGate. Once a list corresponding to a qubit contains >=m gates, the pipeline is sent on to the next engine.

__init__
(m=5)¶ Initialize a LocalOptimizer object.
Parameters: m (int) – Number of gates to cache per qubit, before sending on the first gate.

receive
(command_list)¶ Receive commands from the previous engine and cache them. If a flush gate arrives, the entire buffer is sent on.


class
projectq.setups.ibm.
TagRemover
(tags=[<class 'projectq.meta._compute.ComputeTag'>, <class 'projectq.meta._compute.UncomputeTag'>])¶ TagRemover is a compiler engine which removes temporary command tags (see the tag classes such as LoopTag in projectq.meta._loop).
Removing tags is important (after having handled them if necessary) in order to enable optimizations across metafunction boundaries (compute/ action/uncompute or loops after unrolling)

__init__
(tags=[<class 'projectq.meta._compute.ComputeTag'>, <class 'projectq.meta._compute.UncomputeTag'>])¶ Construct the TagRemover.
Parameters: tags – A list of meta tag classes (e.g., [ComputeTag, UncomputeTag]) denoting the tags to remove

receive
(command_list)¶ Receive a list of commands from the previous engine, remove all tags which are an instance of at least one of the meta tags provided in the constructor, and then send them on to the next compiler engine.
Parameters: command_list (list<Command>) – List of commands to receive and then (after removing tags) send on.

Submodules¶
default module¶
The default module features a standard set of decomposition rules, compiler engines, and the simulator backend.
Registers a variety of useful gate decompositions. Among others it includes
 Controlled zrotations –> Controlled NOTs and singlequbit rotations
 Toffoli gate –> CNOT and singlequbit gates
 mControlled global phases –> (m1)controlled phaseshifts
 Global phases –> ignore
 (controlled) Swap gates –> CNOTs and Toffolis
Module contents¶
types¶
The types package contains quantum types such as Qubit, Qureg, and WeakQubitRef. With further development of the math library, also quantum integers, quantum fixed point numbers etc. will be added.
Module contents¶

class
projectq.types.
BasicQubit
(engine, idx)¶ BasicQubit objects represent qubits.
They have an id and a reference to the owning engine.

__bool__
()¶ Access the result of a previous measurement and return False / True (0 / 1)

__eq__
(other)¶ Compare with other qubit (Returns True if equal id and engine).
Parameters: other (BasicQubit) – BasicQubit to which to compare this one

__hash__
()¶ Return the hash of this qubit.
Hash definition because of custom __eq__. Enables storing a qubit in, e.g., a set.

__init__
(engine, idx)¶ Initialize a BasicQubit object.
Parameters:  engine – Owning engine / engine that created the qubit
 idx – Unique index of the qubit referenced by this qubit

__int__
()¶ Access the result of a previous measurement and return as integer (0 / 1).

__nonzero__
()¶ Access the result of a previous measurement for Python 2.7.

__str__
()¶ Return string representation of this qubit.

__weakref__
¶ list of weak references to the object (if defined)


class
projectq.types.
Qubit
(engine, idx)¶ Qubit class.
Represents a (logicallevel) qubit with a unique index provided by the MainEngine. Once the qubit goes out of scope (and is garbagecollected), it deallocates itself automatically, allowing automatic resource management.
Thus the qubit is not copyable; only returns a reference to the same object.

__copy__
()¶ Noncopyable (returns reference to self).
Note
To prevent problems with automatic deallocation, qubits are not copyable!

__deepcopy__
(memo)¶ Nondeepcopyable (returns reference to self).
Note
To prevent problems with automatic deallocation, qubits are not deepcopyable!

__del__
()¶ Destroy the qubit and deallocate it (automatically).


class
projectq.types.
Qureg
¶ Quantum register class.
Simplifies accessing measured values for singlequbit registers (no [] access necessary) and enables prettyprinting of general quantum registers (call Qureg.__str__(qureg)).

__bool__
()¶ Return measured value if Qureg consists of 1 qubit only.
Raises:  Exception if more than 1 qubit resides in this register (then you
 need to specify which value to get using qureg[???])

__int__
()¶ Return measured value if Qureg consists of 1 qubit only.
Raises:  Exception if more than 1 qubit resides in this register (then you
 need to specify which value to get using qureg[???])

__nonzero__
()¶ Return measured value if Qureg consists of 1 qubit only for Python 2.7.
Raises:  Exception if more than 1 qubit resides in this register (then you
 need to specify which value to get using qureg[???])

__str__
()¶ Get string representation of a quantum register.

__weakref__
¶ list of weak references to the object (if defined)

engine
¶ Return owning engine.


class
projectq.types.
WeakQubitRef
(engine, idx)¶ WeakQubitRef objects are used inside the Command object.
Qubits feature automatic deallocation when destroyed. WeakQubitRefs, on the other hand, do not share this feature, allowing to copy them and pass them along the compiler pipeline, while the actual qubit objects may be garbagecollected (and, thus, cleaned up early). Otherwise there is no difference between a WeakQubitRef and a Qubit object.