Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .bumpversion.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 3.0.12
current_version = 3.0.13
commit = True
tag = False

Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ For more details refer to the [documentation](https://softwarequtech.github.io/S
Upcoming
--------

2020-02-23 (v3.0.13)
-------------------
- Fixed bug in the Boolean Gaussian elimination in stabilizer formalism.

2020-01-27 (v3.0.12)
-------------------
- Boolean Gaussian elimination in stabilizer formalism is now even faster.
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[![Build Status](https://travis-ci.com/SoftwareQuTech/SimulaQron.svg?branch=Develop)](https://travis-ci.com/SoftwareQuTech/SimulaQron)

SimulaQron - simple quantum network simulator (3.0.12)
SimulaQron - simple quantum network simulator (3.0.13)
=====================================================

The purpose of this simulator of quantum network nodes is to allow you to develop new applications for
Expand Down
2 changes: 1 addition & 1 deletion simulaqron/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from simulaqron.tests_run import main as tests

__all__ = ['tests']
__version__ = '3.0.12'
__version__ = '3.0.13'
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,81 @@ def test_measure_eigenstate(self):
output = s.measure(qubit)
self.assertEqual(output, expected)

def test_correlations(self):
tests = [ # stabilizers
["ZI", "IZ"],
["ZZ", "XX"],
["ZX", "XZ"],
["XXX", "ZZI", "IZZ"],
["XIII", "IXII", "IIXI", "IIIX"],
["XZII", "ZXZI", "IZXZ", "IIZX"], # line graph
["XZIZ", "ZXZI", "IZXZ", "ZIZX"], # cycle graph
["XZZZ", "ZXZZ", "ZZXZ", "ZZZX"], # complete graph
["XZZZ", "ZXII", "ZIXI", "ZIIX"], # star graph
]

for stabilizers in tests:
for stabilizer in stabilizers:
for _ in range(10):
with self.subTest(stabilizers=stabilizers, stabilizer=stabilizer):
s = StabilizerState(stabilizers)
outcomes = []
qubit = 0
for pauli in stabilizer:
if pauli == 'X':
s.apply_H(qubit)
elif pauli == 'Y':
s.apply_K(qubit)
elif pauli == 'Z':
pass
else:
qubit += 1
continue
outcomes.append(s.measure(qubit))
self.assertEqual(sum(outcomes) % 2, 0)

def test_standard_form(self):
tests = [ # stabilizers
["ZI", "IZ"],
["ZZ", "XX"],
["ZX", "XZ"],
["XXX", "ZZI", "IZZ"],
["XIII", "IXII", "IIXI", "IIIX"],
["XZII", "ZXZI", "IZXZ", "IIZX"], # line graph
["XZIZ", "ZXZI", "IZXZ", "ZIZX"], # cycle graph
["XZZZ", "ZXZZ", "ZZXZ", "ZZZX"], # complete graph
["XZZZ", "ZXII", "ZIXI", "ZIIX"], # star graph
]

for stabilizers in tests:
with self.subTest(stabilizers=stabilizers):
state = StabilizerState(stabilizers)
state.put_in_standard_form()
# Check that there are no X or Y in the first column except the first row
for row in state._group[1:, :]:
self.assertFalse(row[0])

def test_reduce_when_measuring(self):
tests = [ # stabilizers
["ZI", "IZ"],
["ZZ", "XX"],
["ZX", "XZ"],
["XXX", "ZZI", "IZZ"],
["XIII", "IXII", "IIXI", "IIIX"],
["XZII", "ZXZI", "IZXZ", "IIZX"], # line graph
["XZIZ", "ZXZI", "IZXZ", "ZIZX"], # cycle graph
["XZZZ", "ZXZZ", "ZZXZ", "ZZZX"], # complete graph
["XZZZ", "ZXII", "ZIXI", "ZIIX"], # star graph
]

for stabilizers in tests:
with self.subTest(stabilizers=stabilizers):
state = StabilizerState(stabilizers)
n = len(state)
for i in range(n):
state.measure(0)
self.assertEqual(len(state), n - i - 1)


if __name__ == "__main__":
unittest.main()
19 changes: 13 additions & 6 deletions simulaqron/toolbox/stabilizerStates.py
Original file line number Diff line number Diff line change
Expand Up @@ -225,13 +225,19 @@ def __str__(self):
def __len__(self):
return self.num_qubits

@staticmethod
def _row_to_string(row):
assert (len(row) - 1) % 2 == 0
n = int((len(row) - 1) / 2)
to_return = "{} ".format(StabilizerState.bool2phase[row[-1]])
for i in range(n):
to_return += StabilizerState.bool2Pauli[(row[i], row[i + n])]
return to_return

def to_string(self):
to_return = ""
for row in self._group:
to_return += "{} ".format(self.bool2phase[row[-1]])
n = self.num_qubits
for i in range(n):
to_return += self.bool2Pauli[(row[i], row[i + n])]
to_return += self._row_to_string(row)
to_return += "\n"
return to_return[:-1]

Expand Down Expand Up @@ -285,14 +291,15 @@ def boolean_gaussian_elimination(matrix, return_pivot_columns=False):
else:
i_max = non_zero_ind_under_h[0]
if i_max != h:
# Move the row i_max to the h row
new_matrix[[h, i_max]] = new_matrix[[i_max, h]]
# Add pivot row to the rest
pivot_columns.append(k)
non_zero_except_i_max = non_zero_ind[non_zero_ind != i_max]

if len(non_zero_except_i_max) > 0:
new_matrix[non_zero_except_i_max, :] = np.apply_along_axis(
lambda row: StabilizerState._multiply_stabilizers(row, new_matrix[i_max]),
lambda row: StabilizerState._multiply_stabilizers(row, new_matrix[h]),
1,
new_matrix[non_zero_except_i_max, :],
)
Expand Down Expand Up @@ -707,7 +714,7 @@ def measure(self, position, inplace=False):
"""
n = self.num_qubits
if not (position >= 0 and position < n):
raise ValueError("position= {} if not a valid qubit position (i.e. in [0, {}]".format(position, n))
raise ValueError("position = {} if not a valid qubit position (not in [0, {}))".format(position, n))

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