Ejemplo n.º 1
0
def superposition(repeat_count, basis_measurement):
    """Creates a superposition and measures it using a specified basis a specified number of times.

    Args:
        repeat_count (int): The number of times to repeat the quantum program.
        basis_measurement (function): The function to perform the specified basis measurement with.

    Returns:
        int: The measurement count where the result is 1.
    """
    program = Program()
    program += H(0)
    basis_measurement(program, 0)

    with local_forest_runtime():
        # Initialise simulator and run circuit a specified number of times.
        quantum_virtual_machine = get_qc('9q-square-qvm')
        qubit_result_counts = quantum_virtual_machine.run_and_measure(
            program, trials=repeat_count)

        # Loop through results and update count if result is 1.
        ones_count = 0
        for result in qubit_result_counts[0]:
            if result == 1:
                ones_count += 1

        return ones_count
Ejemplo n.º 2
0
def generate_random_number():
    """Generates a random number between 0-15.

    Returns:
        int: A random number between 0-15.
    """
    # Initialise program.
    # Apply Hadamard gate to 4 qubits.
    program = Program()
    for qubit in range(4):
        program += H(qubit)

    with local_forest_runtime():
        # Initialise simulator and run circuit a specified number of times.
        # Get counts of qubit measurement results, which is a single result with 1 count.
        quantum_virtual_machine = get_qc('9q-square-qvm')
        qubit_result_counts = quantum_virtual_machine.run_and_measure(program, trials=1)

        # Convert result as binary digits into bit-string.
        result_bitstring = '0b'
        for result in range(4):
            result_bitstring += str(qubit_result_counts[result][0])

        # Convert bit-string as binary digits into integer.
        random_number = int(result_bitstring, 2)
        return random_number
Ejemplo n.º 3
0
def interference(repeat_count, starting_state):
    """Creates a superposition and applies interference on a qubit in a specified state a specified number of times.

    Args:
        repeat_count (int): The number of times to repeat the quantum circuit.
        starting_state (int): The state to set the qubit to prior to running the quantum circuit.

    Returns:
        int: The measurement count where the result is 1.
    """
    # Initialise program.
    # Set qubit to desired starting state.
    # If the starting state should be 1, apply the X gate.
    program = Program()
    if starting_state == 1:
        program += X(0)
    
    # Apply Hadamard gate to create a superposition.
    program += H(0)

    # Apply Hadamard gate to cause interference to restore qubit to its starting state.
    program += H(0)

    with local_forest_runtime():
        # Initialise simulator and run circuit a specified number of times.
        quantum_virtual_machine = get_qc('9q-square-qvm')
        qubit_result_counts = quantum_virtual_machine.run_and_measure(program, trials=repeat_count)

        # Loop through results and update count if result is 1.
        ones_count = 0
        for result in qubit_result_counts[0]:
            if result == 1:
                ones_count += 1
        
        return ones_count
Ejemplo n.º 4
0
def local_qvm_quilc():
    """Execute test with local qvm and quilc running"""
    if shutil.which('qvm') is None or shutil.which('quilc') is None:
        return pytest.skip("This test requires 'qvm' and 'quilc' "
                           "executables to be installed locally.")

    with local_forest_runtime() as context:
        yield context
 def solve(self):
     with local_forest_runtime():
         qc = get_qc('9q-square-qvm')
         result = qc.run_and_measure(self.__p, trials = 1)
     a = ''
     for i in range(self.n):
         a+=str(result[i][0])
     
     return a
Ejemplo n.º 6
0
def simons_algorithm(f, n):
    """
    Inputs: f is a blackbox function (f:{0,1}^n -> {0,1}^n) that is either one-to-one or two-to-onw. n is the
    dimension of the input into f. This function finds and returns the key s, if one exists, for a two=to-one
    function by first creating a matrix U_f that represents f, then applying the appropriate quantum gates to
    generate a linear equation. By running the circuit n-1 times, we generate n-1 equations that we then feed into a
    classical solver. The Classical solver returns s.
    Returns: the key string s, if found, or the zero bitstring
    """
    # Initialize the program and apply the Hadamard gate to the first n qubits.
    program = initialize([0] * n)

    # Initialize an extra n bits by applying the Identity gate.
    for index in range(n, (2 * n)):
        program += I(index)
    # Generate the U_f gate for f
    uf_simons_gate = generate_uf_simons(f, n, "Uf_Simons")
    Uf_simons = uf_simons_gate.get_constructor()

    # Initialize qubits and apply the U_f gate to all qubits
    qubits = list(range(2 * n))
    program += uf_simons_gate
    program += Uf_simons(*qubits)

    # Pick the qubits to which to apply the final Hadamard gates.
    apply_to_list = [1] * n
    np.append(apply_to_list, [0] * n)
    program = apply_H(program, apply_to_list)

    with local_forest_runtime():
        qvm = get_qc('9q-square-qvm')
        s_trials = list()

        # Conduct 20 trials of the algorithm - it's not deterministic
        for i in range(20):

            # Run the circuit n-1 times to generate n-1 equations
            measurements = qvm.run_and_measure(program, trials=n - 1)
            Y = np.zeros((n - 1, n))

            # Parse the resulting relevant measurements from the circuit and store in a matrix
            for index in range(n):
                for j in range(len(measurements[index])):
                    Y[j][index] = measurements[index][j]

            # Plug Y into the binary matrix solver and store in a list of possible s strings (s_trials)
            s_primes = simons_solver(Y, n)
            s_trials.append(s_primes)

        # Check if each s satisfies the condition needed to be a 'key' and return it if the condition is met
        for trial in s_trials:
            if (f([0] * n) == f(trial)):
                return trial

        # If no such s is found, return the 0 bitstring to indicate s doesn not exist and the function is one-to-one
        return [0] * n
Ejemplo n.º 7
0
def test_run_and_measure(local_qvm_quilc):
    qc = get_qc("9q-generic-qvm")
    prog = Program(I(8))
    trials = 11
    # note to devs: this is included as an example in the run_and_measure docstrings
    # so if you change it here ... change it there!
    with local_forest_runtime():  # Redundant with test fixture.
        bitstrings = qc.run_and_measure(prog, trials)
    bitstring_array = np.vstack(bitstrings[q] for q in qc.qubits()).T
    assert bitstring_array.shape == (trials, len(qc.qubits()))
 def solve(self):
     with local_forest_runtime():
         qc = get_qc('9q-square-qvm')
         n_trials = 10
         result = qc.run_and_measure(self.__p, trials=self.n_trials)
     values = list()
     for j in range(self.n_trials):
         value = ''
         for i in range(self.n):
             value += str(result[i][j])
         values.append(value)
     return values
def grovers_algorithm(f, n):
    """
    This function is intended to determine if there exists an x in {0,1}^n s.t. f(x) = 1 for a given function f s.t.
        f:{0,1}^n -> {0,1}. The algorithm first constructs Zf, -Z0 gates, initializes with Hanamard matrices, and
        applies G = -H^n o Z0 o H^n o Zf. This algorithm is not deterministic, so G is applied multiple times. More
        specifically, G is run (pi / 4 * sqrt(n)) times. Furthermore, there are 10 trials to minimize the chance of a
        false negative.
    This function has an anonymous function and integer n as parameters.
    This function runs the algorithm as described for each 10 trials, and then checks if for any of the outputted states
        x, if f(x) = 1. If this is true, then 1 is returned, otherwise 0 is returned. The function returns 0 if there
        is an issue with the simulator.
    This function uses 9q-squared-qvm, so it assumes that n <= 9
    """
    # Apply Hadamards to all qubits
    program = initialize([0] * n)
    qubits = list(range(n))
    # Define and generate Z0 gate (really -Z0)
    z0_gate = get_Z0(n)
    Z0 = z0_gate.get_constructor()
    # Define and generate Zf gate
    zf_gate = get_Zf(f, n)
    Zf = zf_gate.get_constructor()
    # Determine the number of times to apply G
    iteration_count = floor(pi / 4 * sqrt(n))
    h_qubits = [1] * n
    # Apply G iteration_count times
    for i in range(iteration_count):
        # Apply Zf
        program += zf_gate
        program += Zf(*qubits)
        # Apply H to all qubits
        apply_H(program, h_qubits)
        # Apply -Z0
        program += z0_gate
        program += Z0(*qubits)
        # Apply H to all qubits
        apply_H(program, h_qubits)
    # Measure
    # Try to run simulator
    with local_forest_runtime():
        # assumes that n <= 9
        qvm = get_qc('9q-square-qvm')
        # run circuit and measure the qubits, 10 trials
        results = qvm.run_and_measure(program, trials=10)
        # Iterate through different results of the different trials and check if f(x) = 1
        for i in range(len(results)):
            new = list()
            for j in range(len(results[i])):
                new.append(results[i][j])
            if f(new) == 1: return 1
        # return 0 if simulator fails
        return 0
Ejemplo n.º 10
0
    def solve(self):
        '''
        Run and measure the quantum circuit and return the results.
        '''
        with local_forest_runtime():
            qc = get_qc('9q-square-qvm')
            qc.compiler.client.timeout = 10000
            result = qc.run_and_measure(self.__p, trials=1)
        a = ''
        for i in range(self.n):
            a += str(result[i][0])

        return a
Ejemplo n.º 11
0
 def solve(self):
     '''
     Run and measure the quantum circuit
     and return the result.
     The circuit is run for n_trials number of trials.
     '''
     with local_forest_runtime():
         qc = get_qc('9q-square-qvm')
         qc.compiler.client.timeout = 10000
         n_trials = 10
         result = qc.run_and_measure(self.__p, trials=self.n_trials)
     values = list()
     for j in range(self.n_trials):
         value = ''
         for i in range(self.n):
             value += str(result[i][j])
         values.append(value)
     return values
Ejemplo n.º 12
0
 def simulate_pyquil(self, program: Program, title: str, shots=1000):
     """ qvm -S and quilc -S must be executed to run the pyquil compiler and simulator servers
     http://docs.rigetti.com/en/stable/start.html
     """
     qubits = program.get_qubits()
     qubit_size = len(qubits)
     program.wrap_in_numshots_loop(shots)
     with local_forest_runtime():
         # create a simulator for the given qubit size that is fully sonnected
         qvm = get_qc(str(qubit_size) + 'q-qvm')
         # default timeout is not enough for some circuits like shor_general(3) --> https://github.com/rigetti/pyquil/issues/935
         qvm.compiler.client.timeout = 60
         # print(program)
         executable = qvm.compile(program)
         # print(executable.program)
         bitstrings = qvm.run(executable)
         counts = self._bitstrings_to_counts(bitstrings)
         plot_histogram(counts, title=title)
         return counts
def bernstein_vazirani_algorithm(f, n):
    """
    This function is intended to determine to find a,b s.t. f(x) = a*x + b where a*x is bitwise inner product and +
        is addition modulo 2, for a given function f s.t. f:{0,1}^n -> {0,1}. It is assumed that f can be represented as
        f(x) = a*x + b. The algorithm first calculates b by solving for f(0^n). It then initializes the qubits with H
        for the first n qubits and X and H for the last qubit. The algorithm then constructs a Uf oracle gate based on
        the function input f. It then applies Uf to all the qubits and applies H to the first n qubits. Finally, the
        simulator is run on the circuit and measures the results. The function then returns the first n measured qubits.
    This function has an anonymous function and integer n as parameters.
    This function uses 9q-squared-qvm, so it assumes that n <= 9.
    """
    initialize_list = [0] * n
    # calculate b by f(0^n) = b
    b = f(initialize_list)
    # Initialize circuit by applying H to first n qubits and X H to last qubit (ancilla qubit)
    initialize_list.append(1)
    qubits = list(range(len(initialize_list)))
    program = initialize(initialize_list)
    # Generate a Uf oracle gate based on given function f
    uf_gate = generate_uf(f, n, "Uf")
    Uf = uf_gate.get_constructor()
    # Add Uf to circuit
    program += uf_gate
    program += Uf(*qubits)
    # Apply H to all qubits except for the last qubit
    apply_to_list = [1] * n
    apply_to_list.append(0)
    program = apply_H(program, apply_to_list)
    # print(program)
    # run simulator and measure qubits
    with local_forest_runtime():
        # Assume n <= 9
        qvm = get_qc('9q-square-qvm')
        # 1 trial because DJ is deterministic
        results = qvm.run_and_measure(program, trials=1)
        # retrive measurement of first n qubits
        a = []
        for i in range(n):
            a.append(results[i][0])
        # return a,b
        return a, b
    # in case of failure, return b, None
    return b, None
Ejemplo n.º 14
0
def deutsch_jozsa_algorithm(f, n):
    """
    This function is intended to determine if f is constant or balanced for a given function f s.t.
        f:{0,1}^n -> {0,1}. The algorithm initializes the qubits with H for the first n qubits and X and H for the last
        qubit. The algorithm then constructs a Uf oracle gate based on the function input f. It then applies Uf to all
        the qubits and applies H to the first n qubits. Finally, the simulator is run on the circuit and measures the
        results. If upon measurement, the first n qubits are all 0, 1 is returned and the function is constant,
        otherwise 0 is returned and the function is balanced.
    This function has an anonymous function and integer n as parameters.
    This function uses 9q-squared-qvm, so it assumes that n <= 9.
    """
    # apply H to first n qubits and X H to the last qubit (ancilla qubit)
    initialize_list = [0] * n
    initialize_list.append(1)
    qubits = list(range(len(initialize_list)))
    program = initialize(initialize_list)
    # Generate Uf oracle from f (anonymous function)
    uf_gate = generate_uf(f, n, "Uf")
    Uf = uf_gate.get_constructor()
    # Add Uf to circuit
    program += uf_gate
    program += Uf(*qubits)
    # Apply Hadamards to first n qubits
    apply_to_list = [1] * n
    apply_to_list.append(0)
    program = apply_H(program, apply_to_list)
    # print(program)
    # Run simulator
    with local_forest_runtime():
        # Assume n <= 9
        qvm = get_qc('9q-square-qvm')
        # 1 trial because DJ is deterministic
        results = qvm.run_and_measure(program, trials=1)
        # check if first n qubits are all 0
        for i in range(n):
            if (results[i] != 0):
                return 0
        return 1
    # in case of failure, return 0
    return 0
Ejemplo n.º 15
0
    """
    uf_definition = DefGate("UF-GATE", uf_matrix)
    UF_GATE = uf_definition.get_constructor()
    return uf_definition, UF_GATE


# Define size of algorithm
n = 4

uf_definition, UF_GATE = Uf(uf_01)

# construct a (0*n, 1) state
zeros = [0] * n
zeros.append(1)
p = init_qubits(zeros)
p += uf_definition
# apply Hadamards
for i in range(len(zeros)):
    p += H(i)
# apply Uf gate
p += UF_GATE()
# apply final Hadamards
for i in range(len(zeros) - 1):
    p += H(i)

with local_forest_runtime():
    qvm = get_qc('9q-square-qvm')
    results = qvm.run_and_measure(p, trials=10)
    print(results[0])
    print(results[1])