예제 #1
0
    def test_measure(self):
        # First, test measurement of a system in a pure state
        STATE = '01010'
        N = len(STATE)
        q = QubitSystem(N, int('0b' + STATE, 2))
        self.assertEqual(q.measure(), int('0b' + STATE, 2))
        self.assertEqual(q.smeasure(), STATE)
        for i in range(N):
            self.assertEqual(q.measure(i + 1), int(STATE[i]))

        # Test probabilistic measurement: repeatedly measure superpositions of
        # basis states and test that the outcome varies randomly.
        N = 2
        NTRIALS = 100
        # number of 1's in the first and second bit, respectively
        nsuccess1 = 0
        nsuccess2 = 0
        for i in range(NTRIALS):
            q = QubitSystem(N) # set the qubits to |00>
            hadamard_gate(N) * q # equal superposition of four basis states
            nsuccess1 += q.measure(1)
            nsuccess2 += q.measure(2)
        # Test that repeated measurement gives the same result
        state = q.measure()
        self.assertEqual(q.measure(), state)
        self.assertEqual(q.measure(), state)
        # Test that the number of 1's that appeared in the first and second
        # qubits is approximately half the total (within approx. 99% confidence
        # interval)
        CUTOFF = NTRIALS * 0.15
        self.assertTrue(abs(nsuccess1 - NTRIALS / 2.) < CUTOFF)
        self.assertTrue(abs(nsuccess2 - NTRIALS / 2.) < CUTOFF)
예제 #2
0
    def test_qft(self):
        N = 4
        q = QubitSystem(N)
        # put q into a non-uniform mixed state
        hadamard_gate(N) * q
        tensor_power(phase_shift_gate(pi), N) * q

        # classical FFT of coefficients, normalized to be unitary like the QFT
        yhat = fft(q._QubitSystem__coeffs) / sqrt(2 ** N)
        qft(q)
        self.assertTrue(numpy.max(numpy.abs(q._QubitSystem__coeffs - yhat)) < EPS)
예제 #3
0
def grover_invert(f, y, n):
    """Grover's algorithm for inverting a general function f that maps a
    sequence of n bits (represented as an int whose binary representation is the
    bit sequence) to another sequence of bits.

    Args:
      f: Function to invert
      y: Value of the function at which to evaluate the inverse.

    Returns:
      The input x such that f(x) = y. If more than one input suffices, it
        returns one at random. If no input suffices, returns -1.
    """
    if n <= 0:
        raise ValueError('n must be positive')

    Hn = hadamard_gate(n)
    Ui = _function_oracle(f, y, n)
    Ud = grover_diffusion_operator(n)

    MAX_ITER = 50
    count = 0
    x = None
    # Repeat until a solution is found or the iteration limit is reached
    while count < MAX_ITER and (x is None or f(x) != y):
        q = QubitSystem(n) # system of n bits in state |0>
        # apply Hadamard gate to create uniform superposition of basis states
        Hn * q

        for _ in range(_r(2**n)):
            Ui * q # apply operator that flips the sign of the matching index
            Ud * q # apply Grover's diffusion operator
        x = q.measure()
        count += 1
    return x if f(x) == y else -1
예제 #4
0
def shor_factor(n):
    """Shor's factorization algorithm.

    Args:
      n: Integer >=2 to factor.

    Returns:
      If n is composite, a non-trivial factor of n. If n is prime, returns 1.

    Raises:
      ValueError if n is <= 1.
    """
    if n <= 1:
        raise ValueError('n must be at least 2')
    if is_prime(n):
        return 1
    if n % 2 == 0:
        return 2 # even numbers > 2 are trivial

    # Need to check that n is not a power of an integer for algorithm to work
    root = int_root(n)
    if root != -1:
        return root

    # choose m s.t. n^2 <= 2^m < 2*n^2
    # log2(n^2) <= m <= log2(2 * n^2) = 1 + log2(n^2)
    m = ceil(log(n**2, 2))

    ny = ceil(log(n - 1, 2)) # number of qubits in output of function f
    I = QuantumGate(eye(2**ny))
    H = kron(hadamard_gate(m), I)

    MAX_ITER = 10
    niter = 0
    while True:
        a = n - 1 # arbitrary integer coprime to n

        # Initialize a system of qubits long enough to represent the integers 0
        # to 2^m - 1 alongside an integer up to n - 1, then apply Hadamard gate
        # to the first m qubits to create a uniform superposition.
        q = QubitSystem(m + ny)
        H * q

        # Apply the function f(x) = a^x (mod n) to the system
        f = lambda x: pow(a, x, n)
        Uf = function_gate(f, m, ny)
        Uf * q

        # Find the period of f via quantum Fourier transform
        qft(q)
        r = 1. / q.measure() # period = 1 / frequency

        niter += 1
        if niter >= MAX_ITER or (r % 2 == 0 and (a**(r / 2)) % n != -1):
            break
    return gcd(a**(r / 2) + 1, n)
예제 #5
0
 def test_hadamard_gate(self):
     N = 3
     # Matrix with 1's for all positive entries of three-qubit Hadamard gate
     is_pos = array([[1, 1, 1, 1, 1, 1, 1, 1],
                   [1, 0, 1, 0, 1, 0, 1, 0],
                   [1, 1, 0, 0, 1, 1, 0, 0],
                   [1, 0, 0, 1, 1, 0, 0, 1],
                   [1, 1, 1, 1, 0, 0, 0, 0],
                   [1, 0, 1, 0, 0, 1, 0, 1],
                   [1, 1, 0, 0, 0, 0, 1, 1],
                   [1, 0, 0, 1, 0, 1, 1, 0]])
     H = hadamard_gate(N)
     ENTRY_VAL = 2.**(-N / 2.) # abs val of each entry
     H_exp = ENTRY_VAL * (2 * is_pos - 1) # expected H
     self.assertTrue((abs(H.matrix() - H_exp) < EPS).all())
예제 #6
0
def grover_search(match_text, lst):
    """Grover's quantum algorithm for searching.

    Args:
      match_text: Text to find in the list lst.
      lst: List of strings to search to find a string matching match_text.

    Returns:
      The index i of the item such that lst[i] is the same string as
        match_text. The lines must match exactly; it is not enough for the text
        to be contained in the line. If two or more lines match, it will only
        return one of the line numbers. Returns -1 if no matching line is found,
        i.e. the algorithm fails to find a solution.
    """
    if len(lst) <= 0:
        raise ValueError('List must be of positive length')

    n = len(lst)
    N = int(ceil(log(n, 2))) # number of qubits needed
    Hn = hadamard_gate(N)
    Ui = _search_oracle(match_text, lst)
    Ud = grover_diffusion_operator(N)

    MAX_ITER = 50
    count = 0
    index = n
    # Repeat until a solution is found or the iteration limit is reached
    while count < MAX_ITER and (index >= n or lst[index] != match_text):
        q = QubitSystem(N) # system of log2(n) bits in state |0>
        # apply Hadamard gate to create uniform superposition of basis states
        Hn * q

        for _ in range(_r(2**N)):
            Ui * q # apply operator that flips the sign of the matching index
            Ud * q # apply Grover's diffusion operator
        index = q.measure()
        count += 1
    return index if index < n and lst[index] == match_text else -1