"""Data structure for single-qubit measurements in MBQC."""from__future__importannotationsimportdataclassesimportmathfromtypingimportLiteral,NamedTuple,SupportsIntfromtyping_extensionsimportTypeAlias# TypeAlias introduced in Python 3.10fromgraphiximportutilsfromgraphix.fundamentalsimportAxis,Plane,Sign# Ruff suggests to move this import to a type-checking block, but dataclass requires it herefromgraphix.parameterimportExpressionOrFloat# noqa: TC001Outcome:TypeAlias=Literal[0,1]defoutcome(b:bool)->Outcome:"""Return 1 if True, 0 if False."""return1ifbelse0deftoggle_outcome(outcome:Outcome)->Outcome:"""Toggle outcome."""return1ifoutcome==0else0@dataclasses.dataclassclassDomains:"""Represent `X^sZ^t` where s and t are XOR of results from given sets of indices."""s_domain:set[int]t_domain:set[int]
[docs]classMeasurement(NamedTuple):"""An MBQC measurement. :param angle: the angle of the measurement. Should be between [0, 2) :param plane: the measurement plane """angle:ExpressionOrFloatplane:Planedefisclose(self,other:Measurement,rel_tol:float=1e-09,abs_tol:float=0.0)->bool:"""Compare if two measurements have the same plane and their angles are close. Example ------- >>> from graphix.opengraph import Measurement >>> from graphix.fundamentals import Plane >>> Measurement(0.0, Plane.XY).isclose(Measurement(0.0, Plane.XY)) True >>> Measurement(0.0, Plane.XY).isclose(Measurement(0.0, Plane.YZ)) False >>> Measurement(0.1, Plane.XY).isclose(Measurement(0.0, Plane.XY)) False """return(math.isclose(self.angle,other.angle,rel_tol=rel_tol,abs_tol=abs_tol)ifisinstance(self.angle,float)andisinstance(other.angle,float)elseself.angle==other.angle)andself.plane==other.plane
classPauliMeasurement(NamedTuple):"""Pauli measurement."""axis:Axissign:Sign@staticmethoddeftry_from(plane:Plane,angle:ExpressionOrFloat)->PauliMeasurement|None:"""Return the Pauli measurement description if a given measure is Pauli."""angle_double=2*angleifnotisinstance(angle_double,SupportsInt)ornotutils.is_integer(angle_double):returnNoneangle_double_mod_4=int(angle_double)%4axis=plane.cosifangle_double_mod_4%2==0elseplane.sinsign=Sign.minus_if(angle_double_mod_4>=2)returnPauliMeasurement(axis,sign)