Skip to content

Commit 3697c29

Browse files
author
Axel Dahlberg
authored
Merge pull request #255 from SoftwareQuTech/master
Update Develop after hot-fix
2 parents a992b38 + d951718 commit 3697c29

File tree

7 files changed

+99
-10
lines changed

7 files changed

+99
-10
lines changed

.bumpversion.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[bumpversion]
2-
current_version = 3.0.12
2+
current_version = 3.0.13
33
commit = True
44
tag = False
55

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ For more details refer to the [documentation](https://softwarequtech.github.io/S
66
Upcoming
77
--------
88

9+
2020-02-23 (v3.0.13)
10+
-------------------
11+
- Fixed bug in the Boolean Gaussian elimination in stabilizer formalism.
12+
913
2020-01-27 (v3.0.12)
1014
-------------------
1115
- Boolean Gaussian elimination in stabilizer formalism is now even faster.

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[![Build Status](https://travis-ci.com/SoftwareQuTech/SimulaQron.svg?branch=Develop)](https://travis-ci.com/SoftwareQuTech/SimulaQron)
22

3-
SimulaQron - simple quantum network simulator (3.0.12)
3+
SimulaQron - simple quantum network simulator (3.0.13)
44
=====================================================
55

66
The purpose of this simulator of quantum network nodes is to allow you to develop new applications for

docs/Makefile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,10 @@ dummy:
251251
python-deps:
252252
@cat requirements.txt | xargs -n 1 -L 1 pip3 install
253253

254-
build: python-deps html
254+
_add_jekyll:
255+
touch build/.nojekyll
256+
257+
build: python-deps html _add_jekyll
255258

256259
open:
257260
@echo "test"

simulaqron/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
from simulaqron.tests_run import main as tests
22

33
__all__ = ['tests']
4-
__version__ = '3.0.12'
4+
__version__ = '3.0.13'

simulaqron/tests/unittests/quick/stabilizerStates/test_stabilizerStates.py

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,81 @@ def test_measure_eigenstate(self):
402402
output = s.measure(qubit)
403403
self.assertEqual(output, expected)
404404

405+
def test_correlations(self):
406+
tests = [ # stabilizers
407+
["ZI", "IZ"],
408+
["ZZ", "XX"],
409+
["ZX", "XZ"],
410+
["XXX", "ZZI", "IZZ"],
411+
["XIII", "IXII", "IIXI", "IIIX"],
412+
["XZII", "ZXZI", "IZXZ", "IIZX"], # line graph
413+
["XZIZ", "ZXZI", "IZXZ", "ZIZX"], # cycle graph
414+
["XZZZ", "ZXZZ", "ZZXZ", "ZZZX"], # complete graph
415+
["XZZZ", "ZXII", "ZIXI", "ZIIX"], # star graph
416+
]
417+
418+
for stabilizers in tests:
419+
for stabilizer in stabilizers:
420+
for _ in range(10):
421+
with self.subTest(stabilizers=stabilizers, stabilizer=stabilizer):
422+
s = StabilizerState(stabilizers)
423+
outcomes = []
424+
qubit = 0
425+
for pauli in stabilizer:
426+
if pauli == 'X':
427+
s.apply_H(qubit)
428+
elif pauli == 'Y':
429+
s.apply_K(qubit)
430+
elif pauli == 'Z':
431+
pass
432+
else:
433+
qubit += 1
434+
continue
435+
outcomes.append(s.measure(qubit))
436+
self.assertEqual(sum(outcomes) % 2, 0)
437+
438+
def test_standard_form(self):
439+
tests = [ # stabilizers
440+
["ZI", "IZ"],
441+
["ZZ", "XX"],
442+
["ZX", "XZ"],
443+
["XXX", "ZZI", "IZZ"],
444+
["XIII", "IXII", "IIXI", "IIIX"],
445+
["XZII", "ZXZI", "IZXZ", "IIZX"], # line graph
446+
["XZIZ", "ZXZI", "IZXZ", "ZIZX"], # cycle graph
447+
["XZZZ", "ZXZZ", "ZZXZ", "ZZZX"], # complete graph
448+
["XZZZ", "ZXII", "ZIXI", "ZIIX"], # star graph
449+
]
450+
451+
for stabilizers in tests:
452+
with self.subTest(stabilizers=stabilizers):
453+
state = StabilizerState(stabilizers)
454+
state.put_in_standard_form()
455+
# Check that there are no X or Y in the first column except the first row
456+
for row in state._group[1:, :]:
457+
self.assertFalse(row[0])
458+
459+
def test_reduce_when_measuring(self):
460+
tests = [ # stabilizers
461+
["ZI", "IZ"],
462+
["ZZ", "XX"],
463+
["ZX", "XZ"],
464+
["XXX", "ZZI", "IZZ"],
465+
["XIII", "IXII", "IIXI", "IIIX"],
466+
["XZII", "ZXZI", "IZXZ", "IIZX"], # line graph
467+
["XZIZ", "ZXZI", "IZXZ", "ZIZX"], # cycle graph
468+
["XZZZ", "ZXZZ", "ZZXZ", "ZZZX"], # complete graph
469+
["XZZZ", "ZXII", "ZIXI", "ZIIX"], # star graph
470+
]
471+
472+
for stabilizers in tests:
473+
with self.subTest(stabilizers=stabilizers):
474+
state = StabilizerState(stabilizers)
475+
n = len(state)
476+
for i in range(n):
477+
state.measure(0)
478+
self.assertEqual(len(state), n - i - 1)
479+
405480

406481
if __name__ == "__main__":
407482
unittest.main()

simulaqron/toolbox/stabilizerStates.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -225,13 +225,19 @@ def __str__(self):
225225
def __len__(self):
226226
return self.num_qubits
227227

228+
@staticmethod
229+
def _row_to_string(row):
230+
assert (len(row) - 1) % 2 == 0
231+
n = int((len(row) - 1) / 2)
232+
to_return = "{} ".format(StabilizerState.bool2phase[row[-1]])
233+
for i in range(n):
234+
to_return += StabilizerState.bool2Pauli[(row[i], row[i + n])]
235+
return to_return
236+
228237
def to_string(self):
229238
to_return = ""
230239
for row in self._group:
231-
to_return += "{} ".format(self.bool2phase[row[-1]])
232-
n = self.num_qubits
233-
for i in range(n):
234-
to_return += self.bool2Pauli[(row[i], row[i + n])]
240+
to_return += self._row_to_string(row)
235241
to_return += "\n"
236242
return to_return[:-1]
237243

@@ -285,14 +291,15 @@ def boolean_gaussian_elimination(matrix, return_pivot_columns=False):
285291
else:
286292
i_max = non_zero_ind_under_h[0]
287293
if i_max != h:
294+
# Move the row i_max to the h row
288295
new_matrix[[h, i_max]] = new_matrix[[i_max, h]]
289296
# Add pivot row to the rest
290297
pivot_columns.append(k)
291298
non_zero_except_i_max = non_zero_ind[non_zero_ind != i_max]
292299

293300
if len(non_zero_except_i_max) > 0:
294301
new_matrix[non_zero_except_i_max, :] = np.apply_along_axis(
295-
lambda row: StabilizerState._multiply_stabilizers(row, new_matrix[i_max]),
302+
lambda row: StabilizerState._multiply_stabilizers(row, new_matrix[h]),
296303
1,
297304
new_matrix[non_zero_except_i_max, :],
298305
)
@@ -707,7 +714,7 @@ def measure(self, position, inplace=False):
707714
"""
708715
n = self.num_qubits
709716
if not (position >= 0 and position < n):
710-
raise ValueError("position= {} if not a valid qubit position (i.e. in [0, {}]".format(position, n))
717+
raise ValueError("position = {} if not a valid qubit position (not in [0, {}))".format(position, n))
711718

712719
tmp_matrix = self._group
713720
# Create a new matrix where the X and Z columns of the corresponding qubit are the first.

0 commit comments

Comments
 (0)