Пример #1
0
def get_hhl_2x2(A, b, r, qubits):
    '''Generate a circuit that implements the full HHL algorithm for the case
    of 2x2 matrices.

    :param A: (numpy.ndarray) A Hermitian 2x2 matrix.
    :param b: (numpy.ndarray) A vector.
    :param r: (float) Parameter to be tuned in the algorithm.
    :param verbose: (bool) Optional information about the wavefunction.

    :return: A Quil program to perform HHL.
    '''
    p = pq.Program()
    p.inst(create_arbitrary_state(b, [qubits[3]]))
    p.inst(H(qubits[1]))
    p.inst(H(qubits[2]))
    p.defgate('CONTROLLED-U0', controlled(scipy.linalg.expm(2j*π*A/4)))
    p.inst(('CONTROLLED-U0', qubits[2], qubits[3]))
    p.defgate('CONTROLLED-U1', controlled(scipy.linalg.expm(2j*π*A/2)))
    p.inst(('CONTROLLED-U1', qubits[1], qubits[3]))
    p.inst(SWAP(qubits[1], qubits[2]))
    p.inst(H(qubits[2]))
    p.defgate('CSdag', controlled(np.array([[1, 0], [0, -1j]])))
    p.inst(('CSdag', qubits[1], qubits[2]))
    p.inst(H(qubits[1]))
    p.inst(SWAP(qubits[1], qubits[2]))
    uncomputation = p.dagger()
    p.defgate('CRy0', controlled(rY(2*π/2**r)))
    p.inst(('CRy0', qubits[1], qubits[0]))
    p.defgate('CRy1', controlled(rY(π/2**r)))
    p.inst(('CRy1', qubits[2], qubits[0]))
    p += uncomputation
    return p
Пример #2
0
    def create_initial_state_program(self, initial_state):
        """
        Creates a pyquil program representing the initial state for the QAOA.
        As an argument it takes either a list with order of the cities, or 
        a string "all". In the second case the initial state is superposition
        of all possible states for this problem.
        """
        initial_state_program = pq.Program()
        if type(initial_state) is list:
            for i in range(self.reduced_number_of_nodes):
                initial_state_program.inst(X(i * (self.reduced_number_of_nodes) + initial_state[i]))

        elif initial_state == "all":
            vector_of_states = np.zeros(2**self.number_of_qubits)
            list_of_possible_states = []
            initial_order = range(0, self.reduced_number_of_nodes)
            all_permutations = [list(x) for x in itertools.permutations(initial_order)]
            for permutation in all_permutations:
                coding_of_permutation = 0
                for i in range(len(permutation)):
                    coding_of_permutation += 2**(i * (self.reduced_number_of_nodes) + permutation[i])
                vector_of_states[coding_of_permutation] = 1
            initial_state_program = create_arbitrary_state(vector_of_states)

        return initial_state_program
    def create_initial_state_program(self):
        """
        As an initial state I use state, where in t=i we visit i-th city.
        """
        initial_state = pq.Program()
        number_of_nodes = len(self.nodes_array)
        if type(self.initial_state) is list:
            for i in range(number_of_nodes):
                initial_state.inst(
                    X(i * number_of_nodes + self.initial_state[i]))

        elif self.initial_state == "all":
            vector_of_states = np.zeros(2**self.number_of_qubits)
            list_of_possible_states = []
            initial_order = range(0, number_of_nodes)
            all_permutations = [
                list(x) for x in itertools.permutations(initial_order)
            ]
            for permutation in all_permutations:
                coding_of_permutation = 0
                for i in range(len(permutation)):
                    coding_of_permutation += 2**(i * number_of_nodes +
                                                 permutation[i])
                vector_of_states[coding_of_permutation] = 1
            initial_state = create_arbitrary_state(vector_of_states)

        return initial_state
Пример #4
0
    def wrap(theta):
        """
        Creates arbitrary state using stereographic projection.

        :param theta: Vector representing the state.
        :return: PyQuil program setting up the state.
        """
        return create_arbitrary_state(maps.plane_to_sphere(theta, pole))
Пример #5
0
    def wrap(theta: np.ndarray):
        """
        Creates arbitrary state.

        :param theta: Vector representing the state.
        :return: PyQuil program setting up the state.
        """
        theta = np.concatenate((np.array([1]) / np.sqrt(dim), theta), axis=0)
        return create_arbitrary_state(theta)
Пример #6
0
    def wrap(theta: np.ndarray) -> Program:
        """
        Creates arbitrary one-particle state.

        :param theta: Coefficients in superposition.
        :return: Pyquil program setting up the state.
        """
        vector = np.zeros(2**dim)
        vector[1] = 1 / np.sqrt(dim)
        vector[[2**(i + 1) for i in range(dim - 1)]] = theta
        vector *= 1 / np.linalg.norm(vector)
        return create_arbitrary_state(vector)
Пример #7
0
def create_initial_state_program():
    initial_state_program = pq.Program()
    vector_of_states = np.zeros(2**number_of_qubits)
    list_of_possible_states = []
    initial_order = range(0, reduced_number_of_nodes)
    all_permutations = [list(x) for x in itertools.permutations(initial_order)]
    for permutation in all_permutations:
        coding_of_permutation = 0
        for i in range(len(permutation)):
            coding_of_permutation += 2**(i * (reduced_number_of_nodes) +
                                         permutation[i])
        vector_of_states[coding_of_permutation] = 1
    initial_state_program = create_arbitrary_state(vector_of_states)
    return initial_state_program
Пример #8
0
def verify_with_swap_test_2x2(reference_amplitudes, qubits):
    '''Generate a circuit for performing a swap test.
    :param program: (pyquil.quil.Program) Program storing the HHL algorithm.
    :param reference_amplitudes: (numpy.ndarray) Amplitudes of the state to be
                                  compared against.
    :return: A Quil program to do a swap test after inverting 2x2 matrices.
    '''
    swaptest = pq.Program()
    swaptest.inst(create_arbitrary_state(reference_amplitudes, [qubits[4]]))
    swaptest.inst(H(qubits[5]))
    swaptest.inst(CSWAP(qubits[5], qubits[4], qubits[3]))
    swaptest.inst(H(qubits[5]))
    c = swaptest.declare('ro', 'BIT', 2)
    swaptest += MEASURE(qubits[0], c[0]) # This is actually the post-selection in HHL
    swaptest += MEASURE(qubits[5], c[1])
    return swaptest
Пример #9
0
def get_hhl_2x2_corrected(A, b, r, qubits):
    """ HHL program with bit code corrections on first two H gates """
    p = pq.Program()
    p.inst(create_arbitrary_state(b, [qubits[3]]))
    
    # PHASE ESTIMATION
    bit_code_H(p, qubits[1], qubits)  
    bit_code_H(p, qubits[2], qubits)    
    p.defgate('CONTROLLED-U0', controlled(scipy.linalg.expm(2j*π*A/4)))
    p.inst(('CONTROLLED-U0', qubits[2], qubits[3]))
    p.defgate('CONTROLLED-U1', controlled(scipy.linalg.expm(2j*π*A/2)))
    p.inst(('CONTROLLED-U1', qubits[1], qubits[3]))
    p.inst(SWAP(qubits[1], qubits[2]))
    p.inst(H(qubits[2]))
    p.defgate('CSdag', controlled(np.array([[1, 0], [0, -1j]])))
    p.inst(('CSdag', qubits[1], qubits[2]))
    p.inst(H(qubits[1]))
    p.inst(SWAP(qubits[1], qubits[2]))

    p.defgate('CRy0', controlled(rY(2*π/2**r)))
    p.inst(('CRy0', qubits[1], qubits[0]))
    p.defgate('CRy1', controlled(rY(π/2**r)))
    p.inst(('CRy1', qubits[2], qubits[0]))
    
    # HARD CODE THE INVERSE PHASE ESTIMATION :'(
    p.inst(SWAP(qubits[1], qubits[2]))
    p.inst(H(qubits[1]))
    p.defgate('CSdag-INV', controlled(np.array([[1, 0], [0, 1j]])))
    p.inst(('CSdag-INV', qubits[1], qubits[2]))
    p.inst(H(qubits[2]))
    p.inst(SWAP(qubits[1], qubits[2]))
    p.defgate('CONTROLLED-U1-INV', controlled(scipy.linalg.expm(-2j*π*A/2)))
    p.inst(('CONTROLLED-U1-INV', qubits[1], qubits[3]))
    p.defgate('CONTROLLED-U0-INV', controlled(scipy.linalg.expm(-2j*π*A/4)))
    p.inst(('CONTROLLED-U0-INV', qubits[2], qubits[3]))    
    p.inst(H(qubits[2]))
    p.inst(H(qubits[1]))

    # undoes create_arbitrary_state
    p.inst(RY(π/2, qubits[3]))
    p.inst(H(qubits[3]))
    return p
# We need to do this inc ase registers are entangled.

hhl += uncomputation

# Rejection sampling on the acnilla register and a swap test
# The state |x> = A^-1 |b> is prop to sum_J beta_j lambda_j^-1 |u_j>
# contains info about the solution to Ax = b when measuring 1 on the ancilla state.

# We perform post selection by projecting onto the desired |1>
# To check the solution is the expected one, we prepare the correct output state
# manually to perform a swap test with the outcome.

from grove.alpha.arbitrary_state.arbitrary_state import create_arbitrary_state
reference_amplitudes = [0.9492929682, 0.3143928443]
# Target state prep
hhl += create_arbitrary_state(reference_amplitudes, [4])
# Swap test
hhl += H(5)
hhl += CSWAP(5, 4, 3)
hhl += H(5)
c = hhl.declare('ro', 'BIT', 2)
hhl += MEASURE(0, c[0])
hhl += MEASURE(5, c[1])

# it is a good ex to check if the right result is given by the state
# |x> = 0.949 |0> + 0.314 |1>

# There are tow measuresments performed, one of the ancilla register ( for doing post selection)
# and another one that gives the result of the swap test. To calculate success probabilities, define helper functions