Ejemplo n.º 1
0
def get_stableset_qubitops(w):
    """Generate Hamiltonian for the maximum stableset in a graph.

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

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

    """
    num_nodes = len(w)
    pauli_list = []
    shift = 0
    for i in range(num_nodes):
        for j in range(i + 1, num_nodes):
            if (w[i, j] != 0):
                wp = np.zeros(num_nodes)
                vp = np.zeros(num_nodes)
                vp[i] = 1
                vp[j] = 1
                pauli_list.append((1.0, Pauli(vp, wp)))
                shift += 1
    for i in range(num_nodes):
        degree = sum(w[i, :])
        wp = np.zeros(num_nodes)
        vp = np.zeros(num_nodes)
        vp[i] = 1
        pauli_list.append((degree - 1 / 2, Pauli(vp, wp)))
    return Operator(paulis=pauli_list), shift - num_nodes / 2
Ejemplo n.º 2
0
    def test_two_qubit_reduction(self):
        """ qiskit.tools.apps.fermion.two_qubit_reduction"""
        pauli_list = []
        n = 4
        w = np.arange(n**2).reshape(n, n)

        for i in range(n):
            for j in range(i):
                if w[i, j] != 0:
                    wp = np.zeros(n)
                    vp = np.zeros(n)
                    vp[n - i - 1] = 1
                    vp[n - j - 1] = 1
                    pauli_list.append((w[i, j], Pauli(vp, wp)))
        r = two_qubit_reduction(pauli_list, 10)
        r0 = [i[0] for i in r]
        self.assertEqual([-5, -8, -2, 13], r0)
        r1 = [i[1] for i in r]
        e = [
            Pauli(self.zo, self.zz),
            Pauli(self.zz, self.zz),
            Pauli(self.oz, self.zz),
            Pauli(self.oo, self.zz)
        ]
        self.assertEqual(e, r1)
Ejemplo n.º 3
0
    def test_group_paulis(self):
        """ qiskit.tools.apps.optimization.group_paulis function"""
        ham_name = self._get_resource_path("../performance/H2/H2Equilibrium.txt")
        zz = np.array([0, 0])
        oo = np.array([1, 1])

        pauli_list = Hamiltonian_from_file(ham_name)
        pauli_list_grouped = group_paulis(pauli_list)

        self.assertEqual(len(pauli_list_grouped), 2)
        r0 = [i[0] for i in pauli_list_grouped]
        r1 = [i[1] for i in pauli_list_grouped]

        self.assertEqual(len(r0), 2)
        r00 = [i[0] for i in r0]
        r01 = [i[1] for i in r0]
        e01 = [Pauli(oo, zz), Pauli(zz, oo)]
        self.assertEqual([0, 0], r00)
        self.assertEqual(e01, r01)

        self.assertEqual(len(r1), 2)
        r10 = [i[0] for i in r1]
        r11 = [i[1] for i in r1]
        e11 = [Pauli(oo, zz), Pauli(zz, oo)]
        self.assertEqual([0.011279956224107712, 0.18093133934472627], r10)
        self.assertEqual(e11, r11)

        expected_stout = ("Post Rotations of TPB set 0:\nZZ\n0\n\nZZ\n0.0112800\n"
                          "II\n-1.0523761\nZI\n0.3979357\nIZ\n"
                          "0.3979357\n\n\nPost Rotations of TPB set 1:\nXX\n0\n\n"
                          "XX\n0.1809313")
        with patch('sys.stdout', new=StringIO()) as fakeOutput:
            print_pauli_list_grouped(pauli_list_grouped)

        self.assertMultiLineEqual(fakeOutput.getvalue().strip(), expected_stout)
Ejemplo n.º 4
0
    def test_pauli_sgn_prod(self):
        p1 = Pauli(np.array([0]), np.array([1]))
        p2 = Pauli(np.array([1]), np.array([1]))

        self.log.info("sign product:")
        p3, sgn = sgn_prod(p1, p2)
        self.log.info("p1: %s", p1.to_label())
        self.log.info("p2: %s", p2.to_label())
        self.log.info("p3: %s", p3.to_label())
        self.log.info("sgn_prod(p1, p2): %s", str(sgn))
        self.assertEqual(p1.to_label(), 'X')
        self.assertEqual(p2.to_label(), 'Y')
        self.assertEqual(p3.to_label(), 'Z')
        self.assertEqual(sgn, 1j)

        self.log.info("sign product reverse:")
        p3, sgn = sgn_prod(p2, p1)
        self.log.info("p2: %s", p2.to_label())
        self.log.info("p1: %s", p1.to_label())
        self.log.info("p3: %s", p3.to_label())
        self.log.info("sgn_prod(p2, p1): %s", str(sgn))
        self.assertEqual(p1.to_label(), 'X')
        self.assertEqual(p2.to_label(), 'Y')
        self.assertEqual(p3.to_label(), 'Z')
        self.assertEqual(sgn, -1j)
Ejemplo n.º 5
0
    def test_hamiltonian(self):
        # printing an example from a H2 file
        hfile = self._get_resource_path("H2Equilibrium.txt")
        hamiltonian = make_Hamiltonian(Hamiltonian_from_file(hfile))
        self.log.info(hamiltonian)
        # [[-0.24522469381221926 0 0 0.18093133934472627 ]
        # [0 -1.0636560168497590 0.18093133934472627 0]
        # [0 0.18093133934472627 -1.0636560168497592 0]
        # [0.18093133934472627 0 0 -1.8369675149908681]]
        self.assertSequenceEqual([str(i) for i in hamiltonian[0]],
                                 ['(-0.245224693812+0j)', '0j', '0j', '(0.180931339345+0j)'])
        self.assertSequenceEqual([str(i) for i in hamiltonian[1]],
                                 ['0j', '(-1.06365601685+0j)', '(0.180931339345+0j)', '0j'])
        self.assertSequenceEqual([str(i) for i in hamiltonian[2]],
                                 ['0j', '(0.180931339345+0j)', '(-1.06365601685+0j)', '0j'])
        self.assertSequenceEqual([str(i) for i in hamiltonian[3]],
                                 ['(0.180931339345+0j)', '0j', '0j', '(-1.83696751499+0j)'])

        # printing an example from a graph input
        n = 3
        v0 = np.zeros(n)
        v0[2] = 1
        v1 = np.zeros(n)
        v1[0] = 1
        v1[1] = 1
        v2 = np.zeros(n)
        v2[0] = 1
        v2[2] = 1
        v3 = np.zeros(n)
        v3[1] = 1
        v3[2] = 1

        pauli_list = [(1, Pauli(v0, np.zeros(n))), (1, Pauli(v1, np.zeros(n))),
                      (1, Pauli(v2, np.zeros(n))), (1, Pauli(v3, np.zeros(n)))]
        a = make_Hamiltonian(pauli_list)
        self.log.info(a)

        w, v = la.eigh(a, eigvals=(0, 0))
        self.log.info(w)
        self.log.info(v)

        data = {'000': 10}
        self.log.info(Energy_Estimate(data, pauli_list))
        data = {'001': 10}
        self.log.info(Energy_Estimate(data, pauli_list))
        data = {'010': 10}
        self.log.info(Energy_Estimate(data, pauli_list))
        data = {'011': 10}
        self.log.info(Energy_Estimate(data, pauli_list))
        data = {'100': 10}
        self.log.info(Energy_Estimate(data, pauli_list))
        data = {'101': 10}
        self.log.info(Energy_Estimate(data, pauli_list))
        data = {'110': 10}
        self.log.info(Energy_Estimate(data, pauli_list))
        data = {'111': 10}
        self.log.info(Energy_Estimate(data, pauli_list))
Ejemplo n.º 6
0
    def _jordan_wigner_mode(self, n):
        """
        Jordan_Wigner mode.

        Args:
            n (int): number of modes
        """
        a = []
        for i in range(n):
            xv = np.asarray([1] * i + [0] + [0] * (n - i - 1))
            xw = np.asarray([0] * i + [1] + [0] * (n - i - 1))
            yv = np.asarray([1] * i + [1] + [0] * (n - i - 1))
            yw = np.asarray([0] * i + [1] + [0] * (n - i - 1))
            a.append((Pauli(xv, xw), Pauli(yv, yw)))
        return a
Ejemplo n.º 7
0
    def test_pauli(self):

        v = np.zeros(3)
        w = np.zeros(3)
        v[0] = 1
        w[1] = 1
        v[2] = 1
        w[2] = 1

        p = Pauli(v, w)
        self.log.info(p)
        self.log.info("In label form:")
        self.log.info(p.to_label())
        self.log.info("In matrix form:")
        self.log.info(p.to_matrix())

        q = random_pauli(2)
        self.log.info(q)

        r = inverse_pauli(p)
        self.log.info("In label form:")
        self.log.info(r.to_label())

        self.log.info("Group in tensor order:")
        grp = pauli_group(3, case=1)
        for j in grp:
            self.log.info(j.to_label())

        self.log.info("Group in weight order:")
        grp = pauli_group(3)
        for j in grp:
            self.log.info(j.to_label())

        self.log.info("sign product:")
        p1 = Pauli(np.array([0]), np.array([1]))
        p2 = Pauli(np.array([1]), np.array([1]))
        p3, sgn = sgn_prod(p1, p2)
        self.log.info(p1.to_label())
        self.log.info(p2.to_label())
        self.log.info(p3.to_label())
        self.log.info(sgn)

        self.log.info("sign product reverse:")
        p3, sgn = sgn_prod(p2, p1)
        self.log.info(p2.to_label())
        self.log.info(p1.to_label())
        self.log.info(p3.to_label())
        self.log.info(sgn)
Ejemplo n.º 8
0
def get_partition_qubitops(values):
    """Construct the Hamiltonian for a given Partition instance.

    Given a list of numbers for the Number Partitioning problem, we
    construct the Hamiltonian described as a list of Pauli gates.

    Args:
        values (numpy.ndarray): array of values.

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

    """
    n = len(values)
    # The Hamiltonian is:
    # \sum_{i,j=1,\dots,n} ij z_iz_j + \sum_{i=1,\dots,n} i^2
    pauli_list = []
    for i in range(n):
        for j in range(i):
            wp = np.zeros(n)
            vp = np.zeros(n)
            vp[i] = 1
            vp[j] = 1
            pauli_list.append([2 * values[i] * values[j], Pauli(vp, wp)])
    return Operator(paulis=pauli_list), sum(values*values)
Ejemplo n.º 9
0
    def _setup_qpe(self):
        self._operator._check_representation('paulis')
        self._ret['translation'] = sum(
            [abs(p[0]) for p in self._operator.paulis])
        self._ret['stretch'] = 0.5 / self._ret['translation']

        # translate the operator
        self._operator._simplify_paulis()
        translation_op = Operator([[
            self._ret['translation'],
            Pauli(np.zeros(self._operator.num_qubits),
                  np.zeros(self._operator.num_qubits))
        ]])
        translation_op._simplify_paulis()
        self._operator += translation_op

        # stretch the operator
        for p in self._operator._paulis:
            p[0] = p[0] * self._ret['stretch']

        # check for identify paulis to get its coef for applying global phase shift on ancillae later
        num_identities = 0
        for p in self._operator.paulis:
            if np.all(p[1].v == 0) and np.all(p[1].w == 0):
                num_identities += 1
                if num_identities > 1:
                    raise RuntimeError(
                        'Multiple identity pauli terms are present.')
                self._ancilla_phase_coef = p[0].real if isinstance(
                    p[0], complex) else p[0]

        self._construct_qpe_evolution()
        logger.info('QPE circuit qasm length is roughly {}.'.format(
            len(self._circuit.qasm().split('\n'))))
Ejemplo n.º 10
0
 def test_constructor_npbool(self):
     v = np.asarray([True, False, True, False])
     w = np.asarray([False, True, True, False])
     p = Pauli(v, w)
     length = 4
     self.assertEqual(p.numberofqubits, length)
     self.assertEqual(p.to_label(), 'ZXYI')
     self.assertEqual(p.id, 'ZXYI')
Ejemplo n.º 11
0
    def test_label_to_pauli(self):
        label = 'ZXYI'
        p = label_to_pauli(label)

        v = np.asarray([1, 0, 1, 0])
        w = np.asarray([0, 1, 1, 0])
        p2 = Pauli(v, w)
        self.assertEqual(p, p2)
Ejemplo n.º 12
0
 def test_constructor_list(self):
     v = [1, 0, 1, 0]
     w = [0, 1, 1, 0]
     p = Pauli(v, w)
     length = 4
     self.assertEqual(p.numberofqubits, length)
     self.assertEqual(p.to_label(), 'ZXYI')
     self.assertEqual(p.id, 'ZXYI')
Ejemplo n.º 13
0
    def test_create_from_label(self):
        """Test creation from pauli label."""
        label = 'IZXY'
        pauli = Pauli(label=label)

        self.assertEqual(pauli, self.ref_p)
        self.assertEqual(pauli.to_label(), self.ref_label)
        self.assertEqual(len(pauli), 4)
Ejemplo n.º 14
0
    def setUp(self):
        v = np.zeros(3)
        w = np.zeros(3)
        v[0] = 1
        w[1] = 1
        v[2] = 1
        w[2] = 1

        self.p3 = Pauli(v, w)
Ejemplo n.º 15
0
    def test_hamiltonian(self):
        # printing an example from a H2 file
        hfile = self._get_resource_path("H2Equilibrium.txt")
        self.log.info(make_Hamiltonian(Hamiltonian_from_file(hfile)))

        # printing an example from a graph input
        n = 3
        v0 = np.zeros(n)
        v0[2] = 1
        v1 = np.zeros(n)
        v1[0] = 1
        v1[1] = 1
        v2 = np.zeros(n)
        v2[0] = 1
        v2[2] = 1
        v3 = np.zeros(n)
        v3[1] = 1
        v3[2] = 1

        pauli_list = [(1, Pauli(v0, np.zeros(n))), (1, Pauli(v1, np.zeros(n))),
                      (1, Pauli(v2, np.zeros(n))), (1, Pauli(v3, np.zeros(n)))]
        a = make_Hamiltonian(pauli_list)
        self.log.info(a)

        w, v = la.eigh(a, eigvals=(0, 0))
        self.log.info(w)
        self.log.info(v)

        data = {'000': 10}
        self.log.info(Energy_Estimate(data, pauli_list))
        data = {'001': 10}
        self.log.info(Energy_Estimate(data, pauli_list))
        data = {'010': 10}
        self.log.info(Energy_Estimate(data, pauli_list))
        data = {'011': 10}
        self.log.info(Energy_Estimate(data, pauli_list))
        data = {'100': 10}
        self.log.info(Energy_Estimate(data, pauli_list))
        data = {'101': 10}
        self.log.info(Energy_Estimate(data, pauli_list))
        data = {'110': 10}
        self.log.info(Energy_Estimate(data, pauli_list))
        data = {'111': 10}
        self.log.info(Energy_Estimate(data, pauli_list))
Ejemplo n.º 16
0
def get_graphpartition_qubitops(weight_matrix):
    """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):
                wp = np.zeros(num_nodes)
                vp = np.zeros(num_nodes)
                vp[i] = 1
                vp[j] = 1
                pauli_list.append([-0.5, Pauli(vp, wp)])
                shift += 0.5

    for i in range(num_nodes):
        for j in range(num_nodes):
            if i != j:
                wp = np.zeros(num_nodes)
                vp = np.zeros(num_nodes)
                vp[i] = 1
                vp[j] = 1
                pauli_list.append([1, Pauli(vp, wp)])
            else:
                shift += 1
    return Operator(paulis=pauli_list), shift
Ejemplo n.º 17
0
    def _parity_mode(self, n):
        """
        Parity mode.

        Args:
            n (int): number of modes
        """
        a = []
        for i in range(n):
            Xv = [0] * (i - 1) + [1] if i > 0 else []
            Xw = [0] * (i - 1) + [0] if i > 0 else []
            Yv = [0] * (i - 1) + [0] if i > 0 else []
            Yw = [0] * (i - 1) + [0] if i > 0 else []
            Xv = np.asarray(Xv + [0] + [0] * (n - i - 1))
            Xw = np.asarray(Xw + [1] + [1] * (n - i - 1))
            Yv = np.asarray(Yv + [1] + [0] * (n - i - 1))
            Yw = np.asarray(Yw + [1] + [1] * (n - i - 1))
            a.append((Pauli(Xv, Xw), Pauli(Yv, Yw)))
        return a
Ejemplo n.º 18
0
    def _parity_mode(self, n):
        """
        Parity mode.

        Args:
            n (int): number of modes
        """
        a = []
        for i in range(n):
            x_v = [0] * (i - 1) + [1] if i > 0 else []
            x_w = [0] * (i - 1) + [0] if i > 0 else []
            y_v = [0] * (i - 1) + [0] if i > 0 else []
            y_w = [0] * (i - 1) + [0] if i > 0 else []
            x_v = np.asarray(x_v + [0] + [0] * (n - i - 1))
            x_w = np.asarray(x_w + [1] + [1] * (n - i - 1))
            y_v = np.asarray(y_v + [1] + [0] * (n - i - 1))
            y_w = np.asarray(y_w + [1] + [1] * (n - i - 1))
            a.append((Pauli(x_v, x_w), Pauli(y_v, y_w)))
        return a
Ejemplo n.º 19
0
def get_portfolio_qubitops(mu, sigma, q, budget, penalty):

    # get problem dimension
    n = len(mu)
    e = np.ones(n)
    E = np.matmul(np.asmatrix(e).T, np.asmatrix(e))

    # map problem to Ising model
    offset = -np.dot(
        mu, e
    ) / 2 + penalty * budget**2 - budget * n * penalty + n**2 * penalty / 4 + q / 4 * np.dot(
        e, np.dot(sigma, e))
    mu_z = mu / 2 + budget * penalty * e - n * penalty / 2 * e - q / 2 * np.dot(
        sigma, e)
    sigma_z = penalty / 4 * E + q / 4 * sigma

    # construct operator
    pauli_list = []
    for i in range(n):
        i_ = i
        # i_ = n-i-1
        if np.abs(mu_z[i_]) > 1e-6:
            wp = np.zeros(n)
            vp = np.zeros(n)
            vp[i_] = 1
            pauli_list.append([mu_z[i_], Pauli(vp, wp)])
        for j in range(i):
            j_ = j
            # j_ = n-j-1
            if np.abs(sigma_z[i_, j_]) > 1e-6:
                wp = np.zeros(n)
                vp = np.zeros(n)
                vp[i_] = 1
                vp[j_] = 1
                pauli_list.append([2 * sigma_z[i_, j_], Pauli(vp, wp)])
        offset += sigma_z[i_, i_]

    return Operator(paulis=pauli_list), offset
Ejemplo n.º 20
0
        def __init__(self, cost_operator, p):
            self.cost_operator = cost_operator
            self.p = p
            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 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]):
        # does the order of number matters?
        if set((i, j)) == set(edge_list[:, edge_index]):
            position_ij = edge_index
            # can we break?
            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.º 22
0
 def test_fermionic_maps_binary_tree(self):
     """ qiskit.tools.apps.fermion.fermionic_maps with BINARY_TREE map type"""
     r = fermionic_maps(self.a2, self.a5, "BINARY_TREE")
     self.assertEqual(len(r), 6)
     r0 = [i[0] for i in r]
     self.assertEqual(self.e0, r0)
     r1 = [i[1] for i in r]
     e = [Pauli(self.zo, self.oz),
          Pauli(self.zz, self.oz),
          Pauli(self.oo, self.oz),
          Pauli(self.oz, self.oz),
          Pauli(self.oo, self.zz),
          Pauli(self.zz, self.zz)]
     self.assertEqual(r1, e)
Ejemplo n.º 23
0
 def test_fermionic_maps_parity(self):
     """ qiskit.tools.apps.fermion.fermionic_maps with PARITY map type"""
     r = fermionic_maps(self.a2, self.a5, "PARITY")
     self.assertEqual(len(r), 6)
     r0 = [i[0] for i in r]
     self.assertEqual(self.e0, r0)
     r1 = [i[1] for i in r]
     e = [Pauli(self.zo, self.oz),
          Pauli(self.zz, self.oz),
          Pauli(self.oo, self.oz),
          Pauli(self.oz, self.oz),
          Pauli(self.oo, self.zz),
          Pauli(self.zz, self.zz)]
     self.assertEqual(r1, e)
Ejemplo n.º 24
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.º 25
0
 def test_fermionic_maps_jordan_wigner(self):
     """ qiskit.tools.apps.fermion.fermionic_maps with JORDAN_WIGNER map type"""
     self.e0[0] = np.complex(0.75, 0)
     r = fermionic_maps(self.a2, self.a5, "JORDAN_WIGNER")
     self.assertEqual(len(r), 6)
     r0 = [i[0] for i in r]
     self.assertEqual(self.e0, r0)
     r1 = [i[1] for i in r]
     e = [Pauli(self.oo, self.oo),
          Pauli(self.zz, self.oo),
          Pauli(self.zo, self.oo),
          Pauli(self.oz, self.oo),
          Pauli(self.zo, self.zz),
          Pauli(self.zz, self.zz)]
     self.assertEqual(r1, e)
Ejemplo n.º 26
0
    def _compute_energy(self):
        self._operator._check_representation('paulis')
        self._ret['translation'] = sum(
            [abs(p[0]) for p in self._operator.paulis])
        self._ret['stretch'] = 0.5 / self._ret['translation']

        # translate the operator
        self._operator._simplify_paulis()
        translation_op = Operator([[
            self._ret['translation'],
            Pauli(np.zeros(self._operator.num_qubits),
                  np.zeros(self._operator.num_qubits))
        ]])
        translation_op._simplify_paulis()
        self._operator += translation_op

        # stretch the operator
        for p in self._operator._paulis:
            p[0] = p[0] * self._ret['stretch']

        # check for identify paulis to get its coef for applying global phase shift on ancilla later
        num_identities = 0
        for p in self._operator.paulis:
            if np.all(p[1].v == 0) and np.all(p[1].w == 0):
                num_identities += 1
                if num_identities > 1:
                    raise RuntimeError(
                        'Multiple identity pauli terms are present.')
                self._ancilla_phase_coef = p[0].real if isinstance(
                    p[0], complex) else p[0]

        self._ret['phase'] = self._estimate_phase_iteratively()
        self._ret['top_measurement_decimal'] = sum([
            t[0] * t[1] for t in
            zip([1 / 2**p for p in range(1, self._num_iterations + 1)],
                [int(n) for n in self._ret['top_measurement_label']])
        ])
        self._ret['energy'] = self._ret['phase'] / self._ret[
            'stretch'] - self._ret['translation']
Ejemplo n.º 27
0
def _one_body(edge_list, p, q, h1_pq):
    r"""
    Map the term a^\dagger_p a_q + a^\dagger_q a_p to qubit operator.

    Args:
        edge_list (numpy.ndarray): 2xE matrix, each indicates (from, to) pair
        p (int): index of the one body term
        q (int): index of the one body term
        h1_pq (complex): coeffient of the one body term at (p, q)

    Return:
        Operator: mapped qubit operator
    """
    # Handle off-diagonal terms.
    final_coeff = 1.0
    if p != q:
        a, b = sorted([p, q])
        b_a = edge_operator_bi(edge_list, a)
        b_b = edge_operator_bi(edge_list, b)
        a_ab = edge_operator_aij(edge_list, a, b)
        qubit_op = a_ab * b_b + b_a * a_ab
        final_coeff = -1j * 0.5

    # Handle diagonal terms.
    else:
        b_p = edge_operator_bi(edge_list, p)
        v = np.zeros(edge_list.shape[1])
        w = np.zeros(edge_list.shape[1])
        id_pauli = Pauli(v, w)

        id_op = Operator(paulis=[[1.0, id_pauli]])
        qubit_op = id_op - b_p
        final_coeff = 0.5

    qubit_op.scaling_coeff(final_coeff * h1_pq)
    qubit_op.zeros_coeff_elimination()
    return qubit_op
Ejemplo n.º 28
0
def get_maxcut_qubitops(weight_matrix):
    """Generate Hamiltonian for the maximum stableset in a graph.

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

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

    """
    num_nodes = weight_matrix.shape[0]
    pauli_list = []
    shift = 0
    for i in range(num_nodes):
        for j in range(i):
            if (weight_matrix[i,j] != 0):
                wp = np.zeros(num_nodes)
                vp = np.zeros(num_nodes)
                vp[i] = 1
                vp[j] = 1
                pauli_list.append([0.5 * weight_matrix[i, j], Pauli(vp, wp)])
                shift -= 0.5 * weight_matrix[i, j]
    return Operator(paulis=pauli_list), shift
Ejemplo n.º 29
0
    def _bravyi_kitaev_mode(self, n):
        """
        Bravyi-Kitaev mode

        Args:
            n (int): number of modes
        """
        def parity_set(j, n):
            """Computes the parity set of the j-th orbital in n modes

            Args:
                j (int) : the orbital index
                n (int) : the total number of modes

            Returns:
                numpy.ndarray: Array of mode indexes
            """
            indexes = np.array([])
            if n % 2 != 0:
                return indexes

            if j < n / 2:
                indexes = np.append(indexes, parity_set(j, n / 2))
            else:
                indexes = np.append(
                    indexes,
                    np.append(parity_set(j - n / 2, n / 2) + n / 2, n / 2 - 1))
            return indexes

        def update_set(j, n):
            """Computes the update set of the j-th orbital in n modes

            Args:
                j (int) : the orbital index
                n (int) : the total number of modes

            Returns:
                numpy.ndarray: Array of mode indexes

            """
            indexes = np.array([])
            if n % 2 != 0:
                return indexes
            if j < n / 2:
                indexes = np.append(indexes,
                                    np.append(n - 1, update_set(j, n / 2)))
            else:
                indexes = np.append(indexes,
                                    update_set(j - n / 2, n / 2) + n / 2)
            return indexes

        def flip_set(j, n):
            """Computes the flip set of the j-th orbital in n modes

            Args:
                j (int) : the orbital index
                n (int) : the total number of modes

            Returns:
                numpy.ndarray: Array of mode indexes

            """
            indexes = np.array([])
            if n % 2 != 0:
                return indexes
            if j < n / 2:
                indexes = np.append(indexes, flip_set(j, n / 2))
            elif j >= n / 2 and j < n - 1:
                indexes = np.append(indexes,
                                    flip_set(j - n / 2, n / 2) + n / 2)
            else:
                indexes = np.append(
                    np.append(indexes,
                              flip_set(j - n / 2, n / 2) + n / 2), n / 2 - 1)
            return indexes

        a = []
        # FIND BINARY SUPERSET SIZE
        bin_sup = 1
        while n > np.power(2, bin_sup):
            bin_sup += 1
        # DEFINE INDEX SETS FOR EVERY FERMIONIC MODE
        update_sets = []
        update_pauli = []

        parity_sets = []
        parity_pauli = []

        flip_sets = []

        remainder_sets = []
        remainder_pauli = []
        for j in range(n):

            update_sets.append(update_set(j, np.power(2, bin_sup)))
            update_sets[j] = update_sets[j][update_sets[j] < n]

            parity_sets.append(parity_set(j, np.power(2, bin_sup)))
            parity_sets[j] = parity_sets[j][parity_sets[j] < n]

            flip_sets.append(flip_set(j, np.power(2, bin_sup)))
            flip_sets[j] = flip_sets[j][flip_sets[j] < n]

            remainder_sets.append(np.setdiff1d(parity_sets[j], flip_sets[j]))

            update_pauli.append(Pauli(np.zeros(n), np.zeros(n)))
            parity_pauli.append(Pauli(np.zeros(n), np.zeros(n)))
            remainder_pauli.append(Pauli(np.zeros(n), np.zeros(n)))
            for k in range(n):
                if np.in1d(k, update_sets[j]):
                    update_pauli[j].w[k] = 1
                if np.in1d(k, parity_sets[j]):
                    parity_pauli[j].v[k] = 1
                if np.in1d(k, remainder_sets[j]):
                    remainder_pauli[j].v[k] = 1

            x_j = Pauli(np.zeros(n), np.zeros(n))
            x_j.w[j] = 1
            y_j = Pauli(np.zeros(n), np.zeros(n))
            y_j.v[j] = 1
            y_j.w[j] = 1
            a.append((update_pauli[j] * x_j * parity_pauli[j],
                      update_pauli[j] * y_j * remainder_pauli[j]))
        return a
Ejemplo n.º 30
0
def _two_body(edge_list, p, q, r, s, h2_pqrs):
    r"""
    Map the term a^\dagger_p a^\dagger_q a_r a_s + h.c. to qubit operator.

    Args:
        edge_list (numpy.ndarray): 2xE matrix, each indicates (from, to) pair
        p (int): index of the two body term
        q (int): index of the two body term
        r (int): index of the two body term
        s (int): index of the two body term
        h2_pqrs (complex): coeffient of the two body term at (p, q, r, s)

    Returns:
        Operator: mapped qubit operator
    """
    # Handle case of four unique indices.
    v = np.zeros(edge_list.shape[1])
    id_op = Operator(paulis=[[1, Pauli(v, v)]])
    final_coeff = 1.0

    if len(set([p, q, r, s])) == 4:
        b_p = edge_operator_bi(edge_list, p)
        b_q = edge_operator_bi(edge_list, q)
        b_r = edge_operator_bi(edge_list, r)
        b_s = edge_operator_bi(edge_list, s)
        a_pq = edge_operator_aij(edge_list, p, q)
        a_rs = edge_operator_aij(edge_list, r, s)
        a_pq = -a_pq if q < p else a_pq
        a_rs = -a_rs if s < r else a_rs

        qubit_op = (a_pq * a_rs) * (-id_op - b_p * b_q + b_p * b_r +
                                    b_p * b_s + b_q * b_r + b_q * b_s -
                                    b_r * b_s + b_p * b_q * b_r * b_s)
        final_coeff = 0.125

    # Handle case of three unique indices.
    elif len(set([p, q, r, s])) == 3:
        b_p = edge_operator_bi(edge_list, p)
        b_q = edge_operator_bi(edge_list, q)
        if p == r:
            b_s = edge_operator_bi(edge_list, s)
            a_qs = edge_operator_aij(edge_list, q, s)
            a_qs = -a_qs if s < q else a_qs
            qubit_op = (a_qs * b_s + b_q * a_qs) * (id_op - b_p)
            final_coeff = 1j * 0.25
        elif p == s:
            b_r = edge_operator_bi(edge_list, r)
            a_qr = edge_operator_aij(edge_list, q, r)
            a_qr = -a_qr if r < q else a_qr
            qubit_op = (a_qr * b_r + b_q * a_qr) * (id_op - b_p)
            final_coeff = 1j * -0.25
        elif q == r:
            b_s = edge_operator_bi(edge_list, s)
            a_ps = edge_operator_aij(edge_list, p, s)
            a_ps = -a_ps if s < p else a_ps
            qubit_op = (a_ps * b_s + b_p * a_ps) * (id_op - b_q)
            final_coeff = 1j * -0.25
        elif q == s:
            b_r = edge_operator_bi(edge_list, r)
            a_pr = edge_operator_aij(edge_list, p, r)
            a_pr = -a_pr if r < p else a_pr
            qubit_op = (a_pr * b_r + b_p * a_pr) * (id_op - b_q)
            final_coeff = 1j * 0.25
        else:
            pass

    # Handle case of two unique indices.
    elif len(set([p, q, r, s])) == 2:
        b_p = edge_operator_bi(edge_list, p)
        b_q = edge_operator_bi(edge_list, q)
        qubit_op = (id_op - b_p) * (id_op - b_q)
        if p == s:
            final_coeff = 0.25
        else:
            final_coeff = -0.25
    else:
        pass

    qubit_op.scaling_coeff(final_coeff * h2_pqrs)
    qubit_op.zeros_coeff_elimination()
    return qubit_op