Ejemplo n.º 1
0
    def test_create_from_paulis_0(self):
        """Test with single paulis."""
        num_qubits = 3
        for pauli_label in itertools.product('IXYZ', repeat=num_qubits):
            coeff = np.random.random(1)[0]
            pauli_term = [coeff, Pauli.from_label(pauli_label)]
            op = Operator(paulis=[pauli_term])

            depth = 1
            var_form = RYRZ(op.num_qubits, depth)
            circuit = var_form.construct_circuit(np.array(np.random.randn(var_form.num_parameters)))
            run_config = {'shots': 1}
            backend = BasicAer.get_backend('statevector_simulator')
            non_matrix_mode = op.eval('paulis', circuit, backend, run_config=run_config)[0]
            matrix_mode = op.eval('matrix', circuit, backend, run_config=run_config)[0]

            self.assertAlmostEqual(matrix_mode, non_matrix_mode, 6)
Ejemplo n.º 2
0
    def test_create_from_matrix(self):
        """Test with matrix initialization."""
        for num_qubits in range(1, 3):
            m_size = np.power(2, num_qubits)
            matrix = np.random.rand(m_size, m_size)

            op = Operator(matrix=matrix)

            depth = 1
            var_form = RYRZ(op.num_qubits, depth)
            circuit = var_form.construct_circuit(np.array(np.random.randn(var_form.num_parameters)))
            backend = BasicAer.get_backend('statevector_simulator')
            run_config = {'shots': 1}
            non_matrix_mode = op.eval('paulis', circuit, backend, run_config=run_config)[0]
            matrix_mode = op.eval('matrix', circuit, backend, run_config=run_config)[0]

            self.assertAlmostEqual(matrix_mode, non_matrix_mode, 6)
Ejemplo n.º 3
0
    def test_scaling_coeff(self):
        """ test scale """
        pauli_a = 'IXYZ'
        pauli_b = 'ZYIX'
        coeff_a = 0.5
        coeff_b = 0.5
        pauli_term_a = [coeff_a, Pauli.from_label(pauli_a)]
        pauli_term_b = [coeff_b, Pauli.from_label(pauli_b)]
        op_a = Operator(paulis=[pauli_term_a])
        op_b = Operator(paulis=[pauli_term_b])
        op_a += op_b

        self.assertEqual(2, len(op_a.paulis))

        op_a.scaling_coeff(0.7)

        self.assertEqual(2, len(op_a.paulis))
        self.assertEqual(0.35, op_a.paulis[0][0])
Ejemplo n.º 4
0
    def _build_hopping_operator(index, num_orbitals, num_particles,
                                qubit_mapping, two_qubit_reduction,
                                qubit_tapering, symmetries, cliffords, sq_list,
                                tapering_values):
        def check_commutativity(op_1, op_2):
            com = op_1 * op_2 - op_2 * op_1
            com.zeros_coeff_elimination()
            return True if com.is_empty() else False

        h1 = np.zeros((num_orbitals, num_orbitals))
        h2 = np.zeros((num_orbitals, num_orbitals, num_orbitals, num_orbitals))
        if len(index) == 2:
            i, j = index
            h1[i, j] = 1.0
            h1[j, i] = -1.0
        elif len(index) == 4:
            i, j, k, m = index
            h2[i, j, k, m] = 1.0
            h2[m, k, j, i] = -1.0

        dummpy_fer_op = FermionicOperator(h1=h1, h2=h2)
        qubit_op = dummpy_fer_op.mapping(qubit_mapping)
        qubit_op = qubit_op.two_qubit_reduced_operator(num_particles) \
            if two_qubit_reduction else qubit_op

        if qubit_tapering:
            for symmetry in symmetries:
                symmetry_op = Operator(paulis=[[1.0, symmetry]])
                symm_commuting = check_commutativity(symmetry_op, qubit_op)
                if not symm_commuting:
                    break

        if qubit_tapering:
            if symm_commuting:
                qubit_op = Operator.qubit_tapering(qubit_op, cliffords,
                                                   sq_list, tapering_values)
            else:
                qubit_op = None

        if qubit_op is None:
            logger.debug('Excitation ({}) is skipped since it is not commuted '
                         'with symmetries'.format(','.join(
                             [str(x) for x in index])))
        return qubit_op
Ejemplo n.º 5
0
    def init_params(cls, params, matrix):
        """
        Initialize via parameters dictionary and algorithm input instance

        Args:
            params: parameters dictionary
            matrix: two dimensional array which represents the operator
        """
        if matrix is None:
            raise AquaError("Operator instance is required.")

        if not isinstance(matrix, np.ndarray):
            matrix = np.array(matrix)

        eigs_params = params.get(Pluggable.SECTION_KEY_EIGS)
        args = {k: v for k, v in eigs_params.items() if k != 'name'}
        num_ancillae = eigs_params['num_ancillae']
        negative_evals = eigs_params['negative_evals']

        # Adding an additional flag qubit for negative eigenvalues
        if negative_evals:
            num_ancillae += 1
            args['num_ancillae'] = num_ancillae

        args['operator'] = Operator(matrix=matrix)

        # Set up iqft, we need to add num qubits to params which is our num_ancillae bits here
        iqft_params = params.get(Pluggable.SECTION_KEY_IQFT)
        iqft_params['num_qubits'] = num_ancillae
        args['iqft'] = get_pluggable_class(
            PluggableType.IQFT, iqft_params['name']).init_params(params)

        # For converting the encoding of the negative eigenvalues, we need two
        # additional instances for QFT and IQFT
        if negative_evals:
            ne_params = params
            qft_num_qubits = iqft_params['num_qubits']
            ne_qft_params = params.get(Pluggable.SECTION_KEY_QFT)
            ne_qft_params['num_qubits'] = qft_num_qubits - 1
            ne_iqft_params = params.get(Pluggable.SECTION_KEY_IQFT)
            ne_iqft_params['num_qubits'] = qft_num_qubits - 1
            ne_params['qft'] = ne_qft_params
            ne_params['iqft'] = ne_iqft_params
            args['ne_qfts'] = [
                get_pluggable_class(
                    PluggableType.QFT,
                    ne_qft_params['name']).init_params(ne_params),
                get_pluggable_class(
                    PluggableType.IQFT,
                    ne_iqft_params['name']).init_params(ne_params)
            ]
        else:
            args['ne_qfts'] = [None, None]

        return cls(**args)
Ejemplo n.º 6
0
    def test_submit_multiple_circuits(self):
        """
            test with single paulis
        """
        num_qubits = 4
        pauli_term = []
        for pauli_label in itertools.product('IXYZ', repeat=num_qubits):
            coeff = np.random.random(1)[0]
            pauli_term.append([coeff, Pauli.from_label(pauli_label)])
        op = Operator(paulis=pauli_term)

        depth = 1
        var_form = RYRZ(op.num_qubits, depth)
        circuit = var_form.construct_circuit(np.array(np.random.randn(var_form.num_parameters)))
        run_config = RunConfig(shots=1)
        backend = BasicAer.get_backend('statevector_simulator')
        non_matrix_mode = op.eval('paulis', circuit, backend, run_config=run_config)[0]
        matrix_mode = op.eval('matrix', circuit, backend, run_config=run_config)[0]

        self.assertAlmostEqual(matrix_mode, non_matrix_mode, 6)
Ejemplo n.º 7
0
def get_exact_cover_qubitops(list_of_subsets):
    """Construct the Hamiltonian for the exact solver problem


    Args:
        list_of_subsets: list of lists (i.e., subsets)

    Returns:
        operator.Operator, float: operator for the Hamiltonian and a
        constant shift for the obj function.

    Assumption:
        the union of the subsets contains all the elements to cover

    The Hamiltonian is:
       sum_{each element e}{(1-sum_{every subset_i that contains e}{Xi})^2},
       where Xi (Xi=1 or 0) means whether should include the subset i.

    """
    n = len(list_of_subsets)

    U = []
    for sub in list_of_subsets:
        U.extend(sub)
    U = np.unique(U)  # U is the universe

    shift = 0
    pauli_list = []

    for e in U:
        cond = [True if e in sub else False for sub in list_of_subsets]
        indices_has_e = np.arange(n)[cond]
        num_has_e = len(indices_has_e)
        Y = 1 - 0.5 * num_has_e
        shift += Y * Y

        for i in indices_has_e:
            for j in indices_has_e:
                if i != j:
                    wp = np.zeros(n)
                    vp = np.zeros(n)
                    vp[i] = 1
                    vp[j] = 1
                    pauli_list.append([0.25, Pauli(vp, wp)])
                else:
                    shift += 0.25

        for i in indices_has_e:
            wp = np.zeros(n)
            vp = np.zeros(n)
            vp[i] = 1
            pauli_list.append([-Y, Pauli(vp, wp)])

    return Operator(paulis=pauli_list), shift
Ejemplo n.º 8
0
def get_vertexcover_qubitops(weight_matrix):
    """Generate Hamiltonian for the vertex cover
    Args:
        weight_matrix (numpy.ndarray) : adjacency matrix.

    Returns:
        operator.Operator, float: operator for the Hamiltonian and a
        constant shift for the obj function.

    Goals:
    1 color some vertices as red such that every edge is connected to some red vertex
    2 minimize the vertices to be colored as red

    Hamiltonian:
    H = A * H_A + H_B
    H_A = sum\_{(i,j)\in E}{(1-Xi)(1-Xj)}
    H_B = sum_{i}{Zi}

    H_A is to achieve goal 1 while H_b is to achieve goal 2.
    H_A is hard constraint so we place a huge penality on it. A=5.
    Note Xi = (Zi+1)/2

    """
    n = len(weight_matrix)
    pauli_list = []
    shift = 0
    A = 5

    for i in range(n):
        for j in range(i):
            if (weight_matrix[i, j] != 0):
                wp = np.zeros(n)
                vp = np.zeros(n)
                vp[i] = 1
                vp[j] = 1
                pauli_list.append([A*0.25, Pauli(vp, wp)])

                vp2 = np.zeros(n)
                vp2[i] = 1
                pauli_list.append([-A*0.25, Pauli(vp2, wp)])

                vp3 = np.zeros(n)
                vp3[j] = 1
                pauli_list.append([-A*0.25, Pauli(vp3, wp)])

                shift += A*0.25

    for i in range(n):
        wp = np.zeros(n)
        vp = np.zeros(n)
        vp[i] = 1
        pauli_list.append([0.5, Pauli(vp, wp)])
        shift += 0.5
    return Operator(paulis=pauli_list), shift
Ejemplo n.º 9
0
def stabilizers(fer_op):

    edge_list = bravyi_kitaev_fast_edge_list(fer_op)
    num_qubits = edge_list.shape[1]
    # vac_operator = Operator(paulis=[[1.0, Pauli.from_label('I' * num_qubits)]])

    g = networkx.Graph()
    g.add_edges_from(tuple(edge_list.transpose()))
    stabs = np.asarray(networkx.cycle_basis(g))
    stabilizers = []
    for stab in stabs:
        a = Operator(paulis=[[1.0, Pauli.from_label('I' * num_qubits)]])
        stab = np.asarray(stab)
        for i in range(np.size(stab)):
            a = a * edge_operator_aij(edge_list, stab[i],
                                      stab[(i + 1) % np.size(stab)])
            a.scaling_coeff(1j)
        stabilizers.append(a)

    return stabilizers
Ejemplo n.º 10
0
    def test_addition_paulis_inplace(self):
        """Test addition."""
        pauli_a = 'IXYZ'
        pauli_b = 'ZYIX'
        coeff_a = 0.5
        coeff_b = 0.5
        pauli_term_a = [coeff_a, Pauli.from_label(pauli_a)]
        pauli_term_b = [coeff_b, Pauli.from_label(pauli_b)]
        op_a = Operator(paulis=[pauli_term_a])
        op_b = Operator(paulis=[pauli_term_b])
        op_a += op_b

        self.assertEqual(2, len(op_a.paulis))

        pauli_c = 'IXYZ'
        coeff_c = 0.25
        pauli_term_c = [coeff_c, Pauli.from_label(pauli_c)]
        op_a += Operator(paulis=[pauli_term_c])

        self.assertEqual(2, len(op_a.paulis))
        self.assertEqual(0.75, op_a.paulis[0][0])
Ejemplo n.º 11
0
    def test_group_paulis_1(self):
        """
            Test with color grouping approach
        """
        num_qubits = 4
        pauli_term = []
        for pauli_label in itertools.product('IXYZ', repeat=num_qubits):
            coeff = np.random.random(1)[0]
            pauli_term.append([coeff, Pauli.from_label(''.join(pauli_label))])
        op = Operator(paulis=pauli_term)
        paulis = copy.deepcopy(op.paulis)
        op.to_grouped_paulis()
        flattened_grouped_paulis = [pauli for group in op.grouped_paulis for pauli in group[1:]]

        for gp in flattened_grouped_paulis:
            passed = False
            for p in paulis:
                if p[1] == gp[1]:
                    passed = p[0] == gp[0]
                    break
            self.assertTrue(passed, "non-existed paulis in grouped_paulis: {}".format(gp[1].to_label()))
Ejemplo n.º 12
0
def get_set_packing_qubitops(list_of_subsets):
    """Construct the Hamiltonian for the set packing
    Args:
        list_of_subsets: list of lists (i.e., subsets)

    Returns:
        operator.Operator, float: operator for the Hamiltonian and a
        constant shift for the obj function.

    find the maximal number of subsets which are disjoint pairwise.

    Hamiltonian:
    H = A Ha + B Hb
    Ha = sum_{Si and Sj overlaps}{XiXj}
    Hb = -sum_{i}{Xi}

    Ha is to ensure the disjoint condition, while Hb is to achieve the maximal number.
    Ha is hard constraint that must be satisified. Therefore A >> B.
    In the following, we set A=10 and B = 1

    Note Xi = (Zi + 1)/2
    """
    shift = 0
    pauli_list = []
    A = 10
    n = len(list_of_subsets)
    for i in range(n):
        for j in range(i):
            if set(list_of_subsets[i]) & set(list_of_subsets[j]):
                wp = np.zeros(n)
                vp = np.zeros(n)
                vp[i] = 1
                vp[j] = 1
                pauli_list.append([A * 0.25, Pauli(vp, wp)])

                vp2 = np.zeros(n)
                vp2[i] = 1
                pauli_list.append([A * 0.25, Pauli(vp2, wp)])

                vp3 = np.zeros(n)
                vp3[j] = 1
                pauli_list.append([A * 0.25, Pauli(vp3, wp)])

                shift += A * 0.25

    for i in range(n):
        wp = np.zeros(n)
        vp = np.zeros(n)
        vp[i] = 1
        pauli_list.append([-0.5, Pauli(vp, wp)])
        shift += -0.5

    return Operator(paulis=pauli_list), shift
Ejemplo n.º 13
0
    def test_subtraction_inplace(self):
        """ test subtraction in place """
        pauli_a = 'IXYZ'
        pauli_b = 'ZYIX'
        coeff_a = 0.5
        coeff_b = 0.5
        pauli_term_a = [coeff_a, Pauli.from_label(pauli_a)]
        pauli_term_b = [coeff_b, Pauli.from_label(pauli_b)]
        op_a = Operator(paulis=[pauli_term_a])
        op_b = Operator(paulis=[pauli_term_b])
        op_a -= op_b

        self.assertEqual(2, len(op_a.paulis))

        pauli_c = 'IXYZ'
        coeff_c = 0.25
        pauli_term_c = [coeff_c, Pauli.from_label(pauli_c)]
        op_a -= Operator(paulis=[pauli_term_c])

        self.assertEqual(2, len(op_a.paulis))
        self.assertEqual(0.25, op_a.paulis[0][0])
Ejemplo n.º 14
0
    def test_chop_complex_only_2(self):

        paulis = ['IXYZ', 'XXZY', 'IIZZ', 'XXYY', 'ZZXX', 'YYYY']
        coeffs = [0.2 + -1j * 0.8, 0.6 + -1j * 0.6, 0.8 + -1j * 0.2,
                  -0.2 + -1j * 0.8, -0.6 - -1j * 0.6, -0.8 - -1j * 0.2]
        op = Operator(paulis=[])
        for coeff, pauli in zip(coeffs, paulis):
            pauli_term = [coeff, Pauli.from_label(pauli)]
            op += Operator(paulis=[pauli_term])

        op1 = copy.deepcopy(op)
        op1.chop(threshold=0.4)
        self.assertEqual(len(op1.paulis), 6, "\n{}".format(op1.print_operators()))

        op2 = copy.deepcopy(op)
        op2.chop(threshold=0.7)
        self.assertEqual(len(op2.paulis), 4, "\n{}".format(op2.print_operators()))

        op3 = copy.deepcopy(op)
        op3.chop(threshold=0.9)
        self.assertEqual(len(op3.paulis), 0, "\n{}".format(op3.print_operators()))
Ejemplo n.º 15
0
def number_operator(fer_op, mode_number=None):
    """Find the qubit operator for the number operator in bravyi_kitaev_fast representation.

    Args:
        fer_op (FermionicOperator): the fermionic operator in the second quanitzed form
        mode_number (int): index, it corresponds to the mode for which number operator is required.

    Returns:
        Operator: the qubit operator
    """
    modes = fer_op.h1.modes
    edge_list = bravyi_kitaev_fast_edge_list(fer_op)
    num_qubits = edge_list.shape[1]
    num_operator = Operator(paulis=[[1.0, Pauli.from_label('I' * num_qubits)]])

    if mode_number is None:
        for i in range(modes):
            num_operator -= edge_operator_bi(edge_list, i)
        num_operator += Operator(
            paulis=[[1.0 *
                     modes, Pauli.from_label('I' * num_qubits)]])
    else:
        num_operator += (
            Operator(paulis=[[1.0, Pauli.from_label('I' * num_qubits)]]) -
            edge_operator_bi(edge_list, mode_number))

    num_operator.scaling_coeff(0.5)

    return num_operator
Ejemplo n.º 16
0
 def setUp(self):
     super().setUp()
     np.random.seed(50)
     pauli_dict = {
         'paulis': [{"coeff": {"imag": 0.0, "real": -1.052373245772859}, "label": "II"},
                    {"coeff": {"imag": 0.0, "real": 0.39793742484318045}, "label": "IZ"},
                    {"coeff": {"imag": 0.0, "real": -0.39793742484318045}, "label": "ZI"},
                    {"coeff": {"imag": 0.0, "real": -0.01128010425623538}, "label": "ZZ"},
                    {"coeff": {"imag": 0.0, "real": 0.18093119978423156}, "label": "XX"}
                    ]
     }
     qubit_op = Operator.load_from_dict(pauli_dict)
     self.algo_input = EnergyInput(qubit_op)
Ejemplo n.º 17
0
    def test_tapered_op(self):
        # set_qiskit_chemistry_logging(logging.DEBUG)
        tapered_ops = []
        for coeff in itertools.product([1, -1], repeat=len(self.sq_list)):
            tapered_op = Operator.qubit_tapering(self.qubit_op, self.cliffords,
                                                 self.sq_list, list(coeff))
            tapered_ops.append((list(coeff), tapered_op))

        smallest_idx = 0  # Prior knowledge of which tapered_op has ground state
        the_tapered_op = tapered_ops[smallest_idx][1]
        the_coeff = tapered_ops[smallest_idx][0]

        optimizer = SLSQP(maxiter=1000)

        init_state = HartreeFock(
            num_qubits=the_tapered_op.num_qubits,
            num_orbitals=self.core._molecule_info['num_orbitals'],
            qubit_mapping=self.core._qubit_mapping,
            two_qubit_reduction=self.core._two_qubit_reduction,
            num_particles=self.core._molecule_info['num_particles'],
            sq_list=self.sq_list)

        var_form = UCCSD(
            num_qubits=the_tapered_op.num_qubits,
            depth=1,
            num_orbitals=self.core._molecule_info['num_orbitals'],
            num_particles=self.core._molecule_info['num_particles'],
            active_occupied=None,
            active_unoccupied=None,
            initial_state=init_state,
            qubit_mapping=self.core._qubit_mapping,
            two_qubit_reduction=self.core._two_qubit_reduction,
            num_time_slices=1,
            cliffords=self.cliffords,
            sq_list=self.sq_list,
            tapering_values=the_coeff,
            symmetries=self.symmetries)

        algo = VQE(the_tapered_op, var_form, optimizer, 'matrix')

        backend = BasicAer.get_backend('statevector_simulator')
        quantum_instance = QuantumInstance(backend=backend)

        algo_result = algo.run(quantum_instance)

        lines, result = self.core.process_algorithm_result(algo_result)

        self.assertAlmostEqual(result['energy'],
                               self.reference_energy,
                               places=6)
Ejemplo n.º 18
0
    def test_addition_paulis_noninplace(self):
        """ test addition """
        pauli_a = 'IXYZ'
        pauli_b = 'ZYIX'
        coeff_a = 0.5
        coeff_b = 0.5
        pauli_term_a = [coeff_a, Pauli.from_label(pauli_a)]
        pauli_term_b = [coeff_b, Pauli.from_label(pauli_b)]
        op_a = Operator(paulis=[pauli_term_a])
        op_b = Operator(paulis=[pauli_term_b])
        copy_op_a = copy.deepcopy(op_a)
        new_op = op_a + op_b

        self.assertEqual(copy_op_a, op_a)
        self.assertEqual(2, len(new_op.paulis))

        pauli_c = 'IXYZ'
        coeff_c = 0.25
        pauli_term_c = [coeff_c, Pauli.from_label(pauli_c)]
        new_op = new_op + Operator(paulis=[pauli_term_c])

        self.assertEqual(2, len(new_op.paulis))
        self.assertEqual(0.75, new_op.paulis[0][0])
Ejemplo n.º 19
0
    def test_zero_elimination(self):
        pauli_a = 'IXYZ'
        coeff_a = 0.0
        pauli_term_a = [coeff_a, Pauli.from_label(pauli_a)]
        op_a = Operator(paulis=[pauli_term_a])
        self.assertEqual(1, len(op_a.paulis), "{}".format(op_a.print_operators()))
        op_a.zeros_coeff_elimination()

        self.assertEqual(0, len(op_a.paulis), "{}".format(op_a.print_operators()))
Ejemplo n.º 20
0
    def __init__(self, cost_operator, p, initial_state=None):
        self._cost_operator = cost_operator
        self._p = p
        self._initial_state = initial_state
        self.num_parameters = 2 * p
        self.parameter_bounds = [(0, np.pi)] * p + [(0, 2 * np.pi)] * p
        self.preferred_init_points = [0] * p * 2

        # prepare the mixer operator
        v = np.zeros(self._cost_operator.num_qubits)
        ws = np.eye(self._cost_operator.num_qubits)
        self._mixer_operator = reduce(lambda x, y: x + y, [
            Operator([[1, Pauli(v, ws[i, :])]])
            for i in range(self._cost_operator.num_qubits)
        ])
Ejemplo n.º 21
0
    def test_eoh(self):
        SIZE = 2

        temp = np.random.random((2 ** SIZE, 2 ** SIZE))
        h1 = temp + temp.T
        qubit_op = Operator(matrix=h1)

        temp = np.random.random((2 ** SIZE, 2 ** SIZE))
        h1 = temp + temp.T
        evo_op = Operator(matrix=h1)

        state_in = Custom(SIZE, state='random')

        evo_time = 1
        num_time_slices = 100

        eoh = EOH(qubit_op, state_in, evo_op, 'paulis', evo_time, num_time_slices)

        backend = BasicAer.get_backend('statevector_simulator')
        quantum_instance = QuantumInstance(backend, shots=1, max_credits=10, pass_manager=PassManager())
        # self.log.debug('state_out:\n\n')

        ret = eoh.run(quantum_instance)
        self.log.debug('Evaluation result: {}'.format(ret))
Ejemplo n.º 22
0
    def construct_circuit(self, k=None, omega=0, measurement=False):
        """Construct the kth iteration Quantum Phase Estimation circuit.

        For details of parameters, please see Fig. 2 in https://arxiv.org/pdf/quant-ph/0610214.pdf.

        Args:
            k (int): the iteration idx.
            omega (float): the feedback angle.
            measurement (bool): Boolean flag to indicate if measurement should be included in the circuit.

        Returns:
            QuantumCircuit: the quantum circuit per iteration
        """
        k = self._num_iterations if k is None else k
        a = QuantumRegister(1, name='a')
        q = QuantumRegister(self._operator.num_qubits, name='q')
        self._ancillary_register = a
        self._state_register = q
        qc = QuantumCircuit(q)
        qc += self._state_in.construct_circuit('circuit', q)
        # hadamard on a[0]
        qc.add_register(a)
        qc.u2(0, np.pi, a[0])
        # controlled-U
        qc_evolutions = Operator.construct_evolution_circuit(
            self._slice_pauli_list,
            -2 * np.pi,
            self._num_time_slices,
            q,
            a,
            unitary_power=2**(k - 1),
            shallow_slicing=self._shallow_circuit_concat)
        if self._shallow_circuit_concat:
            qc.data += qc_evolutions.data
        else:
            qc += qc_evolutions
        # global phase due to identity pauli
        qc.u1(2 * np.pi * self._ancilla_phase_coef * (2**(k - 1)), a[0])
        # rz on a[0]
        qc.u1(omega, a[0])
        # hadamard on a[0]
        qc.u2(0, np.pi, a[0])
        if measurement:
            c = ClassicalRegister(1, name='c')
            qc.add_register(c)
            # qc.barrier(self._ancillary_register)
            qc.measure(self._ancillary_register, c)
        return qc
Ejemplo n.º 23
0
def main():
    # may change graph. But be sure to also change the num_qubits to the appropriate number of nodes in the graph
    graph = [(2, 0), (2, 1)]
    num_qubits = 3  # number of unique nodes in the graph

    # algorithm properties
    p = 2  # number of time steps
    beta = np.random.uniform(0, np.pi*2, p)
    gamma = np.random.uniform(0, np.pi*2, p)
    # n_iter = 10  # number of iterations of the optimization procedure

    # mixing hamiltonian. May pauli X each qubit (change their color for maxcut)
    mixing_hamiltonian = reduce(lambda x, y: x + y,
                                [pauli_x(i, 1, num_qubits) for i in range(num_qubits)])

    # identity operation. As a utility to get the correct cost hamiltonian
    id_pauli = Pauli(np.zeros(num_qubits), np.zeros(num_qubits))
    id_operation = Operator([[1, id_pauli]])

    # cost Hamiltonian: summation of pauli z products. To maximize the number of adjacent different nodes
    cost_hamiltonian = reduce(lambda x, y: x + y,
                              [id_operation - product_pauli_z(i, j, 1, n_q=num_qubits)
                               for i, j in graph])

    # circuit initial state vector. All states in equal superposition
    init_state_vect = [1 for i in range(2**num_qubits)]
    init_state = Custom(num_qubits, state_vector=init_state_vect)

    # initialize quantum circuit
    qr = QuantumRegister(num_qubits)
    init_circ = init_state.construct_circuit('circuit', qr)

    # find optimal beta and gamma
    evaluate = partial(neg_evaluate_circuit, qr=qr, p=p, m_H=mixing_hamiltonian, c_H=cost_hamiltonian, init_circ=init_circ)
    result = minimize(evaluate, np.concatenate([gamma, beta]), method='L-BFGS-B')
    print(result)

    # now use the result of the gathered angles to find the answer
    circuit = create_circuit(qr, result['x'][:p], result['x'][p:], p, m_H=mixing_hamiltonian, c_H=cost_hamiltonian, init_circ=init_circ)

    backend = BasicAer.get_backend('statevector_simulator')
    job = execute(circuit, backend)
    state = np.asarray(job.result().get_statevector(circuit))
    print(np.absolute(state))
    print(np.angle(state))
Ejemplo n.º 24
0
def get_graph_partition_qubitops(weight_matrix):
    r"""Generate Hamiltonian for the graph partitioning

    Args:
        weight_matrix (numpy.ndarray) : adjacency matrix.

    Returns:
        operator.Operator, float: operator for the Hamiltonian and a
        constant shift for the obj function.

    Goals:
        1 separate the vertices into two set of the same size
        2 make sure the number of edges between the two set is minimized.
    Hamiltonian:
    H = H_A + H_B
    H_A = sum\_{(i,j)\in E}{(1-ZiZj)/2}
    H_B = (sum_{i}{Zi})^2 = sum_{i}{Zi^2}+sum_{i!=j}{ZiZj}
    H_A is for achieving goal 2 and H_B is for achieving goal 1.
    """
    num_nodes = len(weight_matrix)
    pauli_list = []
    shift = 0

    for i in range(num_nodes):
        for j in range(i):
            if weight_matrix[i, j] != 0:
                xp = np.zeros(num_nodes, dtype=np.bool)
                zp = np.zeros(num_nodes, dtype=np.bool)
                zp[i] = True
                zp[j] = True
                pauli_list.append([-0.5, Pauli(zp, xp)])
                shift += 0.5

    for i in range(num_nodes):
        for j in range(num_nodes):
            if i != j:
                xp = np.zeros(num_nodes, dtype=np.bool)
                zp = np.zeros(num_nodes, dtype=np.bool)
                zp[i] = True
                zp[j] = True
                pauli_list.append([1, Pauli(zp, xp)])
            else:
                shift += 1
    return Operator(paulis=pauli_list), shift
Ejemplo n.º 25
0
def get_vehiclerouting_qubitops(instance, n, K):
    """Converts an instnance of a vehicle routing problem into a list of Paulis.

    Args:
        instance (numpy.ndarray) : a customers-to-customers distance matrix.
        n (integer) : the number of customers.
        K (integer) : the number of vehicles available.

    Returns:
        operator.Operator: operator for the Hamiltonian.
        """

    N = (n - 1) * n
    (Q, g, c) = get_vehiclerouting_matrices(instance, n, K)

    # Defining the new matrices in the Z-basis
    Iv = np.ones(N)
    Qz = (Q / 4)
    gz = (-g / 2 - np.dot(Iv, Q / 4) - np.dot(Q / 4, Iv))
    cz = (c + np.dot(g / 2, Iv) + np.dot(Iv, np.dot(Q / 4, Iv)))

    cz = cz + np.trace(Qz)
    Qz = Qz - np.diag(np.diag(Qz))

    # Getting the Hamiltonian in the form of a list of Pauli terms

    pauli_list = []
    for i in range(N):
        if gz[i] != 0:
            wp = np.zeros(N)
            vp = np.zeros(N)
            vp[i] = 1
            pauli_list.append((gz[i], Pauli(vp, wp)))
    for i in range(N):
        for j in range(i):
            if Qz[i, j] != 0:
                wp = np.zeros(N)
                vp = np.zeros(N)
                vp[i] = 1
                vp[j] = 1
                pauli_list.append((2 * Qz[i, j], Pauli(vp, wp)))

    pauli_list.append((cz, Pauli(np.zeros(N), np.zeros(N))))
    return Operator(paulis=pauli_list)
Ejemplo n.º 26
0
def getPauliMatrix(matrix):
    rows = matrix.shape[0]
    paulis = []
    for row_pos in range(rows):
        for col_pos in range(matrix.shape[1]):
            temp = {}
            temp["imag"] = 0.0
            temp["real"] = matrix[row_pos, col_pos]
            label_pauli = ["I" for _ in range(rows)]
            if row_pos != col_pos:
                label_pauli[row_pos] = 'Z'
                label_pauli[col_pos] = 'Z'
            label_pauli = "".join(label_pauli)
            paulis.append({"coeff": temp, "label": label_pauli})
    paulis_dict = {"paulis": paulis}
    for i in paulis_dict["paulis"]:
        print(i)
    pauli_matrix = Operator.load_from_dict(paulis_dict)
    return pauli_matrix
Ejemplo n.º 27
0
def edge_operator_aij(edge_list, i, j):
    """Calculate the edge operator A_ij.

    The definitions used here are consistent with arXiv:quant-ph/0003137

    Args:
        edge_list (numpy.ndarray): a 2xE matrix, where E is total number of edge
                                    and each pair denotes (from, to)
        i (int): specifying the edge operator A
        j (int): specifying the edge operator A

    Returns:
        Operator: qubit operator
    """
    v = np.zeros(edge_list.shape[1])
    w = np.zeros(edge_list.shape[1])

    position_ij = -1
    qubit_position_i = np.asarray(np.where(edge_list == i))

    for edge_index in range(edge_list.shape[1]):
        if set((i, j)) == set(edge_list[:, edge_index]):
            position_ij = edge_index
            break

    w[position_ij] = 1

    for edge_index in range(qubit_position_i.shape[1]):
        ii, jj = qubit_position_i[:, edge_index]
        ii = 1 if ii == 0 else 0  # int(not(ii))
        if edge_list[ii][jj] < j:
            v[jj] = 1

    qubit_position_j = np.asarray(np.where(edge_list == j))
    for edge_index in range(qubit_position_j.shape[1]):
        ii, jj = qubit_position_j[:, edge_index]
        ii = 1 if ii == 0 else 0  # int(not(ii))
        if edge_list[ii][jj] < i:
            v[jj] = 1

    qubit_op = Operator(paulis=[[1.0, Pauli(v, w)]])
    return qubit_op
Ejemplo n.º 28
0
def edge_operator_bi(edge_list, i):
    """Calculate the edge operator B_i.

    The definitions used here are consistent with arXiv:quant-ph/0003137

    Args:
        edge_list (numpy.ndarray): a 2xE matrix, where E is total number of edge
                                    and each pair denotes (from, to)
        i (int): index for specifying the edge operator B.

    Returns:
        Operator: qubit operator
    """
    qubit_position_matrix = np.asarray(np.where(edge_list == i))
    qubit_position = qubit_position_matrix[1]
    v = np.zeros(edge_list.shape[1])
    w = np.zeros(edge_list.shape[1])
    v[qubit_position] = 1
    qubit_op = Operator(paulis=[[1.0, Pauli(v, w)]])
    return qubit_op
Ejemplo n.º 29
0
def get_ising_opt_qubitops(model, variables):

    num_variables = len(list(model.linear))
    var_to_int = dict(zip(list(model.linear), range(num_variables)))

    linear, quadratic, offset = model.to_ising()

    pauli_list = []
    xs = np.zeros(num_variables, dtype=np.bool)
    for (i, j), weight in quadratic.items():
        zs = np.zeros(num_variables, dtype=np.bool)
        zs[var_to_int[i]] = True
        zs[var_to_int[j]] = True
        pauli_list.append([weight, Pauli(zs, xs)])

    for (i, weight) in linear.items():
        zs = np.zeros(num_variables, dtype=np.bool)
        zs[var_to_int[i]] = True
        pauli_list.append([weight, Pauli(zs, xs)])

    return Operator(paulis=pauli_list), offset
Ejemplo n.º 30
0
    def test_load_from_file(self):
        paulis = ['IXYZ', 'XXZY', 'IIZZ', 'XXYY', 'ZZXX', 'YYYY']
        coeffs = [0.2 + -1j * 0.8, 0.6 + -1j * 0.6, 0.8 + -1j * 0.2,
                  -0.2 + -1j * 0.8, -0.6 - -1j * 0.6, -0.8 - -1j * 0.2]
        op = Operator(paulis=[])
        for coeff, pauli in zip(coeffs, paulis):
            pauli_term = [coeff, Pauli.from_label(pauli)]
            op += Operator(paulis=[pauli_term])

        op.save_to_file('temp_op.json')
        load_op = Operator.load_from_file('temp_op.json')

        self.assertTrue(os.path.exists('temp_op.json'))
        self.assertEqual(op, load_op)

        os.remove('temp_op.json')