def do_plus_const_mod(*, control: qp.Qubit.Control = True, lvalue: qp.Quint, offset: int, modulus: int, forward: bool = True): assert isinstance(control, qp.QubitIntersection) and len(control.qubits) <= 1 assert isinstance(lvalue, qp.Quint) assert isinstance(offset, int) assert isinstance(modulus, int) assert modulus > 0 n = (modulus - 1).bit_length() assert len(lvalue) >= n if not forward: offset *= -1 offset %= modulus if not modulus & (modulus - 1): lvalue += offset & qp.controlled_by(control) return with qp.qalloc(name='mod_cmp') as q: q.init(lvalue >= modulus - offset, controls=control) lvalue += offset & qp.controlled_by(control) lvalue -= modulus & qp.controlled_by(q & control) q.clear(lvalue < offset, controls=control)
def test_xor_equal_gate_circuit_2(): with qp.Sim(enforce_release_at_zero=False): with qp.LogCirqCircuit() as circuit: with qp.qalloc(len=3, name='a') as a: with qp.qalloc(len=4, name='t') as t: with qp.qalloc(name='_c') as c: t ^= a t ^= a & qp.controlled_by(c) cirq.testing.assert_has_diagram(circuit, r""" _c: ---------------------alloc---------------@---@---@---release----------------------- | | | a[0]: ---alloc-------------------@-----------@---|---|-----------------------release--- | | | | | | a[1]: ---alloc-------------------|---@-------|---@---|-----------------------release--- | | | | | | | a[2]: ---alloc-------------------|---|---@---|---|---@-----------------------release--- | | | | | | t[0]: -----------alloc-----------X---|---|---X---|---|-------------release------------- | | | | | | t[1]: -----------alloc---------------X---|-------X---|-------------release------------- | | | | t[2]: -----------alloc-------------------X-----------X-------------release------------- | | t[3]: -----------alloc---------------------------------------------release------------- """, use_unicode_characters=False)
def add(target: qp.Quint, offset: qp.Quint.Borrowed, *, control: qp.Qubit.Control = False): assert isinstance(target, qp.Quint) assert isinstance(offset, qp.Quint) assert isinstance(control, qp.QubitIntersection) target += offset & qp.controlled_by(control)
def do_multiplication(*, control: qp.Qubit.Control = True, lvalue: qp.Quint, factor: int, forward: bool = True): assert isinstance(control, qp.QubitIntersection) and len(control.qubits) <= 1 assert isinstance(lvalue, qp.Quint) assert isinstance(factor, int) assert factor % 2 == 1 if forward: for i in range(len(lvalue))[::-1]: c = control & lvalue[i] lvalue[i + 1:] += (factor >> 1) & qp.controlled_by(c) else: for i in range(len(lvalue)): c = control & lvalue[i] lvalue[i + 1:] -= (factor >> 1) & qp.controlled_by(c)
def __rixor__(self, other): other, controls = qp.ControlledLValue.split(other) if controls == qp.QubitIntersection.NEVER: return other if isinstance(other, qp.Quint): t = qp.LookupTable(1 << k for k in range(1 << len(self.binary))) other ^= t[self.binary] & qp.controlled_by(controls) return other return NotImplemented
def do_plus_product(*, control: qp.Qubit.Control = True, lvalue: qp.Quint, quantum_factor: qp.Quint.Borrowed, const_factor: int, forward: bool = True): assert isinstance(control, qp.QubitIntersection) and len(control.qubits) <= 1 assert isinstance(lvalue, qp.Quint) assert isinstance(quantum_factor, qp.Quint) assert isinstance(const_factor, int) for i, q in enumerate(quantum_factor): with qp.hold(const_factor & qp.controlled_by(q & control)) as offset: if forward: lvalue[i:] += offset else: lvalue[i:] -= offset
def test_xor_lookup(): with qp.Sim(phase_fixup_bias=True, enforce_release_at_zero=False): with qp.LogCirqCircuit() as circuit: with qp.qalloc(len=4, name='addr') as addr: with qp.qalloc(len=8, name='out') as out: with qp.qalloc(name='cnt') as cnt: out ^= qp.LookupTable(range( 1, 17))[addr] & qp.controlled_by(cnt) cirq.testing.assert_has_diagram(circuit, r""" _lookup_prefix: -----------------------------alloc---X---X-----------@---@-------------------------------------------------------------------------------------------------------------------------------------------------------------@-------------------------------------------------------------------------------------------------------------------------------------------------------------------@-------------------X-----------@---@-------------------------------------------------------------------------------------------------------------------------------------------------------------@-------------------------------------------------------------------------------------------------------------------------------------------------------------------@-------------------Mxc-------cxM---release--------------------------------- | | | | | | | | | | | _lookup_prefix_1: -----------------------------------|---|---alloc---X---X-----------@---@---------------------------------------------------------@---------------------------------------------------------------@-------------------X-----------@---@---------------------------------------------------------@---------------------------------------------------------------@-------------------Mxc---|---cxM---release---|---alloc---X---X-----------@---@---------------------------------------------------------@---------------------------------------------------------------@-------------------X-----------@---@---------------------------------------------------------@---------------------------------------------------------------@-------------------Mxc---|---cxM---release----------------------------------------------------------- | | | | | | | | | | | | | | | | | | | | | | | _lookup_prefix_2: -----------------------------------|---|-----------|-------alloc---X---X-----------@---@-------@-------------@-------------------X-----------@---@-------@-------------@-------------------Mxc---|---cxM---release-------alloc---X---X-----------@---@-------@-------------@-------------------X-----------@---@-------@-------------@-------------------Mxc---|---cxM---release---------|-------------------|-----------|-------alloc---X---X-----------@---@-------@-------------@-------------------X-----------@---@-------@-------------@-------------------Mxc---|---cxM---release-------alloc---X---X-----------@---@-------@-------------@-------------------X-----------@---@-------@-------------@-------------------Mxc---|---cxM---release---------|--------------------------------------------------------------------------- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | _lookup_prefix_3: -----------------------------------|---|-----------|---------------|-------alloc---X---X---@---X---@---Mxc---|---cxM---release-------alloc---X---X---@---X---@---Mxc---|---cxM---release---------|-------------------------------|-------alloc---X---X---@---X---@---Mxc---|---cxM---release-------alloc---X---X---@---X---@---Mxc---|---cxM---release---------|-------------------------|-------------------|-----------|---------------|-------alloc---X---X---@---X---@---Mxc---|---cxM---release-------alloc---X---X---@---X---@---Mxc---|---cxM---release---------|-------------------------------|-------alloc---X---X---@---X---@---Mxc---|---cxM---release-------alloc---X---X---@---X---@---Mxc---|---cxM---release---------|-------------------------|--------------------------------------------------------------------------- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | addr[0]: ------------alloc---------------------------|---|-----------|---------------|---------------@-------|-------|---------Z-------------------------------@-------|-------|---------Z-------------------------|-------------------------------|---------------@-------|-------|---------Z-------------------------------@-------|-------|---------Z-------------------------|-------------------------|-------------------|-----------|---------------|---------------@-------|-------|---------Z-------------------------------@-------|-------|---------Z-------------------------|-------------------------------|---------------@-------|-------|---------Z-------------------------------@-------|-------|---------Z-------------------------|-------------------------|-----------------------------------------------------------------release--- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | addr[1]: ------------alloc---------------------------|---|-----------|---------------@-----------------------|-------|-------------------------------------------------|-------|-----------------------------------Z-------------------------------@-----------------------|-------|-------------------------------------------------|-------|-----------------------------------Z-------------------------|-------------------|-----------|---------------@-----------------------|-------|-------------------------------------------------|-------|-----------------------------------Z-------------------------------@-----------------------|-------|-------------------------------------------------|-------|-----------------------------------Z-------------------------|-----------------------------------------------------------------release--- | | | | | | | | | | | | | | | | | | | | | | | | | addr[2]: ------------alloc---------------------------|---|-----------@---------------------------------------|-------|-------------------------------------------------|-------|-------------------------------------------------------------------------------------------|-------|-------------------------------------------------|-------|-------------------------------------------------------------Z-------------------|-----------@---------------------------------------|-------|-------------------------------------------------|-------|-------------------------------------------------------------------------------------------|-------|-------------------------------------------------|-------|-------------------------------------------------------------Z-----------------------------------------------------------------release--- | | | | | | | | | | | | | | | | | | | | | addr[3]: ------------alloc---------------------------@---|---------------------------------------------------|-------|-------------------------------------------------|-------|-------------------------------------------------------------------------------------------|-------|-------------------------------------------------|-------|---------------------------------------------------------------------------------|---------------------------------------------------|-------|-------------------------------------------------|-------|-------------------------------------------------------------------------------------------|-------|-------------------------------------------------|-------|---------------------------------------------------------------------------------------Z---------------------------------------release--- | | | | | | | | | | | | | | | | | | | | cnt: --------------------------------alloc-----------@---@---------------------------------------------------|-------|-------------------------------------------------|-------|-------------------------------------------------------------------------------------------|-------|-------------------------------------------------|-------|---------------------------------------------------------------------------------@---------------------------------------------------|-------|-------------------------------------------------|-------|-------------------------------------------------------------------------------------------|-------|-------------------------------------------------|-------|---------------------------------------------------------------------------------------@-------------------release----------------------- | | | | | | | | | | | | | | | | out[0]: ---------------------alloc---------------------------------------------------------------------------X-------|-------------------------------------------------X-------|-------------------------------------------------------------------------------------------X-------|-------------------------------------------------X-------|-------------------------------------------------------------------------------------------------------------------------------------X-------|-------------------------------------------------X-------|-------------------------------------------------------------------------------------------X-------|-------------------------------------------------X-------|---------------------------------------------------------------------------------------------------------------------release------------- | | | | | | | | | | | | | | | | | out[1]: ---------------------alloc-----------------------------------------------------------------------------------X-------------------------------------------------X-------|-------------------------------------------------------------------------------------------|-------X-------------------------------------------------X-------|-------------------------------------------------------------------------------------------------------------------------------------|-------X-------------------------------------------------X-------|-------------------------------------------------------------------------------------------|-------X-------------------------------------------------X-------|---------------------------------------------------------------------------------------------------------------------release------------- | | | | | | | | | | | | | | | out[2]: ---------------------alloc---------------------------------------------------------------------------------------------------------------------------------------------X-------------------------------------------------------------------------------------------X-------X-------------------------------------------------X-------|-------------------------------------------------------------------------------------------------------------------------------------|-------|-------------------------------------------------|-------X-------------------------------------------------------------------------------------------X-------X-------------------------------------------------X-------|---------------------------------------------------------------------------------------------------------------------release------------- | | | | | | | | | | | out[3]: ---------------------alloc-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------X-------------------------------------------------------------------------------------------------------------------------------------X-------X-------------------------------------------------X-------X-------------------------------------------------------------------------------------------X-------X-------------------------------------------------X-------|---------------------------------------------------------------------------------------------------------------------release------------- | | | out[4]: ---------------------alloc---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------X---------------------------------------------------------------------------------------------------------------------release------------- | | out[5]: ---------------------alloc-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------release------------- | | out[6]: ---------------------alloc-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------release------------- | | out[7]: ---------------------alloc-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------release------------- """, use_unicode_characters=False)
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 test_xor_unary_circuit(): with qp.Sim(phase_fixup_bias=True): b = qp.qalloc(len=3, name='b') u = qp.qalloc(len=8, name='u') c = qp.qalloc(name='_c') with qp.LogCirqCircuit() as circuit: u ^= (1 << b) & qp.controlled_by(c) cirq.testing.assert_has_diagram(circuit, r""" _c: -------------------------@---@-------------------------------------------------------------------------------------------------------------------------------------------------------------@-------------------------------------------------------------------------------------------------------------------------------------------------------------------@------------------- | | | | _lookup_prefix: -----alloc---X---X-----------@---@---------------------------------------------------------@---------------------------------------------------------------@-------------------X-----------@---@---------------------------------------------------------@---------------------------------------------------------------@-------------------Mxc---|---cxM---release--- | | | | | | | | | | _lookup_prefix_1: -----------|-------alloc---X---X-----------@---@-------@-------------@-------------------X-----------@---@-------@-------------@-------------------Mxc---|---cxM---release-------alloc---X---X-----------@---@-------@-------------@-------------------X-----------@---@-------@-------------@-------------------Mxc---|---cxM---release---------|------------------- | | | | | | | | | | | | | | | | | | | | | | _lookup_prefix_2: -----------|---------------|-------alloc---X---X---@---X---@---Mxc---|---cxM---release-------alloc---X---X---@---X---@---Mxc---|---cxM---release---------|-------------------------------|-------alloc---X---X---@---X---@---Mxc---|---cxM---release-------alloc---X---X---@---X---@---Mxc---|---cxM---release---------|-------------------------|------------------- | | | | | | | | | | | | | | | | | | | | | | b[0]: -----------------------|---------------|---------------@-------|-------|---------Z-------------------------------@-------|-------|---------Z-------------------------|-------------------------------|---------------@-------|-------|---------Z-------------------------------@-------|-------|---------Z-------------------------|-------------------------|------------------- | | | | | | | | | | | | | | b[1]: -----------------------|---------------@-----------------------|-------|-------------------------------------------------|-------|-----------------------------------Z-------------------------------@-----------------------|-------|-------------------------------------------------|-------|-----------------------------------Z-------------------------|------------------- | | | | | | | | | | b[2]: -----------------------@---------------------------------------|-------|-------------------------------------------------|-------|-------------------------------------------------------------------------------------------|-------|-------------------------------------------------|-------|-------------------------------------------------------------Z------------------- | | | | | | | | u[0]: ---------------------------------------------------------------X-------|-------------------------------------------------|-------|-------------------------------------------------------------------------------------------|-------|-------------------------------------------------|-------|--------------------------------------------------------------------------------- | | | | | | | u[1]: -----------------------------------------------------------------------X-------------------------------------------------|-------|-------------------------------------------------------------------------------------------|-------|-------------------------------------------------|-------|--------------------------------------------------------------------------------- | | | | | | u[2]: -------------------------------------------------------------------------------------------------------------------------X-------|-------------------------------------------------------------------------------------------|-------|-------------------------------------------------|-------|--------------------------------------------------------------------------------- | | | | | u[3]: ---------------------------------------------------------------------------------------------------------------------------------X-------------------------------------------------------------------------------------------|-------|-------------------------------------------------|-------|--------------------------------------------------------------------------------- | | | | u[4]: -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------X-------|-------------------------------------------------|-------|--------------------------------------------------------------------------------- | | | u[5]: -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------X-------------------------------------------------|-------|--------------------------------------------------------------------------------- | | u[6]: ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------X-------|--------------------------------------------------------------------------------- | u[7]: -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------X--------------------------------------------------------------------------------- """, use_unicode_characters=False)
def test_redundant_lookup(): with qp.Sim(phase_fixup_bias=True, enforce_release_at_zero=False): with qp.LogCirqCircuit() as circuit: with qp.qalloc(len=4, name='addr') as addr: with qp.qalloc(len=8, name='out') as out: with qp.qalloc(name='cnt') as cnt: out ^= qp.LookupTable( [3] * 16)[addr] & qp.controlled_by(cnt) cirq.testing.assert_has_diagram(circuit, r""" addr[0]: ---alloc-------------------------------------------release--- | | addr[1]: ---alloc-------------------------------------------release--- | | addr[2]: ---alloc-------------------------------------------release--- | | addr[3]: ---alloc-------------------------------------------release--- cnt: -----------------------alloc---@---release----------------------- | out[0]: ------------alloc-----------X-------------release------------- | | | out[1]: ------------alloc-----------X-------------release------------- | | out[2]: ------------alloc-------------------------release------------- | | out[3]: ------------alloc-------------------------release------------- | | out[4]: ------------alloc-------------------------release------------- | | out[5]: ------------alloc-------------------------release------------- | | out[6]: ------------alloc-------------------------release------------- | | out[7]: ------------alloc-------------------------release------------- """, use_unicode_characters=False)
def do_plus_mod(control: 'qp.Qubit.Control' = True, *, lvalue: qp.Quint, offset: qp.Quint.Borrowed, modulus: int, forward: bool = True): assert isinstance(lvalue, qp.Quint) assert modulus > 0 n = (modulus - 1).bit_length() assert len(offset) <= len(lvalue) assert len(lvalue) >= n if not modulus & (modulus - 1): if forward: lvalue[:n] += offset & qp.controlled_by(control) else: lvalue[:n] -= offset & qp.controlled_by(control) return with offset.hold_padded_to(n) as offset: with qp.qalloc(name='mod_cmp') as q: if forward: offset ^= -1 offset += modulus + 1 q.init(lvalue >= offset, controls=control) offset -= modulus + 1 offset ^= -1 lvalue += offset & qp.controlled_by(control) lvalue -= modulus & qp.controlled_by(q & control) q.clear(lvalue < offset, controls=control) else: q.init(lvalue < offset, controls=control) lvalue += modulus & qp.controlled_by(q & control) lvalue -= offset & qp.controlled_by(control) offset ^= -1 offset += modulus + 1 q.clear(lvalue >= offset, controls=control) offset -= modulus + 1 offset ^= -1
def f(c: qp.Qubit, t: qp.Quint): t ^= 1 & qp.controlled_by(c)
def test_ixor(): q = qp.Quint(qp.NamedQureg('test', 10)) with pytest.raises(TypeError): q ^= None with qp.LogCirqCircuit() as circuit: q ^= 5 cirq.testing.assert_has_diagram(circuit, """ test[0]: ---X--- | test[2]: ---X--- """, use_unicode_characters=False) q2 = qp.Quint(qp.NamedQureg('test2', 5)) with qp.LogCirqCircuit() as circuit: q ^= q2 cirq.testing.assert_has_diagram(circuit, """ test2[0]: ---@------------------- | test2[1]: ---|---@--------------- | | test2[2]: ---|---|---@----------- | | | test2[3]: ---|---|---|---@------- | | | | test2[4]: ---|---|---|---|---@--- | | | | | test[0]: ----X---|---|---|---|--- | | | | test[1]: --------X---|---|---|--- | | | test[2]: ------------X---|---|--- | | test[3]: ----------------X---|--- | test[4]: --------------------X--- """, use_unicode_characters=False) q3 = qp.Quint(qp.NamedQureg('test3', 5)) c = qp.Qubit('c') with qp.LogCirqCircuit() as circuit: q ^= q3 & qp.controlled_by(c) cirq.testing.assert_has_diagram(circuit, """ c: ----------@---@---@---@---@--- | | | | | test3[0]: ---@---|---|---|---|--- | | | | | test3[1]: ---|---@---|---|---|--- | | | | | test3[2]: ---|---|---@---|---|--- | | | | | test3[3]: ---|---|---|---@---|--- | | | | | test3[4]: ---|---|---|---|---@--- | | | | | test[0]: ----X---|---|---|---|--- | | | | test[1]: --------X---|---|---|--- | | | test[2]: ------------X---|---|--- | | test[3]: ----------------X---|--- | test[4]: --------------------X--- """, use_unicode_characters=False) # Classes can specify custom behavior via __rixor__. class Rixor: def __rixor__(self, other): qp.phase_flip() return other with qp.capture() as out: q ^= Rixor() assert out == [('phase_flip', qp.QubitIntersection.ALWAYS)]
def init_storage_location(self, location: 'qp.Quint', controls: 'qp.QubitIntersection'): location ^= self.val & qp.controlled_by(controls)