Skip to content

Commit

Permalink
Masking functionality for PauliwordOp.__getitem__
Browse files Browse the repository at this point in the history
  • Loading branch information
TimWeaving committed Nov 8, 2022
1 parent 2ac7196 commit 2a5ebe9
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 21 deletions.
2 changes: 1 addition & 1 deletion symmer/projection/contextual_subspace.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def manual_stabilizers(self, S: Union[List[str], StabilizerOp]) -> None:
"""
"""
if isinstance(S, list):
S = StabilizerOp.from_list(S_list)
S = StabilizerOp.from_list(S)
self.n_qubits_in_subspace = self.operator.n_qubits - S.n_terms
self.stabilizers = S

Expand Down
2 changes: 1 addition & 1 deletion symmer/projection/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ def build_basis_weighting_operator(self):
np.abs(self.weighting_operator.coeff_vec)
).cleanup()
#X_op = self.weighting_operator
self.basis_weighting = X_op.sort(key='magnitude')
self.basis_weighting = X_op.sort(by='magnitude')
self.qubit_positions = np.arange(self.weighting_operator.n_qubits)
self.term_region = [0,self.basis_weighting.n_terms]

Expand Down
36 changes: 20 additions & 16 deletions symmer/symplectic/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -293,27 +293,27 @@ def copy(self) -> "PauliwordOp":
return deepcopy(self)

def sort(self,
by: str = 'decreasing',
key:str = 'magnitude'
by: str = 'magnitude',
key: str = 'decreasing'
) -> "PauliwordOp":
"""
Sort the terms by some key, either magnitude, weight X, Y or Z
Sort the terms either by magnitude, weight X, Y or Z
"""
if key=='magnitude':
if by=='magnitude':
sort_order = np.argsort(-abs(self.coeff_vec))
elif key=='weight':
sort_order = np.argsort(-np.sum(self.symp_matrix, axis=1))
elif key=='Z':
sort_order = np.argsort(np.sum((self.n_qubits+1)*self.X_block + self.Z_block, axis=1))
elif key=='X':
sort_order = np.argsort(np.sum(self.X_block + (self.n_qubits+1)*self.Z_block, axis=1))
elif key=='Y':
sort_order = np.argsort(np.sum(abs(self.X_block - self.Z_block), axis=1))
elif by=='weight':
sort_order = np.argsort(-np.sum(self.symp_matrix.astype(int), axis=1))
elif by=='Z':
sort_order = np.argsort(np.sum((self.n_qubits+1)*self.X_block.astype(int) + self.Z_block.astype(int), axis=1))
elif by=='X':
sort_order = np.argsort(np.sum(self.X_block.astype(int) + (self.n_qubits+1)*self.Z_block.astype(int), axis=1))
elif by=='Y':
sort_order = np.argsort(np.sum(abs(self.X_block.astype(int) - self.Z_block.astype(int)), axis=1))
else:
raise ValueError('Only permitted sort key values are magnitude, weight, X, Y or Z')
if by=='increasing':
raise ValueError('Only permitted sort by values are magnitude, weight, X, Y or Z')
if key=='increasing':
sort_order = sort_order[::-1]
elif by!='decreasing':
elif key!='decreasing':
raise ValueError('Only permitted sort by values are increasing or decreasing')
return PauliwordOp(self.symp_matrix[sort_order], self.coeff_vec[sort_order])

Expand Down Expand Up @@ -572,6 +572,10 @@ def __getitem__(self,
if stop is None:
stop=self.n_terms
mask = np.arange(start, stop, key.step)
elif isinstance(key, (list, np.ndarray)):
mask = np.asarray(key)
else:
raise ValueError('Unrecognised input, must be an integer, slice, list or np.array')

symp_items = self.symp_matrix[mask]
coeff_items = self.coeff_vec[mask]
Expand Down Expand Up @@ -809,7 +813,7 @@ def clique_cover(self,
if colouring_interchange is not False:
warnings.warn(f'{strategy} is not a graph colouring method, so colouring_interchange flag is ignored')

sorted_op_list = list(self.sort(by='decreasing', key='magnitude'))
sorted_op_list = list(self.sort(by='magnitude', key='decreasing'))

check_dic = {
'C': lambda x, y: np.all(x.commutes_termwise(y)),
Expand Down
6 changes: 3 additions & 3 deletions symmer/symplectic/noncontextual_op.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def _dfs_noncontextual_op(cls, H: PauliwordOp, runtime=10, strategy='magnitude')
cutoff time ensures if the number of possibilities is large the function will STOP and not take too long
"""
operator = H.sort(key='magnitude')
operator = H.sort(by='magnitude')
noncontextual_ops = []

n=0
Expand Down Expand Up @@ -102,7 +102,7 @@ def _diag_first_noncontextual_op(cls, H: PauliwordOp):
"""
noncontextual_operator = cls._diag_noncontextual_op(H)
# order the remaining terms by coefficient magnitude
off_diag_terms = (H - noncontextual_operator).sort(key='magnitude')
off_diag_terms = (H - noncontextual_operator).sort(by='magnitude')
# append terms that do not make the noncontextual_operator contextual!
for term in off_diag_terms:
if (noncontextual_operator+term).is_noncontextual:
Expand All @@ -117,7 +117,7 @@ def _single_sweep_noncontextual_operator(cls, H, strategy='magnitude'):
noncontextual_operator = PauliwordOp.empty(H.n_qubits)

if strategy=='magnitude':
operator = H.sort(key='magnitude')
operator = H.sort(by='magnitude')
elif strategy=='random':
order = np.arange(H.n_terms)
np.random.shuffle(order)
Expand Down

0 comments on commit 2a5ebe9

Please sign in to comment.