Ejemplo n.º 1
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.º 2
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.º 3
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.º 4
0
 def test_imul(self):
     """Test in-place multiplication."""
     p1 = self.ref_p
     p2 = Pauli.from_label('ZXXI')
     p3 = deepcopy(p2)
     p2 *= p1
     self.assertTrue(p2 != p3)
     self.assertEqual(p2.to_label(), 'ZYIY')
Ejemplo n.º 5
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.º 6
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.º 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_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.º 9
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.º 10
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.º 11
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.º 12
0
 def test_random_pauli(self):
     """Test random pauli creation."""
     length = 4
     q = Pauli.random(length)
     self.log.info(q)
     self.assertEqual(q.numberofqubits, length)
     self.assertEqual(len(q.z), length)
     self.assertEqual(len(q.x), length)
     self.assertEqual(len(q.to_label()), length)
     self.assertEqual(len(q.to_matrix()), 2 ** length)
Ejemplo n.º 13
0
    def test_insert_paulis(self):
        """Test inserting paulis via pauli object."""
        p1 = deepcopy(self.ref_p)

        new_p = Pauli.from_label('XY')

        p1.insert_paulis(indices=[0], paulis=new_p)

        self.assertTrue(p1 != self.ref_p)
        self.assertEqual(len(p1), 6)
        self.assertEqual(p1.to_label(), self.ref_label + 'XY')
Ejemplo n.º 14
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.º 15
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.º 16
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.º 17
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.º 18
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.º 19
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.º 20
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.º 21
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.º 22
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.º 23
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.º 24
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.º 25
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.º 26
0
def fermionic_maps(h1, h2, map_type, out_file=None, threshold=0.000000000001):
    """Creates a list of Paulis with coefficients from fermionic one and
    two-body operator.

    Args:
        h1 (list): second-quantized fermionic one-body operator
        h2 (list): second-quantized fermionic two-body operator
        map_type (str): "JORDAN_WIGNER", "PARITY", "BINARY_TREE"
        out_file (str): name of the optional file to write the Pauli list on
        threshold (float): threshold for Pauli simplification
    Returns:
        list: A list of Paulis with coefficients
    """
    # pylint: disable=invalid-name

    ####################################################################
    # ###########   DEFINING MAPPED FERMIONIC OPERATORS    #############
    ####################################################################

    pauli_list = []
    n = len(h1)  # number of fermionic modes / qubits
    a = []
    if map_type == 'JORDAN_WIGNER':
        for i in range(n):
            xv = np.append(np.append(np.ones(i), 0), np.zeros(n - i - 1))
            xw = np.append(np.append(np.zeros(i), 1), np.zeros(n - i - 1))
            yv = np.append(np.append(np.ones(i), 1), np.zeros(n - i - 1))
            yw = np.append(np.append(np.zeros(i), 1), np.zeros(n - i - 1))
            # defines the two mapped Pauli components of a_i and a_i^\dag,
            # according to a_i -> (a[i][0]+i*a[i][1])/2,
            # a_i^\dag -> (a_[i][0]-i*a[i][1])/2
            a.append((Pauli(xv, xw), Pauli(yv, yw)))
    if map_type == 'PARITY':
        for i in range(n):
            if i > 1:
                Xv = np.append(np.append(np.zeros(i - 1),
                                         [1, 0]), np.zeros(n - i - 1))
                Xw = np.append(np.append(np.zeros(i - 1),
                                         [0, 1]), np.ones(n - i - 1))
                Yv = np.append(np.append(np.zeros(i - 1),
                                         [0, 1]), np.zeros(n - i - 1))
                Yw = np.append(np.append(np.zeros(i - 1),
                                         [0, 1]), np.ones(n - i - 1))
            elif i > 0:
                Xv = np.append((1, 0), np.zeros(n - i - 1))
                Xw = np.append([0, 1], np.ones(n - i - 1))
                Yv = np.append([0, 1], np.zeros(n - i - 1))
                Yw = np.append([0, 1], np.ones(n - i - 1))
            else:
                Xv = np.append(0, np.zeros(n - i - 1))
                Xw = np.append(1, np.ones(n - i - 1))
                Yv = np.append(1, np.zeros(n - i - 1))
                Yw = np.append(1, np.ones(n - i - 1))
            # defines the two mapped Pauli components of a_i and a_i^\dag,
            # according to a_i -> (a[i][0]+i*a[i][1])/2,
            # a_i^\dag -> (a_[i][0]-i*a[i][1])/2
            a.append((Pauli(Xv, Xw), Pauli(Yv, Yw)))
    if map_type == 'BINARY_TREE':
        # 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
            # defines the two mapped Pauli components of a_i and a_i^\dag,
            # according to a_i -> (a[i][0]+i*a[i][1])/2, a_i^\dag ->
            # (a_[i][0]-i*a[i][1])/2
            a.append((update_pauli[j] * x_j * parity_pauli[j],
                      update_pauli[j] * y_j * remainder_pauli[j]))

    ####################################################################
    # ###########    BUILDING THE MAPPED HAMILTONIAN     ###############
    ####################################################################

    # ######################    One-body    #############################
    for i in range(n):
        for j in range(n):
            if h1[i, j] != 0:
                for alpha in range(2):
                    for beta in range(2):
                        pauli_prod = sgn_prod(a[i][alpha], a[j][beta])
                        pauli_term = [h1[i, j] * 1 / 4 * pauli_prod[1] *
                                      np.power(-1j, alpha) *
                                      np.power(1j, beta),
                                      pauli_prod[0]]
                        pauli_list = pauli_term_append(
                            pauli_term, pauli_list, threshold)

    # ######################    Two-body    ############################
    for i in range(n):
        for j in range(n):
            for k in range(n):
                for m in range(n):
                    if h2[i, j, k, m] != 0:
                        for alpha in range(2):
                            for beta in range(2):
                                for gamma in range(2):
                                    for delta in range(2):
                                        # Note: chemists' notation for the
                                        # labeling,
                                        # h2(i,j,k,m) adag_i adag_k a_m a_j
                                        pauli_prod_1 = sgn_prod(
                                            a[i][alpha], a[k][beta])
                                        pauli_prod_2 = sgn_prod(
                                            pauli_prod_1[0], a[m][gamma])
                                        pauli_prod_3 = sgn_prod(
                                            pauli_prod_2[0], a[j][delta])

                                        phase1 = pauli_prod_1[1] *\
                                            pauli_prod_2[1] * pauli_prod_3[1]
                                        phase2 = np.power(-1j, alpha + beta) *\
                                            np.power(1j, gamma + delta)

                                        pauli_term = [
                                            h2[i, j, k, m] * 1 / 16 * phase1 *
                                            phase2, pauli_prod_3[0]]

                                        pauli_list = pauli_term_append(
                                            pauli_term, pauli_list, threshold)

    ####################################################################
    # ################          WRITE TO FILE         ##################
    ####################################################################

    if out_file is not None:
        out_stream = open(out_file, 'w')
        for pauli_term in pauli_list:
            out_stream.write(pauli_term[1].to_label() + '\n')
            out_stream.write('%.15f' % pauli_term[0].real + '\n')
        out_stream.close()
    return pauli_list
Ejemplo n.º 27
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.º 28
0
def fermionic_maps(h1, h2, map_type, out_file=None, threshold=0.000000000001):
    """Creates a list of Paulis with coefficients from fermionic one and
    two-body operator.

    Args:
        h1 (list): second-quantized fermionic one-body operator
        h2 (list): second-quantized fermionic two-body operator
        map_type (str): "JORDAN_WIGNER", "PARITY", "BINARY_TREE"
        out_file (str): name of the optional file to write the Pauli list on
        threshold (float): threshold for Pauli simplification
    Returns:
        list: A list of Paulis with coefficients
    """
    # pylint: disable=invalid-name

    ####################################################################
    # ###########   DEFINING MAPPED FERMIONIC OPERATORS    #############
    ####################################################################

    pauli_list = []
    n = len(h1)  # number of fermionic modes / qubits
    a = []
    if map_type == 'JORDAN_WIGNER':
        for i in range(n):
            xv = np.append(np.append(np.ones(i), 0), np.zeros(n - i - 1))
            xw = np.append(np.append(np.zeros(i), 1), np.zeros(n - i - 1))
            yv = np.append(np.append(np.ones(i), 1), np.zeros(n - i - 1))
            yw = np.append(np.append(np.zeros(i), 1), np.zeros(n - i - 1))
            # defines the two mapped Pauli components of a_i and a_i^\dag,
            # according to a_i -> (a[i][0]+i*a[i][1])/2,
            # a_i^\dag -> (a_[i][0]-i*a[i][1])/2
            a.append((Pauli(xv, xw), Pauli(yv, yw)))
    if map_type == 'PARITY':
        for i in range(n):
            if i > 1:
                Xv = np.append(np.append(np.zeros(i - 1),
                                         [1, 0]), np.zeros(n - i - 1))
                Xw = np.append(np.append(np.zeros(i - 1),
                                         [0, 1]), np.ones(n - i - 1))
                Yv = np.append(np.append(np.zeros(i - 1),
                                         [0, 1]), np.zeros(n - i - 1))
                Yw = np.append(np.append(np.zeros(i - 1),
                                         [0, 1]), np.ones(n - i - 1))
            elif i > 0:
                Xv = np.append((1, 0), np.zeros(n - i - 1))
                Xw = np.append([0, 1], np.ones(n - i - 1))
                Yv = np.append([0, 1], np.zeros(n - i - 1))
                Yw = np.append([0, 1], np.ones(n - i - 1))
            else:
                Xv = np.append(0, np.zeros(n - i - 1))
                Xw = np.append(1, np.ones(n - i - 1))
                Yv = np.append(1, np.zeros(n - i - 1))
                Yw = np.append(1, np.ones(n - i - 1))
            # defines the two mapped Pauli components of a_i and a_i^\dag,
            # according to a_i -> (a[i][0]+i*a[i][1])/2,
            # a_i^\dag -> (a_[i][0]-i*a[i][1])/2
            a.append((Pauli(Xv, Xw), Pauli(Yv, Yw)))
    if map_type == 'BINARY_TREE':
        # 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
            # defines the two mapped Pauli components of a_i and a_i^\dag,
            # according to a_i -> (a[i][0]+i*a[i][1])/2, a_i^\dag ->
            # (a_[i][0]-i*a[i][1])/2
            a.append((update_pauli[j] * x_j * parity_pauli[j],
                      update_pauli[j] * y_j * remainder_pauli[j]))

    ####################################################################
    # ###########    BUILDING THE MAPPED HAMILTONIAN     ###############
    ####################################################################

    # ######################    One-body    #############################
    for i in range(n):
        for j in range(n):
            if h1[i, j] != 0:
                for alpha in range(2):
                    for beta in range(2):
                        pauli_prod = sgn_prod(a[i][alpha], a[j][beta])
                        pauli_term = [h1[i, j] * 1 / 4 * pauli_prod[1] *
                                      np.power(-1j, alpha) *
                                      np.power(1j, beta),
                                      pauli_prod[0]]
                        pauli_list = pauli_term_append(
                            pauli_term, pauli_list, threshold)

    # ######################    Two-body    ############################
    for i in range(n):
        for j in range(n):
            for k in range(n):
                for m in range(n):
                    if h2[i, j, k, m] != 0:
                        for alpha in range(2):
                            for beta in range(2):
                                for gamma in range(2):
                                    for delta in range(2):
                                        # Note: chemists' notation for the
                                        # labeling,
                                        # h2(i,j,k,m) adag_i adag_k a_m a_j
                                        pauli_prod_1 = sgn_prod(
                                            a[i][alpha], a[k][beta])
                                        pauli_prod_2 = sgn_prod(
                                            pauli_prod_1[0], a[m][gamma])
                                        pauli_prod_3 = sgn_prod(
                                            pauli_prod_2[0], a[j][delta])

                                        phase1 = pauli_prod_1[1] *\
                                            pauli_prod_2[1] * pauli_prod_3[1]
                                        phase2 = np.power(-1j, alpha + beta) *\
                                            np.power(1j, gamma + delta)

                                        pauli_term = [
                                            h2[i, j, k, m] * 1 / 16 * phase1 *
                                            phase2, pauli_prod_3[0]]

                                        pauli_list = pauli_term_append(
                                            pauli_term, pauli_list, threshold)

    ####################################################################
    # ################          WRITE TO FILE         ##################
    ####################################################################

    if out_file is not None:
        out_stream = open(out_file, 'w')
        for pauli_term in pauli_list:
            out_stream.write(pauli_term[1].to_label() + '\n')
            out_stream.write('%.15f' % pauli_term[0].real + '\n')
        out_stream.close()
    return pauli_list
Ejemplo n.º 29
0
class TestPauli(QiskitTestCase):
    """Tests for Pauli class"""

    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)

    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')

    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')

    def test_random_pauli5(self):
        length = 2
        q = random_pauli(length)
        self.log.info(q)
        self.assertEqual(q.numberofqubits, length)
        self.assertEqual(len(q.v), length)
        self.assertEqual(len(q.w), length)
        self.assertEqual(len(q.to_label()), length)
        self.assertEqual(len(q.to_matrix()), 2 ** length)

    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)

    def test_pauli_invert(self):
        self.log.info("===== p3 =====")
        self.log.info(self.p3)
        self.assertEqual(str(self.p3), 'v = 1.0\t0.0\t1.0\t\nw = 0.0\t1.0\t1.0\t')

        self.log.info("\tIn label form:")
        self.log.info(self.p3.to_label())
        self.assertEqual(self.p3.to_label(), 'ZXY')

        self.log.info("\tIn matrix form:")
        self.log.info(self.p3.to_matrix())
        m = np.array([
            [0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. - 1.j, 0. + 0.j],
            [0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 1.j],
            [0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. - 1.j, 0. + 0.j, 0. + 0.j, 0. + 0.j],
            [0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 1.j, 0. + 0.j, 0. + 0.j],
            [0. + 0.j, 0. + 0.j, 0. + 1.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j],
            [0. + 0.j, 0. - 0.j, 0. + 0.j, 0. - 1.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j],
            [0. + 1.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j],
            [0. + 0.j, 0. - 1.j, 0. + 0.j, 0. - 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j]])
        self.assertTrue((self.p3.to_matrix() == m).all())

        self.log.info("\tIn spatrix matrix form:")
        self.log.info(self.p3.to_spmatrix())
        self.assertTrue((self.p3.to_spmatrix().toarray() == m).all())

        self.log.info("===== r =====")
        r = inverse_pauli(self.p3)
        self.assertEqual(str(r), 'v = 1.0\t0.0\t1.0\t\nw = 0.0\t1.0\t1.0\t')

        self.log.info("In label form:")
        self.log.info(r.to_label())
        self.assertEqual(r.to_label(), 'ZXY')

        self.log.info("\tIn matrix form:")
        self.assertTrue((r.to_matrix() == m).all())

    def test_pauli_group(self):
        self.log.info("Group in tensor order:")
        expected = ['III', 'XII', 'YII', 'ZII', 'IXI', 'XXI', 'YXI', 'ZXI', 'IYI', 'XYI', 'YYI',
                    'ZYI', 'IZI', 'XZI', 'YZI', 'ZZI', 'IIX', 'XIX', 'YIX', 'ZIX', 'IXX', 'XXX',
                    'YXX', 'ZXX', 'IYX', 'XYX', 'YYX', 'ZYX', 'IZX', 'XZX', 'YZX', 'ZZX', 'IIY',
                    'XIY', 'YIY', 'ZIY', 'IXY', 'XXY', 'YXY', 'ZXY', 'IYY', 'XYY', 'YYY', 'ZYY',
                    'IZY', 'XZY', 'YZY', 'ZZY', 'IIZ', 'XIZ', 'YIZ', 'ZIZ', 'IXZ', 'XXZ', 'YXZ',
                    'ZXZ', 'IYZ', 'XYZ', 'YYZ', 'ZYZ', 'IZZ', 'XZZ', 'YZZ', 'ZZZ']
        grp = pauli_group(3, case=1)
        for j in grp:
            self.log.info('==== j (tensor order) ====')
            self.log.info(j.to_label())
            self.assertEqual(expected.pop(0), j.to_label())

        self.log.info("Group in weight order:")
        expected = ['III', 'XII', 'YII', 'ZII', 'IXI', 'IYI', 'IZI', 'IIX', 'IIY', 'IIZ', 'XXI',
                    'YXI', 'ZXI', 'XYI', 'YYI', 'ZYI', 'XZI', 'YZI', 'ZZI', 'XIX', 'YIX', 'ZIX',
                    'IXX', 'IYX', 'IZX', 'XIY', 'YIY', 'ZIY', 'IXY', 'IYY', 'IZY', 'XIZ', 'YIZ',
                    'ZIZ', 'IXZ', 'IYZ', 'IZZ', 'XXX', 'YXX', 'ZXX', 'XYX', 'YYX', 'ZYX', 'XZX',
                    'YZX', 'ZZX', 'XXY', 'YXY', 'ZXY', 'XYY', 'YYY', 'ZYY', 'XZY', 'YZY', 'ZZY',
                    'XXZ', 'YXZ', 'ZXZ', 'XYZ', 'YYZ', 'ZYZ', 'XZZ', 'YZZ', 'ZZZ']
        grp = pauli_group(3)
        for j in grp:
            self.log.info('==== j (weight order) ====')
            self.log.info(j.to_label())
            self.assertEqual(expected.pop(0), j.to_label())

    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)

    def test_equality_equal(self):
        """Test equality operator: equal Paulis"""
        p1 = self.p3
        p2 = deepcopy(p1)

        self.log.info(p1 == p2)
        self.assertTrue(p1 == p2)

        self.log.info(p2.to_label())
        self.log.info(p1.to_label())
        self.assertEqual(p1.to_label(), 'ZXY')
        self.assertEqual(p2.to_label(), 'ZXY')

    def test_equality_different(self):
        """Test equality operator: different Paulis"""
        p1 = self.p3
        p2 = deepcopy(p1)

        p2.v[0] = (p1.v[0] + 1) % 2
        self.log.info(p1 == p2)
        self.assertFalse(p1 == p2)

        self.log.info(p2.to_label())
        self.log.info(p1.to_label())
        self.assertEqual(p1.to_label(), 'ZXY')
        self.assertEqual(p2.to_label(), 'IXY')

    def test_inequality_equal(self):
        """Test inequality operator: equal Paulis"""
        p1 = self.p3
        p2 = deepcopy(p1)

        self.log.info(p1 != p2)
        self.assertFalse(p1 != p2)

        self.log.info(p2.to_label())
        self.log.info(p1.to_label())
        self.assertEqual(p1.to_label(), 'ZXY')
        self.assertEqual(p2.to_label(), 'ZXY')

    def test_inequality_different(self):
        """Test inequality operator: different Paulis"""
        p1 = self.p3
        p2 = deepcopy(p1)

        p2.v[0] = (p1.v[0] + 1) % 2
        self.log.info(p1 != p2)
        self.assertTrue(p1 != p2)

        self.log.info(p2.to_label())
        self.log.info(p1.to_label())
        self.assertEqual(p1.to_label(), 'ZXY')
        self.assertEqual(p2.to_label(), 'IXY')

    def test_pauli_singles(self):
        qubit_index = 3
        num_qubits = 5
        ps = pauli_singles(qubit_index, num_qubits)
        self.assertEqual(ps[0].to_label(), 'IIXII')
        self.assertEqual(ps[1].to_label(), 'IIYII')
        self.assertEqual(ps[2].to_label(), 'IIZII')
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
Ejemplo n.º 31
0
def fermionic_maps(h1,h2,map_type,out_file=None,threshold=0.000000000001):


    """ Takes fermionic one and two-body operators in the form of numpy arrays with real entries, e.g.
        h1=np.zeros((n,n))
        h2=np.zeros((n,n,n,n))
        where n is the number of fermionic modes, and gives a pauli_list of mapped pauli terms and
        coefficients, according to the map_type specified, with values

        map_type:
        JORDAN_WIGNER
        PARITY
        BINARY_TREE

        the notation for the two-body operator is the chemists' one,
        h2(i,j,k,m) a^dag_i a^dag_k a_m a_j

        Options:
        - writes the mapped pauli_list to a file named out_file given as an input (does not do this as default)
        - neglects mapped terms below a threshold defined by the user (default is 10^-12)

    """

    pauli_list=[]

    n=len(h1) # number of fermionic modes / qubits

    """
    ####################################################################
    ############   DEFINING MAPPED FERMIONIC OPERATORS    ##############
    ####################################################################
    """

    a=[]

    if map_type=='JORDAN_WIGNER':

        for i in range(n):


            Xv=np.append(np.append(np.ones(i),0),np.zeros(n-i-1))
            Xw=np.append(np.append(np.zeros(i),1),np.zeros(n-i-1))
            Yv=np.append(np.append(np.ones(i),1),np.zeros(n-i-1))
            Yw=np.append(np.append(np.zeros(i),1),np.zeros(n-i-1))

            # defines the two mapped Pauli components of a_i and a_i^\dag, according to a_i -> (a[i][0]+i*a[i][1])/2, a_i^\dag -> (a_[i][0]-i*a[i][1])/2
            a.append((Pauli(Xv,Xw),Pauli(Yv,Yw)))


    if map_type=='PARITY':

        for i in range(n):

            if i>1:

                Xv=np.append(np.append(np.zeros(i-1),[1,0]),np.zeros(n-i-1))
                Xw=np.append(np.append(np.zeros(i-1),[0,1]),np.ones(n-i-1))
                Yv=np.append(np.append(np.zeros(i-1),[0,1]),np.zeros(n-i-1))
                Yw=np.append(np.append(np.zeros(i-1),[0,1]),np.ones(n-i-1))

            elif i>0:

                Xv=np.append((1,0),np.zeros(n-i-1))
                Xw=np.append([0,1],np.ones(n-i-1))
                Yv=np.append([0,1],np.zeros(n-i-1))
                Yw=np.append([0,1],np.ones(n-i-1))

            else:

                Xv=np.append(0,np.zeros(n-i-1))
                Xw=np.append(1,np.ones(n-i-1))
                Yv=np.append(1,np.zeros(n-i-1))
                Yw=np.append(1,np.ones(n-i-1))

            # defines the two mapped Pauli components of a_i and a_i^\dag, according to a_i -> (a[i][0]+i*a[i][1])/2, a_i^\dag -> (a_[i][0]-i*a[i][1])/2
            a.append((Pauli(Xv,Xw),Pauli(Yv,Yw)))


    if map_type=='BINARY_TREE':


        # 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=[]
        flip_pauli=[]

        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

            Xj=Pauli(np.zeros(n),np.zeros(n))
            Xj.w[j]=1
            Yj=Pauli(np.zeros(n),np.zeros(n))
            Yj.v[j]=1
            Yj.w[j]=1

            # defines the two mapped Pauli components of a_i and a_i^\dag, according to a_i -> (a[i][0]+i*a[i][1])/2, a_i^\dag -> (a_[i][0]-i*a[i][1])/2
            a.append((update_pauli[j]*Xj*parity_pauli[j],update_pauli[j]*Yj*remainder_pauli[j]))


    """
    ####################################################################
    ############    BUILDING THE MAPPED HAMILTONIAN     ################
    ####################################################################
    """


    """
    #######################    One-body    #############################
    """

    for i in range(n):
        for j in range(n):
            if h1[i,j]!=0:
                for alpha in range(2):
                    for beta in range(2):

                            pauli_prod=sgn_prod(a[i][alpha],a[j][beta])
                            pauli_term=[  h1[i,j]*1/4*pauli_prod[1]*np.power(-1j,alpha)*np.power(1j,beta),  pauli_prod[0]  ]
                            pauli_list=pauli_term_append(pauli_term,pauli_list,threshold)



    """
    #######################    Two-body    #############################
    """

    for i in range(n):
        for j in range(n):
            for k in range(n):
                for m in range(n):

                    if h2[i,j,k,m]!=0:

                        for alpha in range(2):
                            for beta in range(2):
                                for gamma in range(2):
                                    for delta in range(2):

                                        """
                                        # Note: chemists' notation for the labeling, h2(i,j,k,m) adag_i adag_k a_m a_j
                                        """

                                        pauli_prod_1=sgn_prod(a[i][alpha],a[k][beta])
                                        pauli_prod_2=sgn_prod(pauli_prod_1[0],a[m][gamma])
                                        pauli_prod_3=sgn_prod(pauli_prod_2[0],a[j][delta])

                                        phase1=pauli_prod_1[1]*pauli_prod_2[1]*pauli_prod_3[1]
                                        phase2=np.power(-1j,alpha+beta)*np.power(1j,gamma+delta)

                                        pauli_term=[h2[i,j,k,m]*1/16*phase1*phase2,pauli_prod_3[0]]

                                        pauli_list=pauli_term_append(pauli_term,pauli_list,threshold)


    """
    ####################################################################
    #################          WRITE TO FILE         ###################
    ####################################################################
    """


    if out_file!= None:
        out_stream=open(out_file,'w')

        for pauli_term in pauli_list:
            out_stream.write(pauli_term[1].to_label()+'\n')
            out_stream.write('%.15f' % pauli_term[0].real+'\n')

        out_stream.close()

    return pauli_list
Ejemplo n.º 32
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.º 33
0
class TestPauli(QiskitTestCase):
    """Tests for Pauli class"""

    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)

    def test_random_pauli5(self):
        length = 2
        q = random_pauli(length)
        self.log.info(q)
        self.assertEqual(q.numberofqubits, length)
        self.assertEqual(len(q.v), length)
        self.assertEqual(len(q.w), length)
        self.assertEqual(len(q.to_label()), length)
        self.assertEqual(len(q.to_matrix()), 2 ** length)

    def test_pauli_invert(self):
        self.log.info("===== p3 =====")
        self.log.info(self.p3)
        self.assertEqual(str(self.p3), 'v = 1.0\t0.0\t1.0\t\nw = 0.0\t1.0\t1.0\t')

        self.log.info("\tIn label form:")
        self.log.info(self.p3.to_label())
        self.assertEqual(self.p3.to_label(), 'ZXY')

        self.log.info("\tIn matrix form:")
        self.log.info(self.p3.to_matrix())
        m = np.array([
            [0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. - 1.j, 0. + 0.j],
            [0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 1.j],
            [0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. - 1.j, 0. + 0.j, 0. + 0.j, 0. + 0.j],
            [0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 1.j, 0. + 0.j, 0. + 0.j],
            [0. + 0.j, 0. + 0.j, 0. + 1.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j],
            [0. + 0.j, 0. - 0.j, 0. + 0.j, 0. - 1.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j],
            [0. + 1.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j],
            [0. + 0.j, 0. - 1.j, 0. + 0.j, 0. - 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j]])
        self.assertTrue((self.p3.to_matrix() == m).all())

        self.log.info("===== r =====")
        r = inverse_pauli(self.p3)
        self.assertEqual(str(r), 'v = 1.0\t0.0\t1.0\t\nw = 0.0\t1.0\t1.0\t')

        self.log.info("In label form:")
        self.log.info(r.to_label())
        self.assertEqual(r.to_label(), 'ZXY')

        self.log.info("\tIn matrix form:")
        self.assertTrue((r.to_matrix() == m).all())

    def test_pauli_group(self):
        self.log.info("Group in tensor order:")
        expected = ['III', 'XII', 'YII', 'ZII', 'IXI', 'XXI', 'YXI', 'ZXI', 'IYI', 'XYI', 'YYI',
                    'ZYI', 'IZI', 'XZI', 'YZI', 'ZZI', 'IIX', 'XIX', 'YIX', 'ZIX', 'IXX', 'XXX',
                    'YXX', 'ZXX', 'IYX', 'XYX', 'YYX', 'ZYX', 'IZX', 'XZX', 'YZX', 'ZZX', 'IIY',
                    'XIY', 'YIY', 'ZIY', 'IXY', 'XXY', 'YXY', 'ZXY', 'IYY', 'XYY', 'YYY', 'ZYY',
                    'IZY', 'XZY', 'YZY', 'ZZY', 'IIZ', 'XIZ', 'YIZ', 'ZIZ', 'IXZ', 'XXZ', 'YXZ',
                    'ZXZ', 'IYZ', 'XYZ', 'YYZ', 'ZYZ', 'IZZ', 'XZZ', 'YZZ', 'ZZZ']
        grp = pauli_group(3, case=1)
        for j in grp:
            self.log.info('==== j (tensor order) ====')
            self.log.info(j.to_label())
            self.assertEqual(expected.pop(0), j.to_label())

        self.log.info("Group in weight order:")
        expected = ['III', 'XII', 'YII', 'ZII', 'IXI', 'IYI', 'IZI', 'IIX', 'IIY', 'IIZ', 'XXI',
                    'YXI', 'ZXI', 'XYI', 'YYI', 'ZYI', 'XZI', 'YZI', 'ZZI', 'XIX', 'YIX', 'ZIX',
                    'IXX', 'IYX', 'IZX', 'XIY', 'YIY', 'ZIY', 'IXY', 'IYY', 'IZY', 'XIZ', 'YIZ',
                    'ZIZ', 'IXZ', 'IYZ', 'IZZ', 'XXX', 'YXX', 'ZXX', 'XYX', 'YYX', 'ZYX', 'XZX',
                    'YZX', 'ZZX', 'XXY', 'YXY', 'ZXY', 'XYY', 'YYY', 'ZYY', 'XZY', 'YZY', 'ZZY',
                    'XXZ', 'YXZ', 'ZXZ', 'XYZ', 'YYZ', 'ZYZ', 'XZZ', 'YZZ', 'ZZZ']
        grp = pauli_group(3)
        for j in grp:
            self.log.info('==== j (weight order) ====')
            self.log.info(j.to_label())
            self.assertEqual(expected.pop(0), j.to_label())

    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)

    def test_equality_equal(self):
        """Test equality operator: equal Paulis"""
        p1 = self.p3
        p2 = deepcopy(p1)

        self.log.info(p1 == p2)
        self.assertTrue(p1 == p2)

        self.log.info(p2.to_label())
        self.log.info(p1.to_label())
        self.assertEqual(p1.to_label(), 'ZXY')
        self.assertEqual(p2.to_label(), 'ZXY')

    def test_equality_different(self):
        """Test equality operator: different Paulis"""
        p1 = self.p3
        p2 = deepcopy(p1)

        p2.v[0] = (p1.v[0] + 1) % 2
        self.log.info(p1 == p2)
        self.assertFalse(p1 == p2)

        self.log.info(p2.to_label())
        self.log.info(p1.to_label())
        self.assertEqual(p1.to_label(), 'ZXY')
        self.assertEqual(p2.to_label(), 'IXY')

    def test_inequality_equal(self):
        """Test inequality operator: equal Paulis"""
        p1 = self.p3
        p2 = deepcopy(p1)

        self.log.info(p1 != p2)
        self.assertFalse(p1 != p2)

        self.log.info(p2.to_label())
        self.log.info(p1.to_label())
        self.assertEqual(p1.to_label(), 'ZXY')
        self.assertEqual(p2.to_label(), 'ZXY')

    def test_inequality_different(self):
        """Test inequality operator: different Paulis"""
        p1 = self.p3
        p2 = deepcopy(p1)

        p2.v[0] = (p1.v[0] + 1) % 2
        self.log.info(p1 != p2)
        self.assertTrue(p1 != p2)

        self.log.info(p2.to_label())
        self.log.info(p1.to_label())
        self.assertEqual(p1.to_label(), 'ZXY')
        self.assertEqual(p2.to_label(), 'IXY')
Ejemplo n.º 34
0
def two_qubit_reduction(ham_in, m, out_file=None, threshold=0.000000000001):
    """
    Eliminates the central and last qubit in a list of Pauli that has
    diagonal operators (Z,I) at those positions.abs

    It can be used to taper two qubits in parity and binary-tree mapped
    fermionic Hamiltonians when the spin orbitals are ordered in two spin
    sectors, according to the number of particles in the system.

    Args:
        ham_in (list): a list of Paulis representing the mapped fermionic
            Hamiltonian
        m (int): number of fermionic particles
        out_file (string or None): name of the optional file to write the Pauli
            list on
        threshold (float): threshold for Pauli simplification
    Returns:
        list: A tapered Hamiltonian in the form of list of Paulis with
            coefficients
    """
    ham_out = []
    if m % 4 == 0:
        par_1 = 1
        par_2 = 1
    elif m % 4 == 1:
        par_1 = -1
        par_2 = -1    # could be also +1, +1/-1 are  spin-parity sectors
    elif m % 4 == 2:
        par_1 = 1
        par_2 = -1
    else:
        par_1 = -1
        par_2 = -1    # could be also +1, +1/-1 are  spin-parity sectors
    if isinstance(ham_in, str):
        # conversion from Hamiltonian text file to pauli_list
        ham_in = Hamiltonian_from_file(ham_in)
    # number of qubits
    n = len(ham_in[0][1].v)
    for pauli_term in ham_in:  # loop over Pauli terms
        coeff_out = pauli_term[0]
        # Z operator encountered at qubit n/2-1
        if pauli_term[1].v[n // 2 -
                           1] == 1 and pauli_term[1].w[n // 2 - 1] == 0:
            coeff_out = par_2 * coeff_out
        # Z operator encountered at qubit n-1
        if pauli_term[1].v[n - 1] == 1 and pauli_term[1].w[n - 1] == 0:
            coeff_out = par_1 * coeff_out
        v_temp = []
        w_temp = []
        for j in range(n):
            if j != n // 2 - 1 and j != n - 1:
                v_temp.append(pauli_term[1].v[j])
                w_temp.append(pauli_term[1].w[j])
        pauli_term_out = [coeff_out, Pauli(v_temp, w_temp)]
        ham_out = pauli_term_append(pauli_term_out, ham_out, threshold)

    ####################################################################
    # ################          WRITE TO FILE         ##################
    ####################################################################

    if out_file is not None:
        out_stream = open(out_file, 'w')
        for pauli_term in ham_out:
            out_stream.write(pauli_term[1].to_label() + '\n')
            out_stream.write('%.15f' % pauli_term[0].real + '\n')
        out_stream.close()
    return ham_out
Ejemplo n.º 35
0
    def test_hamiltonian(self):
        # pylint: disable=unexpected-keyword-arg
        # 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]]

        expected_result = [
            [(-0.245224693812+0j), 0j, 0j, (0.180931339345+0j)],
            [0j, (-1.06365601685+0j), (0.180931339345+0j), 0j],
            [0j, (0.180931339345+0j), (-1.06365601685+0j), 0j],
            [(0.180931339345+0j), 0j, 0j, (-1.83696751499+0j)]
        ]

        for i in range(4):
            with self.subTest(i=i):
                for result, expected in zip(hamiltonian[i], expected_result[i]):
                    self.assertAlmostEqual(result, expected)

        # 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.º 36
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)