@@ -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