Ejemplo n.º 1
0
def compute_max_cut(n: int, nodes: List[int]) -> int:
    """Compute (inefficiently) the max cut, exhaustively."""

    max_cut = -1000
    for bits in helper.bitprod(n):
        # Collect in/out sets.
        iset = []
        oset = []
        for idx, val in enumerate(bits):
            iset.append(idx) if val == 0 else oset.append(idx)

        # Compute costs for this cut, record maximum.
        cut = 0
        for node in nodes:
            if node[0] in iset and node[1] in oset:
                cut += node[2]
            if node[1] in iset and node[0] in oset:
                cut += node[2]
        if cut > max_cut:
            max_cut_in, max_cut_out = iset.copy(), oset.copy()
            max_cut = cut
            max_bits = bits

    state = bin(helper.bits2val(max_bits))[2:].zfill(n)
    print('Max Cut. N: {}, Max: {:.1f}, {}-{}, |{}>'
          .format(n, np.real(max_cut), max_cut_in, max_cut_out,
                  state))
    return helper.bits2val(max_bits)
Ejemplo n.º 2
0
def simple_walk():
  """Simple quantum walk, allowing initial experiments."""

  nbits = 8
  qc = circuit.qc('simple_walk')
  x = qc.reg(nbits, 0b10000000)
  aux = qc.reg(nbits, 0)
  coin = qc.reg(1, 0)

  for _ in range(32):
    # Using a Hadamard coin, others are possible, of course.
    qc.h(coin[0])
    incr(qc, 0, nbits, aux, [coin[0]])
    decr(qc, 0, nbits, aux, [[coin[0]]])

  # Find and print the non-zero amplitudes for all states
  for bits in helper.bitprod(nbits):
    idx_bits = bits
    for i in range(nbits):
        idx_bits = idx_bits + (0,)
    idx_bits0 = idx_bits + (0,)
    idx_bits1 = idx_bits + (1,)

    # Printing bits0 only, this can be changed, of course.
    if qc.psi.ampl(*idx_bits0) != 0.0:
      print('{:5.1f} {:5.4f}'.format(float(helper.bits2val(bits)),
                                     qc.psi.ampl(*idx_bits0).real))
Ejemplo n.º 3
0
def check_result(psi, a, b, nbits, factor=1.0):
    """Find most likely result, dump it, compare against expected."""

    maxbits, _ = psi.maxprob()
    result = helper.bits2val(maxbits[0:nbits][::-1])
    if result != a + factor * b:
        print(f'{a} + ({factor} * {b}) = {result}')
        raise AssertionError('incorrect addition')
Ejemplo n.º 4
0
def main(argv):
    if len(argv) > 1:
        raise app.UsageError('Too many command-line arguments.')
    print('Order finding.')

    number = flags.FLAGS.N
    a = flags.FLAGS.a

    # The classical part are handled in 'shor_classic.py'
    nbits = number.bit_length()
    print('Shor: N = {}, a = {}, n = {} -> qubits: {}'.format(
        number, a, nbits, nbits * 4 + 2))
    qc = circuit.qc('order_finding')

    # Aux register for additional and multiplication.
    aux = qc.reg(nbits + 2, name='q0')

    # Register for QFT. This reg will hold the resulting x-value.
    up = qc.reg(nbits * 2, name='q1')

    # Register for multiplications.
    down = qc.reg(nbits, name='q2')

    qc.h(up)
    qc.x(down[0])
    for i in range(nbits * 2):
        cmultmodn(qc, up[i], down, aux, int(a**(2**i)), number, nbits)
    inverse_qft(qc, up, 2 * nbits, with_swaps=1)

    qc.dump_to_file()

    print('Measurement...')
    total_prob = 0.0
    for bits in helper.bitprod(nbits * 4 + 2):
        prob = qc.psi.prob(*bits)
        if prob > 0.01:
            intval = helper.bits2val(bits[nbits + 2:nbits + 2 +
                                          nbits * 2][::-1])
            phase = helper.bits2frac(bits[nbits + 2:nbits + 2 +
                                          nbits * 2][::-1])

            r = fractions.Fraction(phase).limit_denominator(8).denominator
            guesses = [
                math.gcd(a**(r // 2) - 1, number),
                math.gcd(a**(r // 2) + 1, number)
            ]

            print(
                'Final x: {:3d} phase: {:3f} prob: {:.3f} factors: {}'.format(
                    intval, phase, prob.real, guesses))

            total_prob += qc.psi.prob(*bits)
            if total_prob > 0.999:
                break

    print(qc.stats())
Ejemplo n.º 5
0
Archivo: state.py Proyecto: qcc4cp/qcc
def bitstring(*bits) -> State:
    """Produce a state from a given bit sequence, eg., |0101>."""

    d = len(bits)
    if d == 0:
        raise ValueError('Rank must be at least 1.')
    for _, val in enumerate(bits):
        if val != 0 and val != 1:
            raise ValueError(f'Bits must be 0 or 1, got: {val}')
    t = np.zeros(1 << d, dtype=tensor.tensor_type())
    t[helper.bits2val(bits)] = 1
    return State(t)
Ejemplo n.º 6
0
def check_result(psi: state.State,
                 a,
                 b,
                 nbits: int,
                 factor: float = 1.0) -> None:
    """Find most likely result, dump it, compare against expected."""

    maxbits, _ = psi.maxprob()
    result = helper.bits2val(maxbits[0:nbits][::-1])
    if result != a + factor * b:
        print(f'{a} + ({factor} * {b}) != {result}')
        raise AssertionError('Incorrect addition.')
Ejemplo n.º 7
0
def experiment_decr():
  """Run a few decr experiments."""
  qc = circuit.qc('decr')
  x = qc.reg(4, 15)
  aux = qc.reg(4)

  for val in range(15, 0, -1):
    decr(qc, 0, 4, aux)

    maxbits, _ = qc.psi.maxprob()
    res = helper.bits2val(maxbits[0:4])
    if val-1 != res:
      raise AssertionError('Invalid Result')
Ejemplo n.º 8
0
def experiment_mod_9():
  """Run a few incr-mod-9 experiments."""

  qc = circuit.qc('incr')
  x = qc.reg(4, 0)
  aux = qc.reg(5)  # extra aux

  for val in range(18):
    incr_mod_9(qc, aux)
    maxbits, _ = qc.psi.maxprob()
    res = helper.bits2val(maxbits[0:4])
    if ((val+1) % 9) != res:
      raise AssertionError('Invalid Result')
Ejemplo n.º 9
0
def Permutation(nbits, f):
    """Compute a permutation from function f."""

    dim = 2**nbits
    perm = []
    for row in range(dim):
        bits = helper.val2bits(row, nbits)
        fx = f(bits[0:-1])
        xor = bits[-1] ^ fx
        new_bits = bits[0:-1]
        new_bits.append(xor)

        # Construct new column (int) from the new bit sequence.
        new_col = helper.bits2val(new_bits)
        perm.append(new_col)
    return perm
Ejemplo n.º 10
0
def arith_quantum_constant(n, init_a, c):
    """Run a quantum add-constant experiment."""

    qc = circuit.qc('qadd')
    a = qc.reg(n + 1, helper.val2bits(init_a, n)[::-1], name='a')
    for i in range(0, n + 1):
        qft(qc, a, n - i)

    angles = precompute_angles(c, n)
    for i in range(0, n):
        qc.u1(a[i], angles[i])

    for i in range(0, n + 1):
        inverse_qft(qc, a, i)

    maxbits, _ = qc.psi.maxprob()
    result = helper.bits2val(maxbits[0:n][::-1])
    if result != init_a + c:
        print(f'{init_a} + {c} = {result}')
        raise AssertionError('incorrect addition')
Ejemplo n.º 11
0
def OracleUf(nbits, f):
    """Make an n-qubit Oracle for function f (eg. Deutsch, Grover)."""

    # This Oracle is constructed similar to the implementation in
    # ./deutsch.py, just with an n-bit |x> and a 1-bit |y>
    #
    dim = 2**nbits
    u = np.zeros(dim**2).reshape(dim, dim)
    for row in range(dim):
        bits = helper.val2bits(row, nbits)
        fx = f(bits[0:-1])  # f(x) without the y.
        xor = bits[-1] ^ fx

        new_bits = bits[0:-1]
        new_bits.append(xor)

        # Construct new column (int) from the new bit sequence.
        new_col = helper.bits2val(new_bits)
        u[row][new_col] = 1.0

    op = Operator(u)
    if not op.is_unitary():
        raise AssertionError('constructed non-unitary operators.')
    return op
Ejemplo n.º 12
0
Archivo: grover.py Proyecto: qcc4cp/qcc
 def func(*bits):
   return answers[helper.bits2val(*bits)]
Ejemplo n.º 13
0
Archivo: state.py Proyecto: qcc4cp/qcc
    def ampl(self, *bits) -> np.complexfloating:
        """Return amplitude for state indexed by 'bits'."""

        idx = helper.bits2val(bits)
        return self[idx]
Ejemplo n.º 14
0
    def test_bits_converstions(self):
        bits = helper.val2bits(6, 3)
        self.assertEqual(bits, [1, 1, 0])

        val = helper.bits2val(bits)
        self.assertEqual(val, 6)
Ejemplo n.º 15
0
    def f(*bit_string):
        """Return f(bits) for one of the 2 possible function types."""

        # pylint: disable=no-value-for-parameter
        idx = helper.bits2val(*bit_string)
        return bits[idx]