Example #1
0
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))
Example #2
0
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)
Example #3
0
 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()
Example #5
0
 def clear_storage_location(self,
                            location: Any,
                            controls: 'qp.QubitIntersection'):
     with qp.measurement_based_uncomputation(location) as b:
         qp.phase_flip(self & controls & b)
Example #6
0
 def __riadd__(self, other):
     qp.phase_flip()
     return other
Example #7
0
 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)
Example #8
0
 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)