本文整理汇总了Python中PauliClass类的典型用法代码示例。如果您正苦于以下问题:Python PauliClass类的具体用法?Python PauliClass怎么用?Python PauliClass使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了PauliClass类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Python代码示例。
示例1: block_logical_pauli
def block_logical_pauli(self, P):
r"""
Given a Pauli operator :math:`P` acting on :math:`k`, finds a Pauli
operator :math:`\overline{P}` on :math:`n_k` qubits that corresponds
to the logical operator acting across :math:`k` blocks of this code.
Note that this method is only supported for single logical qubit codes.
"""
if self.nq_logical > 1:
raise NotImplementedError("Mapping of logical Pauli operators is currently only supported for single-qubit codes.")
# TODO: test that phases are handled correctly.
# FIXME: cache this dictionary.
replace_dict = {
'I': p.eye_p(self.nq),
'X': self.logical_xs[0],
'Y': (self.logical_xs[0] * self.logical_zs[0]).mul_phase(1),
'Z': self.logical_zs[0]
}
# FIXME: using eye_p(0) is a hack.
return reduce(op.and_,
(replace_dict[sq_op] for sq_op in P.op),
p.eye_p(0))
示例2: flip_code
def flip_code(n_correctable, stab_kind='Z'):
"""
Creates an instance of :class:`qecc.StabilizerCode` representing a
code that protects against weight-``n_correctable`` flip errors of a
single kind.
This method generalizes the bit-flip and phase-flip codes, corresponding
to ``stab_kind=qecc.Z`` and ``stab_kind=qecc.X``, respectively.
:param int n_correctable: Maximum weight of the errors that can be
corrected by this code.
:param qecc.Pauli stab_kind: Single-qubit Pauli operator specifying
which kind of operators to use for the new stabilizer code.
:rtype: qecc.StabilizerCode
"""
nq = 2 * n_correctable + 1
stab_kind = p.ensure_pauli(stab_kind)
if len(stab_kind) != 1:
raise ValueError("stab_kind must be single-qubit.")
return StabilizerCode(
[p.eye_p(j) & stab_kind & stab_kind & p.eye_p(nq-j-2) for j in range(nq-1)],
['X'*nq], ['Z'*nq],
label='{}-flip code (t = {})'.format(stab_kind.op, n_correctable)
)
示例3: transcoding_cliffords
def transcoding_cliffords(self,other):
r"""
Returns an iterator onto all :class:`qecc.Clifford` objects which
take states specified by ``self``, and
return states specified by ``other``.
:arg other: :class:`qecc.StabilizerCode`
"""
#Preliminaries:
stab_in = self.group_generators
stab_out = other.group_generators
xs_in = self.logical_xs
xs_out = other.logical_xs
zs_in = self.logical_zs
zs_out = other.logical_zs
nq_in=len(stab_in[0])
nq_out=len(stab_out[0])
nq_anc=abs(nq_in-nq_out)
#Decide left side:
if nq_in<nq_out:
stab_left=stab_out
xs_left=xs_out
zs_left=zs_out
stab_right=stab_in
xs_right=xs_in
zs_right=zs_in
else:
stab_right=stab_out
xs_right=xs_out
zs_right=zs_out
stab_left=stab_in
xs_left=xs_in
zs_left=zs_in
cliff_xouts_left=stab_left+xs_left
cliff_zouts_left=[Unspecified]*len(stab_left)+zs_left
cliff_left=c.Clifford(cliff_xouts_left,cliff_zouts_left).constraint_completions().next()
list_left=cliff_left.xout+cliff_left.zout
for mcset in p.mutually_commuting_sets(n_elems=len(stab_left)-len(stab_right),n_bits=nq_anc):
temp_xouts_right = p.pad(stab_right,lower_right=mcset) + map(lambda elem: elem & p.eye_p(nq_anc), xs_right)
temp_zouts_right = [Unspecified]*len(stab_left) + map(lambda elem: elem & p.eye_p(nq_anc), zs_right)
for completion in c.Clifford(temp_xouts_right,temp_zouts_right).constraint_completions():
if nq_in < nq_out:
yield c.gen_cliff(completion.xout+completion.zout,list_left)
else:
yield c.gen_cliff(list_left,completion.xout+completion.zout)
示例4: min_len_transcoding_clifford
def min_len_transcoding_clifford(self,other):
"""
Searches the iterator provided by `transcoding_cliffords` for the shortest
circuit decomposition.
"""
circuit_iter=map(lambda p: p.as_bsm().circuit_decomposition(), self.transcoding_cliffords(other))
return min(*circuit_iter)
示例5: in_group_generated_by
def in_group_generated_by(*paulis):
"""
Returns a predicate that selects Pauli operators in the group generated by
a given list of generators.
"""
# Warning: This is inefficient for large groups!
paulis = list(map(pc.ensure_pauli, paulis))
return PauliMembershipPredicate(pc.from_generators(paulis), ignore_phase=True)
示例6: concatenate
def concatenate(self,other):
r"""
Returns the stabilizer for a concatenated code, given the
stabilizers for two codes. At this point, it only works for two
:math:`k=1` codes.
"""
if self.nq_logical > 1 or other.nq_logical > 1:
raise NotImplementedError("Concatenation is currently only supported for single-qubit codes.")
nq_self = self.nq
nq_other = other.nq
nq_new = nq_self * nq_other
# To obtain the new generators, we must apply the stabilizer generators
# to each block of the inner code (self), as well as the stabilizer
# generators of the outer code (other), using the inner logical Paulis
# for the outer stabilizer generators.
# Making the stabilizer generators from the inner (L0) code is straight-
# forward: we repeat the code other.nq times, once on each block of the
# outer code. We use that PauliList supports tensor products.
new_generators = sum(
(
p.eye_p(nq_self * k) & self.group_generators & p.eye_p(nq_self * (nq_other - k - 1))
for k in range(nq_other)
),
pc.PauliList())
# Each of the stabilizer generators due to the outer (L1) code can be
# found by computing the block-logical operator across multiple L0
# blocks, as implemented by StabilizerCode.block_logical_pauli.
new_generators += map(self.block_logical_pauli, other.group_generators)
# In the same way, the logical operators are also found by mapping L1
# operators onto L0 qubits.
# This completes the definition of the concatenated code, and so we are
# done.
return StabilizerCode(new_generators,
logical_xs=map(self.block_logical_pauli, other.logical_xs),
logical_zs=map(self.block_logical_pauli, other.logical_zs)
)
示例7: ancilla_register
def ancilla_register(nq=1):
r"""
Creates an instance of :class:`qecc.StabilizerCode` representing an
ancilla register of ``nq`` qubits, initialized in the state
:math:`\left|0\right\rangle^{\otimes \text{nq}}`.
:rtype: qecc.StabilizerCode
"""
return StabilizerCode(
p.elem_gens(nq)[1],
[], []
)
示例8: possible_faults
def possible_faults(circuit):
"""
Takes a sub-circuit which has been padded with waits, and returns an
iterator onto Paulis which may occur as faults after this sub-circuit.
:param qecc.Circuit circuit: Subcircuit to in which faults are to be
considered.
"""
return it.chain.from_iterable(
pc.restricted_pauli_group(loc.qubits, circuit.nq)
for loc in circuit
)
示例9: unencoded_state
def unencoded_state(nq_logical=1, nq_ancilla=0):
"""
Creates an instance of :class:`qecc.StabilizerCode` representing an
unencoded register of ``nq_logical`` qubits tensored with an ancilla
register of ``nq_ancilla`` qubits.
:param int nq_logical: Number of qubits to
:rtype: qecc.StabilizerCode
"""
return (
StabilizerCode([], *p.elem_gens(nq_logical)) &
StabilizerCode.ancilla_register(nq_ancilla)
)
示例10: logical_pauli_group
def logical_pauli_group(self, incl_identity=True):
r"""
Iterator onto the group :math:`\text{N}(S) / S`, where :math:`S` is
the stabilizer group describing this code. Each member of the group
is specified by a coset representative drawn from the respective
elements of :math:`\text{N}(S) / S`. These representatives are
chosen to be the logical :math:`X` and :math:`Z` operators specified
as properties of this instance.
:param bool incl_identity: If ``False``, the identity coset :math:`S`
is excluded from this iterator.
:yields: A representative for each element of :math:`\text{N}(S) / S`.
"""
return p.from_generators(self.logical_xs + self.logical_zs, incl_identity=incl_identity)
示例11: minimize_distance_from
def minimize_distance_from(self, other, quiet=True):
"""
Reorders the stabilizer group generators of this code to minimize
the Hamming distance with the group generators of another code,
using a greedy heuristic algorithm.
"""
self_gens = self.group_generators
other_gens = other.group_generators
for idx_generator in range(len(self_gens)):
min_hdist = self.nq + 1 # Effectively infinite.
min_wt = self.nq + 1
best_gen = None
best_gen_decomp = ()
for stab_elems in p.powerset(self_gens[idx_generator:]):
if len(stab_elems) > 0:
stab_elem = reduce(op.mul, stab_elems)
hd = stab_elem.hamming_dist(other_gens[idx_generator])
if hd <= min_hdist and stab_elem.wt <= min_wt and (hd < min_hdist or stab_elem.wt < min_wt):
min_hdist = hd
min_wt = stab_elem.wt
best_gen = stab_elem
best_gen_decomp = stab_elems
assert best_gen is not None, "Powerset iteration failed."
if best_gen in self_gens:
# Swap so that it lies at the front.
idx = self_gens.index(best_gen)
if not quiet and idx != idx_generator:
print 'Swap move: {} <-> {}'.format(idx_generator, idx)
self_gens[idx_generator], self_gens[idx] = self_gens[idx], self_gens[idx_generator]
else:
# Set the head element to best_gen, correcting the rest
# as needed.
if self_gens[idx_generator] in best_gen_decomp:
if not quiet:
print 'Set move: {} = {}'.format(idx_generator, best_gen)
self_gens[idx_generator] = best_gen
else:
if not quiet:
print 'Mul move: {} *= {}'.format(idx_generator, best_gen)
self_gens[idx_generator] *= best_gen
return self
示例12: pad
def pad(self, extra_bits=0, lower_right=None):
r"""
Takes a PauliList, and returns a new PauliList,
appending ``extra_bits`` qubits, with stabilizer operators specified by
``lower_right``.
:arg pauli_list_in: list of Pauli operators to be padded.
:param int extra_bits: Number of extra bits to be appended to the system.
:param lower_right: list of `qecc.Pauli` operators, acting on `extra_bits` qubits.
:rtype: list of :class:`qecc.Pauli` objects.
Example:
>>> import qecc as q
>>> pauli_list = q.PauliList('XXX', 'YIY', 'ZZI')
>>> pauli_list.pad(extra_bits=2, lower_right=q.PauliList('IX','ZI'))
PauliList(i^0 XXXII, i^0 YIYII, i^0 ZZIII, i^0 IIIIX, i^0 IIIZI)
"""
len_P = len(self)
nq_P = len(self[0]) if len_P > 0 else 0
if extra_bits == 0 and lower_right is None or len(lower_right) == 0:
return PauliList(self)
elif len(lower_right) != 0:
extra_bits=len(lower_right[0])
setout = PauliList([pc.Pauli(pauli.op + 'I'*extra_bits) for pauli in self])
if lower_right is None:
setout += [pc.eye_p(nq_P + extra_bits)] * extra_bits
else:
setout += [pc.eye_p(nq_P) & P for P in lower_right]
return setout
示例13: syndrome_to_recovery_operator
def syndrome_to_recovery_operator(self,synd):
r"""
Returns a Pauli operator which corrects an error on the stabilizer code
``self``, given the syndrome ``synd``, a bitstring indicating which
generators the implied error commutes with and anti-commutes with.
:param synd: a string, list, tuple or other sequence type with entries
consisting only of 0 or 1. This parameter will be certified before
use.
"""
# If the syndrome is an integer, change it to a bitstring by
# using string formatting.
if isinstance(synd,int):
fmt = "{{0:0>{n}b}}".format(n=self.n_constraints)
synd = fmt.format(synd)
# Ensures synd is a list of integers by mapping int onto the list.
synd=map(int, synd)
# Check that the syndrome is all zeros and ones.
acceptable_syndrome = all([bit == 0 or bit == 1 for bit in synd])
if not acceptable_syndrome:
raise ValueError("Please input a syndrome which is an iterable onto 0 and 1.")
if len(synd) != self.nq - self.nq_logical:
raise ValueError("Syndrome must account for n-k bits of syndrome data.")
# We produce commutation and anti_commutation constraints from synd.
anti_coms = list(it.compress(self.group_generators,synd))
coms = list(it.compress(self.group_generators,[1-bit for bit in synd]))
for op_weight in range(self.nq+1):
#We loop over all possible weights. As soon as we find an operator
#that satisfies the commutation and anti-commutation constraints,
#we return it:
low_weight_ops=map(p.remove_phase,
cs.solve_commutation_constraints(coms,anti_coms,
search_in_set=p.paulis_by_weight(self.nq,
op_weight)))
if low_weight_ops:
break
return low_weight_ops[0]
示例14: centralizer_gens
def centralizer_gens(self, group_gens=None):
r"""
Returns the generators of the centralizer group
:math:`\mathrm{C}(P_1, \dots, P_k)`, where :math:`P_i` is the :math:`i^{\text{th}}`
element of this list. See :meth:`qecc.Pauli.centralizer_gens` for
more information.
"""
if group_gens is None:
# NOTE: Assumes all Paulis contained by self have the same nq.
Xs, Zs = pc.elem_gens(len(self[0]))
group_gens = Xs + Zs
if len(self) == 0:
# C({}) = G
return PauliList(group_gens)
centralizer_0 = self[0].centralizer_gens(group_gens=group_gens)
if len(self) == 1:
return centralizer_0
else:
return self[1:].centralizer_gens(group_gens=centralizer_0)
示例15: __and__
def __and__(self, other):
"""Returns the Kronecker product of two stabilizer codes,
given each of the constituent codes. """
if not isinstance(other, StabilizerCode):
return NotImplemented
return StabilizerCode(
(self.group_generators & p.eye_p(other.nq)) +
(p.eye_p(self.nq) & other.group_generators),
(self.logical_xs & p.eye_p(other.nq)) +
(p.eye_p(self.nq) & other.logical_xs),
(self.logical_zs & p.eye_p(other.nq)) +
(p.eye_p(self.nq) & other.logical_zs),
)