def test_uncompute(): for a, b, p in itertools.product([False, True], repeat=3): with qp.Sim(phase_fixup_bias=p): with qp.hold(a, name='a') as qa: with qp.hold(b, name='b') as qb: with qp.hold(a & b, name='c') as qc: assert qp.measure(qa) == a assert qp.measure(qb) == b assert qp.measure(qc) == (a and b)
def test_neq(): with qp.Sim(): with qp.qalloc(len=4) as t: t.init(5) for k in range(-2, 60): with qp.hold(t != k) as q: assert qp.measure(q) == (k != 5) assert qp.measure(t, reset=True) == 5
def test_sim(): v1 = 15 v2 = 235 offset = 4 bits = 10 with qp.Sim(): with qp.hold(val=v1, name='a') as a: with qp.qalloc(len=bits, name='out') as out: out += a * v2 out += offset result = qp.measure(out, reset=True) assert result == (v1*v2 + offset) & ((1 << bits) - 1)
def test_integration(exp_len: int, modulus_len: int, emulate_additions: bool): with qp.Sim(emulate_additions=emulate_additions): exponent = random.randint(0, 1 << exp_len) modulus = random.randint(0, 1 << modulus_len) * 2 + 1 base = 0 while math.gcd(base, modulus) != 1 or base >= modulus: base = random.randint(0, 1 << modulus_len) * 2 + 1 with qp.hold(exponent) as exp: actual = measure_pow_mod(base=base, exponent=exp, modulus=modulus) expected = pow(base, exponent, modulus) assert actual == expected
def test_count(): v1 = 15 v2 = 235 offset = 4 bits = 100 with qp.Sim(): with qp.CountNots() as counts: with qp.hold(val=v1, name='a') as a: with qp.qalloc(len=bits, name='out') as out: out += a * v2 out += offset _ = qp.measure(out, reset=True) assert len(counts.keys()) == 3 assert counts[0] > 0 assert counts[1] > 0 assert 0 < counts[2] <= 1000
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_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 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_eq_circuit(): with qp.Sim(enforce_release_at_zero=False, phase_fixup_bias=True): with qp.LogCirqCircuit() as circuit: with qp.qalloc(len=4, name='lhs') as lhs: with qp.hold(lhs == 5, name='target'): pass cirq.testing.assert_has_diagram(circuit, r""" lhs[0]: ---alloc---------------@-----------------@-----------------------release--- | | | | lhs[1]: ---alloc-----------X---@---X---------X---@---X-------------------release--- | | | | | | | | lhs[2]: ---alloc-----------|---@---|---------|---@---|-------------------release--- | | | | | | | | lhs[3]: ---alloc-----------X---@---X---------X---Z---X-------------------release--- | target: -----------alloc-------X-------Mxc---------------cxM---release------------- """, use_unicode_characters=False)
def measure(val: Union[qp.RValue[T], qp.Quint, qp.Qureg, qp.Qubit], *, reset: bool = False) -> Union[bool, int, List[bool], T]: if isinstance(val, qp.RValue): with qp.hold(val) as target: return measure(target) if isinstance(val, qp.Qubit): qureg = val.qureg wrap = bool elif isinstance(val, qp.Qureg): qureg = val wrap = lambda e: qp.little_endian_bits(e, len(val)) elif isinstance(val, (qp.Quint, qp.QuintMod)): qureg = val.qureg wrap = lambda e: e else: raise NotImplementedError(f"Don't know how to measure {val!r}.") result = sink.global_sink.do_measure(qureg, reset) return wrap(result)
def test_del_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(name='cnt'): with qp.hold(qp.LookupTable(range(1, 17))[addr], name='out'): circuit[:] = [] 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---------------------------------------------------------------------------------------------------------------------------------------------- | | | | | | | | | | | | | | addr[0]: ----------------------@-------------------------------|---------------|-------|---|---|-------|---|---------|-------------------------------|-------|-------|---|---|---------|-----------------------------------------------------------------------------------------------Z----------------------------------------------------release--- | | | | | | | | | | | | | | | | | addr[1]: ----------------------|-------@-------@---------------|---------------|-------|---|---|-------|---|---------|-------------------------------|-------|-------|---|---|---------|-------------------------------------------------------Z-------------------Z-------------------|----------------------------------------------------release--- | | | | | | | | | | | | | | | | | | | | | addr[2]: ----------------------|-------|-------|---------------|---------------@-------|---|---|-------|---|---------Z-------------------------------@-------|-------|---|---|---------Z-------------------------------------------------------|-------------------|-------------------|----------------------------------------------------release--- | | | | | | | | | | | | | | | | | addr[3]: ----------------------|-------|-------|---------------@-----------------------|---|---|-------|---|-------------------------------------------------|-------|---|---|-----------------------------------Z-----------------------------|-------------------|-------------------|----------------------------------------------------release--- | | | | | | | | | | | | | | | cnt: --------------------------|-------|-------|---------------------------------------|---|---|-------|---|-------------------------------------------------|-------|---|---|-----------------------------------------------------------------|-------------------|-------------------|------------------------------------------release------------- | | | | | | | | | | | | | | | out[0]: -------------Mxc---X---@---X---@---X---|---------------------------------------Z---|---|-------|---|-------------------------------------------------|-------Z---|---|-----------------------------------------------------------------|---------X---------@---------X---------@---------Mxc--------cxM---cxM---release----------------------- | | | | | | | | | | | | | | | | | | out[1]: -------------Mxc-------X---@---|---|---@---X---------------------------------------Z---|-------|---|-------------------------------------------------|-----------Z---|-------------------------------------------------------X---------@---------|-------------------@---Mxc-------cxM--------------------cxM---release----------------------- | | | | | | | | | | | | | | out[2]: -------------Mxc---------------X---@---|---|-------------------------------------------|-------Z---|-------------------------------------------------Z---------------|-------------------------------------------------------|-------------------@---Mxc-------cxM----------------------------------------cxM---release----------------------- | | | | | | | | | out[3]: -------------Mxc-----------------------X---@-------------------------------------------Z-----------Z-----------------------------------------------------------------Z-------------------------------------------------------@---Mxc-------cxM------------------------------------------------------------cxM---release----------------------- | | | out[4]: -------------Mxc------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------cxM---release----------------------- global phase: pi """, use_unicode_characters=False)