Skip to content

Commit faeff78

Browse files
author
Axel Dahlberg
authored
Merge pull request #249 from SoftwareQuTech/hot-fix
Made boolean Gaussian elimination in stabilizer formalism faster
2 parents 656af0c + 687a1bc commit faeff78

5 files changed

Lines changed: 56 additions & 20 deletions

File tree

.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.10
2+
current_version = 3.0.11
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-01-27 (v3.0.11)
10+
-------------------
11+
- Boolean Gaussian elimination in stabilizer formalism is now faster.
12+
913
2019-10-30 (v3.0.10)
1014
-------------------
1115
- SimulaQron compatible with `cqc` version 3.1.0.

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.10)
3+
SimulaQron - simple quantum network simulator (3.0.11)
44
=====================================================
55

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

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.10'
4+
__version__ = '3.0.11'

simulaqron/toolbox/stabilizerStates.py

Lines changed: 49 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,6 @@ def boolean_gaussian_elimination(matrix, return_pivot_columns=False):
276276
h = 0
277277
k = 0
278278
pivot_columns = []
279-
num_paulis = int((n - 1) / 2)
280279
while (h < m) and (k < n):
281280
non_zero_ind = new_matrix[:, k].nonzero()[0]
282281
non_zero_ind_under_h = non_zero_ind[non_zero_ind >= h]
@@ -291,22 +290,13 @@ def boolean_gaussian_elimination(matrix, return_pivot_columns=False):
291290
pivot_columns.append(k)
292291
non_zero_except_i_max = non_zero_ind[non_zero_ind != i_max]
293292

294-
for i_loop in non_zero_except_i_max:
295-
extra_phase = 0 # we count i's here, so 2 -> (-i)^2=-1, 4->1, 6-> -1
296-
for j in range(num_paulis):
297-
extra_phase += StabilizerState.Pauli_phase_tracking([
298-
new_matrix[i_loop, j],
299-
new_matrix[i_loop, j + num_paulis]
300-
], [
301-
new_matrix[h, j],
302-
new_matrix[h, j + num_paulis]
303-
]
304-
)
305-
new_matrix[i_loop, :] = np.logical_xor(new_matrix[i_loop, :], new_matrix[h, :])
306-
# NOTE we are assuming that -I is not in the group and therefore that no stabilizer element
307-
# has a phase of +/- i, and therefore that extra_phase is a multiple of two
308-
if (extra_phase / 2) % 2:
309-
new_matrix[i_loop, -1] = np.logical_not(new_matrix[i_loop, -1])
293+
if len(non_zero_except_i_max) > 0:
294+
new_matrix[non_zero_except_i_max, :] = np.apply_along_axis(
295+
lambda row: StabilizerState._multiply_stabilizers(row, new_matrix[i_max]),
296+
1,
297+
new_matrix[non_zero_except_i_max, :],
298+
)
299+
310300
h += 1
311301
k += 1
312302
if return_pivot_columns:
@@ -317,6 +307,48 @@ def boolean_gaussian_elimination(matrix, return_pivot_columns=False):
317307
def check_symplectic(self):
318308
return self._is_symplectic(self._group)
319309

310+
@staticmethod
311+
def _multiply_stabilizers(s1, s2):
312+
"""
313+
Multiplies two stabilizers together to a third one.
314+
315+
See https://www.cs.umd.edu/~amchilds/teaching/w10/project-sample.pdf
316+
"""
317+
def g(vals):
318+
"""
319+
Helper function, see https://www.cs.umd.edu/~amchilds/teaching/w10/project-sample.pdf
320+
"""
321+
x1, z1, x2, z2 = map(int, vals)
322+
if x1 == 0:
323+
if z1 == 0:
324+
return 0
325+
else:
326+
return x2 * (1 - 2 * z2)
327+
else:
328+
if z1 == 0:
329+
return z2 * (2 * x2 - 1)
330+
else:
331+
return z2 - x2
332+
333+
assert len(s1) == len(s2)
334+
assert (len(s1) - 1) % 2 == 0
335+
num_paulis = int((len(s1) - 1) / 2)
336+
337+
# Update the x and z stabilizers
338+
new_s = np.logical_xor(s1, s2)
339+
340+
# Update the phase
341+
m = sum(map(g, zip(
342+
s2[:num_paulis],
343+
s2[num_paulis:-1],
344+
new_s[:num_paulis],
345+
new_s[num_paulis:-1],
346+
)))
347+
m %= 4
348+
349+
new_s[-1] ^= bool(m / 2)
350+
return new_s
351+
320352
@staticmethod
321353
def _is_symplectic(matrix):
322354
"""

0 commit comments

Comments
 (0)