Skip to content

Commit 1513fb5

Browse files
ProjectQ v0.4.2
2 parents 24d0cbf + f7bef17 commit 1513fb5

26 files changed

+677
-164
lines changed

docs/projectq.ops.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ The operations collection consists of various default gates and is a work-in-pro
66
.. autosummary::
77

88
projectq.ops.BasicGate
9+
projectq.ops.MatrixGate
910
projectq.ops.SelfInverseGate
1011
projectq.ops.BasicRotationGate
1112
projectq.ops.BasicPhaseGate
@@ -52,6 +53,7 @@ The operations collection consists of various default gates and is a work-in-pro
5253
projectq.ops.UniformlyControlledRy
5354
projectq.ops.UniformlyControlledRz
5455
projectq.ops.StatePreparation
56+
projectq.ops.FlipBits
5557

5658

5759
Module contents

docs/projectq.setups.decompositions.rst

Lines changed: 49 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,23 @@ The decomposition package is a collection of gate decomposition / replacement ru
99
projectq.setups.decompositions.arb1qubit2rzandry
1010
projectq.setups.decompositions.barrier
1111
projectq.setups.decompositions.carb1qubit2cnotrzandry
12+
projectq.setups.decompositions.cnot2cz
1213
projectq.setups.decompositions.cnu2toffoliandcu
1314
projectq.setups.decompositions.crz2cxandrz
1415
projectq.setups.decompositions.entangle
1516
projectq.setups.decompositions.globalphase
1617
projectq.setups.decompositions.ph2r
1718
projectq.setups.decompositions.qft2crandhadamard
19+
projectq.setups.decompositions.qubitop2onequbit
1820
projectq.setups.decompositions.r2rzandph
1921
projectq.setups.decompositions.rx2rz
2022
projectq.setups.decompositions.ry2rz
23+
projectq.setups.decompositions.sqrtswap2cnot
24+
projectq.setups.decompositions.stateprep2cnot
2125
projectq.setups.decompositions.swap2cnot
2226
projectq.setups.decompositions.time_evolution
2327
projectq.setups.decompositions.toffoli2cnotandtgate
28+
projectq.setups.decompositions.uniformlycontrolledr2cnot
2429

2530

2631
Submodules
@@ -32,7 +37,7 @@ projectq.setups.decompositions.arb1qubit2rzandry module
3237
.. automodule:: projectq.setups.decompositions.arb1qubit2rzandry
3338
:members:
3439
:undoc-members:
35-
40+
3641

3742
projectq.setups.decompositions.barrier module
3843
---------------------------------------------
@@ -48,6 +53,13 @@ projectq.setups.decompositions.carb1qubit2cnotrzandry module
4853
:members:
4954
:undoc-members:
5055

56+
projectq.setups.decompositions.cnot2cz module
57+
---------------------------------------------
58+
59+
.. automodule:: projectq.setups.decompositions.cnot2cz
60+
:members:
61+
:undoc-members:
62+
5163
projectq.setups.decompositions.cnu2toffoliandcu module
5264
------------------------------------------------------
5365

@@ -61,35 +73,42 @@ projectq.setups.decompositions.crz2cxandrz module
6173
.. automodule:: projectq.setups.decompositions.crz2cxandrz
6274
:members:
6375
:undoc-members:
64-
76+
6577
projectq.setups.decompositions.entangle module
6678
----------------------------------------------
6779

6880
.. automodule:: projectq.setups.decompositions.entangle
6981
:members:
7082
:undoc-members:
71-
83+
7284
projectq.setups.decompositions.globalphase module
7385
-------------------------------------------------
7486

7587
.. automodule:: projectq.setups.decompositions.globalphase
7688
:members:
7789
:undoc-members:
78-
90+
7991
projectq.setups.decompositions.ph2r module
8092
------------------------------------------
8193

8294
.. automodule:: projectq.setups.decompositions.ph2r
8395
:members:
8496
:undoc-members:
85-
97+
8698
projectq.setups.decompositions.qft2crandhadamard module
8799
-------------------------------------------------------
88100

89101
.. automodule:: projectq.setups.decompositions.qft2crandhadamard
90102
:members:
91103
:undoc-members:
92-
104+
105+
projectq.setups.decompositions.qubitop2onequbit module
106+
-------------------------------------------------------
107+
108+
.. automodule:: projectq.setups.decompositions.qubitop2onequbit
109+
:members:
110+
:undoc-members:
111+
93112
projectq.setups.decompositions.r2rzandph module
94113
-----------------------------------------------
95114

@@ -110,7 +129,21 @@ projectq.setups.decompositions.ry2rz module
110129
.. automodule:: projectq.setups.decompositions.ry2rz
111130
:members:
112131
:undoc-members:
113-
132+
133+
projectq.setups.decompositions.sqrtswap2cnot module
134+
---------------------------------------------------
135+
136+
.. automodule:: projectq.setups.decompositions.sqrtswap2cnot
137+
:members:
138+
:undoc-members:
139+
140+
projectq.setups.decompositions.stateprep2cnot module
141+
----------------------------------------------------
142+
143+
.. automodule:: projectq.setups.decompositions.stateprep2cnot
144+
:members:
145+
:undoc-members:
146+
114147
projectq.setups.decompositions.swap2cnot module
115148
-----------------------------------------------
116149

@@ -124,14 +157,21 @@ projectq.setups.decompositions.time_evolution module
124157
.. automodule:: projectq.setups.decompositions.time_evolution
125158
:members:
126159
:undoc-members:
127-
160+
128161
projectq.setups.decompositions.toffoli2cnotandtgate module
129162
----------------------------------------------------------
130163

131164
.. automodule:: projectq.setups.decompositions.toffoli2cnotandtgate
132165
:members:
133166
:undoc-members:
134-
167+
168+
projectq.setups.decompositions.uniformlycontrolledr2cnot module
169+
---------------------------------------------------------------
170+
171+
.. automodule:: projectq.setups.decompositions.uniformlycontrolledr2cnot
172+
:members:
173+
:undoc-members:
174+
135175

136176
Module contents
137177
---------------

examples/variational_quantum_eigensolver.ipynb

Lines changed: 197 additions & 0 deletions
Large diffs are not rendered by default.

projectq/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,4 @@
1313
# limitations under the License.
1414

1515
"""Define version number here and read it from setup.py automatically"""
16-
__version__ = "0.4.1"
16+
__version__ = "0.4.2"

projectq/backends/_circuits/_to_latex.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ def _footer(settings):
209209
Returns:
210210
tex_footer_str (string): Latex document footer.
211211
"""
212-
return "\n\n\end{tikzpicture}\n\end{document}"
212+
return "\n\n\\end{tikzpicture}\n\\end{document}"
213213

214214

215215
class _Circ2Tikz(object):
@@ -329,7 +329,7 @@ def to_tikz(self, line, circuit, end=None):
329329
self.is_quantum[l] = False
330330
elif gate == Allocate:
331331
# draw 'begin line'
332-
add_str = "\n\\node[none] ({}) at ({},-{}) {{$\Ket{{0}}{}$}};"
332+
add_str = "\n\\node[none] ({}) at ({},-{}) {{$\\Ket{{0}}{}$}};"
333333
id_str = ""
334334
if self.settings['gates']['AllocateQubitGate']['draw_id']:
335335
id_str = "^{{\\textcolor{{red}}{{{}}}}}".format(cmds[i].id)
@@ -433,7 +433,7 @@ def _sqrtswap_gate(self, lines, ctrl_lines, daggered):
433433
gate_str += ("\n\\node[xstyle] ({op}) at ({pos},-{line})\
434434
{{\\scriptsize $\\frac{{1}}{{2}}{dagger}$}};"
435435
).format(op=op_mid, line=midpoint, pos=pos,
436-
dagger='^{{\dagger}}' if daggered else '')
436+
dagger='^{{\\dagger}}' if daggered else '')
437437

438438
# add two vertical lines to connect circled 1/2
439439
gate_str += "\n\\draw ({}) edge[edgestyle] ({});".format(

projectq/backends/_circuits/_to_latex_test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ def test_body():
174174
# CZ is two phases plus 2 from CNOTs + 2 from cswap + 2 from csqrtswap
175175
assert code.count("phase") == 8
176176
assert code.count("{{{}}}".format(str(H))) == 2 # 2 hadamard gates
177-
assert code.count("{$\Ket{0}") == 3 # 3 qubits allocated
177+
assert code.count("{$\\Ket{0}") == 3 # 3 qubits allocated
178178
# 1 cnot, 1 not gate, 3 SqrtSwap, 1 inv(SqrtSwap)
179179
assert code.count("xstyle") == 7
180180
assert code.count("measure") == 1 # 1 measurement

projectq/backends/_ibm/_ibm.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ class IBMBackend(BasicEngine):
4646
"""
4747
def __init__(self, use_hardware=False, num_runs=1024, verbose=False,
4848
user=None, password=None, device='ibmqx4',
49+
num_retries=3000, interval=1,
4950
retrieve_execution=None):
5051
"""
5152
Initialize the Backend object.
@@ -62,6 +63,11 @@ def __init__(self, use_hardware=False, num_runs=1024, verbose=False,
6263
password (string): IBM Quantum Experience password
6364
device (string): Device to use ('ibmqx4', or 'ibmqx5')
6465
if use_hardware is set to True. Default is ibmqx4.
66+
num_retries (int): Number of times to retry to obtain
67+
results from the IBM API. (default is 3000)
68+
interval (float, int): Number of seconds between successive
69+
attempts to obtain results from the IBM API.
70+
(default is 1)
6571
retrieve_execution (int): Job ID to retrieve instead of re-
6672
running the circuit (e.g., if previous run timed out).
6773
"""
@@ -75,6 +81,8 @@ def __init__(self, use_hardware=False, num_runs=1024, verbose=False,
7581
self._verbose = verbose
7682
self._user = user
7783
self._password = password
84+
self._num_retries = num_retries
85+
self._interval = interval
7886
self._probabilities = dict()
7987
self.qasm = ""
8088
self._measured_ids = []
@@ -256,11 +264,17 @@ def _run(self):
256264
if self._retrieve_execution is None:
257265
res = send(info, device=self.device,
258266
user=self._user, password=self._password,
259-
shots=self._num_runs, verbose=self._verbose)
267+
shots=self._num_runs,
268+
num_retries=self._num_retries,
269+
interval=self._interval,
270+
verbose=self._verbose)
260271
else:
261272
res = retrieve(device=self.device, user=self._user,
262273
password=self._password,
263-
jobid=self._retrieve_execution)
274+
jobid=self._retrieve_execution,
275+
num_retries=self._num_retries,
276+
interval=self._interval,
277+
verbose=self._verbose)
264278

265279
counts = res['data']['counts']
266280
# Determine random outcome

projectq/backends/_ibm/_ibm_http_client.py

Lines changed: 47 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import requests
1818
import getpass
1919
import json
20+
import signal
2021
import sys
2122
import time
2223
from requests.compat import urljoin
@@ -35,7 +36,8 @@ def is_online(device):
3536
return r.json()['state']
3637

3738

38-
def retrieve(device, user, password, jobid):
39+
def retrieve(device, user, password, jobid, num_retries=3000,
40+
interval=1, verbose=False):
3941
"""
4042
Retrieves a previously run job by its ID.
4143
@@ -46,12 +48,13 @@ def retrieve(device, user, password, jobid):
4648
jobid (str): Id of the job to retrieve
4749
"""
4850
user_id, access_token = _authenticate(user, password)
49-
res = _get_result(device, jobid, access_token)
51+
res = _get_result(device, jobid, access_token, num_retries=num_retries,
52+
interval=interval, verbose=verbose)
5053
return res
5154

5255

5356
def send(info, device='sim_trivial_2', user=None, password=None,
54-
shots=1, verbose=False):
57+
shots=1, num_retries=3000, interval=1, verbose=False):
5558
"""
5659
Sends QASM through the IBM API and runs the quantum circuit.
5760
@@ -84,7 +87,9 @@ def send(info, device='sim_trivial_2', user=None, password=None,
8487
execution_id = _run(info, device, user_id, access_token, shots)
8588
if verbose:
8689
print("- Waiting for results...")
87-
res = _get_result(device, execution_id, access_token)
90+
res = _get_result(device, execution_id, access_token,
91+
num_retries=num_retries,
92+
interval=interval, verbose=verbose)
8893
if verbose:
8994
print("- Done.")
9095
return res
@@ -143,32 +148,47 @@ def _run(qasm, device, user_id, access_token, shots):
143148

144149

145150
def _get_result(device, execution_id, access_token, num_retries=3000,
146-
interval=1):
151+
interval=1, verbose=False):
147152
suffix = 'Jobs/{execution_id}'.format(execution_id=execution_id)
148153
status_url = urljoin(_api_url, 'Backends/{}/queue/status'.format(device))
149154

150-
print("Waiting for results. [Job ID: {}]".format(execution_id))
151-
152-
for retries in range(num_retries):
153-
r = requests.get(urljoin(_api_url, suffix),
154-
params={"access_token": access_token})
155-
r.raise_for_status()
156-
157-
r_json = r.json()
158-
if 'qasms' in r_json:
159-
qasm = r_json['qasms'][0]
160-
if 'result' in qasm:
161-
return qasm['result']
162-
time.sleep(interval)
163-
if device in ['ibmqx4', 'ibmqx5'] and retries % 60 == 0:
164-
r = requests.get(status_url)
155+
if verbose:
156+
print("Waiting for results. [Job ID: {}]".format(execution_id))
157+
158+
original_sigint_handler = signal.getsignal(signal.SIGINT)
159+
160+
def _handle_sigint_during_get_result(*_):
161+
raise Exception("Interrupted. The ID of your submitted job is {}."
162+
.format(execution_id))
163+
164+
try:
165+
signal.signal(signal.SIGINT, _handle_sigint_during_get_result)
166+
167+
for retries in range(num_retries):
168+
r = requests.get(urljoin(_api_url, suffix),
169+
params={"access_token": access_token})
170+
r.raise_for_status()
165171
r_json = r.json()
166-
if 'state' in r_json and not r_json['state']:
167-
raise DeviceOfflineError("Device went offline. The ID of your "
168-
"submitted job is {}."
169-
.format(execution_id))
170-
if 'lengthQueue' in r_json:
171-
print("Currently there are {} jobs queued for execution on {}."
172-
.format(r_json['lengthQueue'], device))
172+
if 'qasms' in r_json:
173+
qasm = r_json['qasms'][0]
174+
if 'result' in qasm and qasm['result'] is not None:
175+
return qasm['result']
176+
time.sleep(interval)
177+
if device in ['ibmqx4', 'ibmqx5'] and retries % 60 == 0:
178+
r = requests.get(status_url)
179+
r_json = r.json()
180+
if 'state' in r_json and not r_json['state']:
181+
raise DeviceOfflineError("Device went offline. The ID of "
182+
"your submitted job is {}."
183+
.format(execution_id))
184+
if verbose and 'lengthQueue' in r_json:
185+
print("Currently there are {} jobs queued for execution "
186+
"on {}."
187+
.format(r_json['lengthQueue'], device))
188+
189+
finally:
190+
if original_sigint_handler is not None:
191+
signal.signal(signal.SIGINT, original_sigint_handler)
192+
173193
raise Exception("Timeout. The ID of your submitted job is {}."
174194
.format(execution_id))

0 commit comments

Comments
 (0)