Skip to content

algo/statiliser.py

class Statiliser

Statiliser is a class that generates a basis of states stabilized by a given set of stabilizers. Stabilizers are represented as strings of Paulis (e.g., "ZZZII", "IIZZZ", "XIXXI", "IXXIX").

generate uses gradient-free optimization to find states that are stabilized by the provided stabilizers, and then applies the Gram-Schmidt process to ensure the resulting states form an orthonormal basis.

nametypedefault
basisOptional[pt.Tensor]None
num_statesintNone
stabilisersList[pt.Tensor]None
szintNone

init

Create a generator for the subspace stabilised by stabilisers.

py
def __init__(self: Any, stabilisers: Sequence[Union[str, pt.Tensor]], d: int) -> Any
Implementation
python
def __init__(self, stabilisers: Sequence[Union[str, pt.Tensor]], d: int=2):
    self.d = d
    gg = Gategen(dim=d)
    self._ops = {'I': pt.eye(d, dtype=pt.cfloat), 'X': gg.X.tensor.to(pt.cfloat), 'Z': gg.Z.tensor.to(pt.cfloat), 'Y': gg.Y.tensor.to(pt.cfloat)}

    def _str_to_tensor(string: str) -> pt.Tensor:
        ops = [self._ops[c] for c in string]
        state = ops[0]
        for op in ops[1:]:
            state = pt.kron(op, state)
        return state
    stabilisers = [_str_to_tensor(s) if isinstance(s, str) else s for s in stabilisers]
    self.stabilisers = list(stabilisers)
    self.sz = int(math.log(stabilisers[0].shape[0], d))
    self.num_states = d ** (self.sz - len(stabilisers))
    self.basis = None

generate

Generate an orthonormal basis for the stabilised subspace.

py
def generate(self: Any, mode: str, tol: float, minimal: bool) -> pt.Tensor
Implementation
python
def generate(self, mode: str='real', tol: float=1e-06, minimal: bool=True) -> pt.Tensor:
    basis: List[pt.Tensor] = []
    factor = 2 if mode == 'complex' else 1
    for _ in range(self.num_states):
        res = minimize(self._fun, x0=pt.rand(self.d ** self.sz * factor).numpy(), args=(mode, int(minimal)), method='Powell', tol=tol).x
        state = pt.tensor(res, dtype=pt.float32 if mode == 'real' else pt.cfloat)
        if mode != 'real':
            state = self._to_complex(state)
        state = state / pt.norm(state)
        basis.append(state)
    basis_t = GramSchmidt(basis)
    basis_t = basis_t.to(dtype=pt.float16 if mode == 'real' else pt.cfloat)
    self.basis = basis_t
    return basis_t

S

Convert a Pauli string (e.g. "XIIZ") into its operator tensor.

py
def S(string: str) -> pt.Tensor
Implementation
python
def S(string: str) -> pt.Tensor:
    paulis = [_paulis[i] for i in string]
    return _S(*paulis)

GramSchmidt

Orthonormalise a list/sequence of vectors using Gram-Schmidt.

Vectors with (near-)zero residual norm are dropped.

py
def GramSchmidt(vectors: Sequence[pt.Tensor]) -> pt.Tensor
Implementation
python
def GramSchmidt(vectors: Sequence[pt.Tensor]) -> pt.Tensor:
    ortho: List[pt.Tensor] = []
    for v in vectors:
        w = v - sum((v @ u.conj() * u for u in ortho))
        nrm = pt.norm(w)
        if nrm > 1e-08:
            ortho.append(w / nrm)
    return pt.stack(ortho)