def phase_flip( condition: 'Union[bool, qp.Qubit, qp.QubitIntersection, qp.RValue[bool]]' = True): if isinstance(condition, qp.QubitIntersection): sink.global_sink.do_phase_flip(condition) elif condition is False or condition == qp.QubitIntersection.NEVER: pass elif condition is True: phase_flip(qp.QubitIntersection.ALWAYS) elif isinstance(condition, qp.Qubit): phase_flip(qp.QubitIntersection((condition, ))) elif isinstance(condition, (qp.Qubit, qp.RValue)): with qp.hold(condition) as q: qp.phase_flip(q) else: raise NotImplementedError( "Unknown phase flip condition: {!r}".format(condition))
def do_xor_lookup(*, lvalue: 'qp.Quint', table: 'qp.LookupTable', address: 'qp.Quint.Borrowed', phase_instead_of_toggle: bool = False, control: 'qp.Qubit.Control' = True): assert isinstance(lvalue, qp.Quint) assert isinstance(address, qp.Quint) assert isinstance(control, qp.QubitIntersection) and len(control.qubits) <= 1 table = table[:1 << len(address)] address = address[:qp.ceil_lg2(len(table))] # Base case: single distinct value in table. if all(e == table[0] for e in table): if phase_instead_of_toggle: for k in range(len(lvalue)): if table[0] & (1 << k): qp.phase_flip(control & lvalue[k]) else: lvalue ^= table[0] & qp.controlled_by(control) return # Recursive case: divide and conquer. high_bit = address[-1] rest = address[:-1] h = 1 << (len(address) - 1) low_table = table[:h] high_table = table[h:] with qp.hold(control & high_bit, name='_lookup_prefix') as q: # Do lookup for half of table where high_bit is 0. q ^= control # Flip q to storing 'controls & ~high_bit'. do_xor_lookup(lvalue=lvalue, table=low_table, address=rest, phase_instead_of_toggle=phase_instead_of_toggle, control=q) q ^= control # Do lookup for half of table where high_bit is 1. do_xor_lookup(lvalue=lvalue, table=high_table, address=rest, phase_instead_of_toggle=phase_instead_of_toggle, control=q)
def clear_storage_location(self, location: Any, controls: 'qp.QubitIntersection'): if self.rhs & (-1 << len(self.lhs)): with qp.measurement_based_uncomputation(location) as b: if b: qp.phase_flip(self.invert) return with qp.measurement_based_uncomputation(location) as b: if b: self.lhs ^= ~self.rhs qp.phase_flip( qp.QubitIntersection(tuple(self.lhs)) & controls & b) qp.phase_flip(self.invert) self.lhs ^= ~self.rhs
def qf(): qp.phase_flip()
def clear_storage_location(self, location: Any, controls: 'qp.QubitIntersection'): with qp.measurement_based_uncomputation(location) as b: qp.phase_flip(self & controls & b)
def __riadd__(self, other): qp.phase_flip() return other
def clear_storage_location(self, location: 'qp.Quint', controls: 'qp.QubitIntersection'): with qp.measurement_based_uncomputation(location) as r: if qp.popcnt(r & self.val) & 1: qp.phase_flip(controls)
def clear_storage_location(self, location: 'qp.Qubit', controls: 'qp.QubitIntersection'): with qp.measurement_based_uncomputation(location) as b: if self.val and b: qp.phase_flip(controls)