Ejemplo n.º 1
0
def plot_state_paulivec(rho, title=""):
    """Plot the paulivec representation of a quantum state.

    Plot a bargraph of the mixed state rho over the pauli matricies

    Args:
        rho (np.array[[complex]]): array of dimensions 2**n x 2**nn complex
                                   numbers
        title (str): a string that represents the plot title

    Returns:
        none: plot is shown with matplotlib to the screen

    """
    num = int(np.log2(len(rho)))
    labels = list(map(lambda x: x.to_label(), pauli_group(num)))
    values = list(map(lambda x: np.real(np.trace(np.dot(x.to_matrix(), rho))),
                      pauli_group(num)))
    numelem = len(values)
    ind = np.arange(numelem)  # the x locations for the groups
    width = 0.5  # the width of the bars
    fig, ax = plt.subplots()
    ax.grid(zorder=0)
    ax.bar(ind, values, width, color='seagreen')

    # add some text for labels, title, and axes ticks
    ax.set_ylabel('Expectation value', fontsize=12)
    ax.set_xticks(ind)
    ax.set_yticks([-1, -0.5, 0, 0.5, 1])
    ax.set_xticklabels(labels, fontsize=12, rotation=70)
    ax.set_xlabel('Pauli', fontsize=12)
    ax.set_ylim([-1, 1])
    plt.title(title)
    plt.show()
Ejemplo n.º 2
0
def plot_state_paulivec(rho, title=""):
    """Plot the paulivec representation of a quantum state.

    Plot a bargraph of the mixed state rho over the pauli matricies

    Args:
        rho (np.array[[complex]]): array of dimensions 2**n x 2**nn complex
                                   numbers
        title (str): a string that represents the plot title

    Returns:
        none: plot is shown with matplotlib to the screen

    """
    num = int(np.log2(len(rho)))
    labels = list(map(lambda x: x.to_label(), pauli_group(num)))
    values = list(
        map(lambda x: np.real(np.trace(np.dot(x.to_matrix(), rho))),
            pauli_group(num)))
    numelem = len(values)
    ind = np.arange(numelem)  # the x locations for the groups
    width = 0.5  # the width of the bars
    fig, ax = plt.subplots()
    ax.grid(zorder=0)
    ax.bar(ind, values, width, color='seagreen')

    # add some text for labels, title, and axes ticks
    ax.set_ylabel('Expectation value', fontsize=12)
    ax.set_xticks(ind)
    ax.set_yticks([-1, -0.5, 0, 0.5, 1])
    ax.set_xticklabels(labels, fontsize=12, rotation=70)
    ax.set_xlabel('Pauli', fontsize=12)
    ax.set_ylim([-1, 1])
    plt.title(title)
    plt.show()
Ejemplo n.º 3
0
def vectorize(density_matrix, method='col'):
    """Flatten an operator to a vector in a specified basis.

    Args:
        density_matrix (ndarray): a density matrix.
        method (str): the method of vectorization. Allowed values are
            - 'col' (default) flattens to column-major vector.
            - 'row' flattens to row-major vector.
            - 'pauli'flattens in the n-qubit Pauli basis.
            - 'pauli-weights': flattens in the n-qubit Pauli basis ordered by
               weight.

    Returns:
        ndarray: the resulting vector.
    Raises:
        Exception: if input state is not a n-qubit state
    """
    density_matrix = np.array(density_matrix)
    if method == 'col':
        return density_matrix.flatten(order='F')
    elif method == 'row':
        return density_matrix.flatten(order='C')
    elif method in ['pauli', 'pauli_weights']:
        num = int(np.log2(len(density_matrix)))  # number of qubits
        if len(density_matrix) != 2**num:
            raise Exception('Input state must be n-qubit state')
        if method == 'pauli_weights':
            pgroup = pauli_group(num, case=0)
        else:
            pgroup = pauli_group(num, case=1)
        vals = [np.trace(np.dot(p.to_matrix(), density_matrix))
                for p in pgroup]
        return np.array(vals)
    return None
Ejemplo n.º 4
0
    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())
Ejemplo n.º 5
0
def devectorize(vec, method='col'):
    """Devectorize a vectorized square matrix.

    Args:
        vec (ndarray): a vectorized density matrix.
        basis (str): the method of devectorizaation. Allowed values are
            - 'col' (default): flattens to column-major vector.
            - 'row': flattens to row-major vector.
            - 'pauli': flattens in the n-qubit Pauli basis.
            - 'pauli-weights': flattens in the n-qubit Pauli basis ordered by
               weight.

    Returns:
        ndarray: the resulting matrix.

    """
    vec = np.array(vec)
    d = int(np.sqrt(vec.size))  # the dimension of the matrix
    if len(vec) != d*d:
        raise Exception('Input is not a vectorized square matrix')

    if method == 'col':
        return vec.reshape(d, d, order='F')
    elif method == 'row':
        return vec.reshape(d, d, order='C')
    elif method in ['pauli', 'pauli_weights']:
        num = int(np.log2(d))  # number of qubits
        if d != 2 ** num:
            raise Exception('Input state must be n-qubit state')
        if method is 'pauli_weights':
            pgroup = pauli_group(num, case=0)
        else:
            pgroup = pauli_group(num, case=1)
        pbasis = np.array([p.to_matrix() for p in pgroup]) / 2 ** num
        return np.tensordot(vec, pbasis, axes=1)
Ejemplo n.º 6
0
def process_data(rho):
    """ Sort rho data """
    result = dict()

    num = int(np.log2(len(rho)))
    labels = list(map(lambda x: x.to_label(), pauli_group(num)))
    values = list(
        map(lambda x: np.real(np.trace(np.dot(x.to_matrix(), rho))),
            pauli_group(num)))

    for position, label in enumerate(labels):
        result[label] = values[position]
    return result
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 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())
Ejemplo n.º 9
0
def choi_to_rauli(choi, order=1):
    """
    Convert a Choi-matrix to a Pauli-basis superoperator.

    Note that this function assumes that the Choi-matrix
    is defined in the standard column-stacking converntion
    and is normalized to have trace 1. For a channel E this
    is defined as: choi = (I \otimes E)(bell_state).

    The resulting 'rauli' R acts on input states as
    |rho_out>_p = R.|rho_in>_p
    where |rho> = vectorize(rho, method='pauli') for order=1
    and |rho> = vectorize(rho, method='pauli_weights') for order=0.

    Args:
        choi (matrix): the input Choi-matrix.
        order (int): ordering of the Pauli group vector.
            order=1 (default) is standard lexicographic ordering.
                Eg: [II, IX, IY, IZ, XI, XX, XY,...]
            order=0 is ordered by weights.
                Eg. [II, IX, IY, IZ, XI, XY, XZ, XX, XY,...]

    Returns:
        np.array: A superoperator in the Pauli basis.
    """
    # get number of qubits'
    num_qubits = int(np.log2(np.sqrt(len(choi))))
    pgp = pauli_group(num_qubits, case=order)
    rauli = []
    for i in pgp:
        for j in pgp:
            pauliop = np.kron(j.to_matrix().T, i.to_matrix())
            rauli += [np.trace(np.dot(choi, pauliop))]
    return np.array(rauli).reshape(4 ** num_qubits, 4 ** num_qubits)
Ejemplo n.º 10
0
def plot_state_paulivec(rho, title="", filename=None):
    """Plot the paulivec representation of a quantum state.

    Plot a bargraph of the mixed state rho over the pauli matrices

    Args:
        rho (np.array[[complex]]): array of dimensions 2**n x 2**nn complex
                                   numbers
        title (str): a string that represents the plot title
        filename (str): the output file to save the plot as. If specified it
            will save and exit and not open up the plot in a new window.

    """
    num = int(np.log2(len(rho)))
    labels = list(map(lambda x: x.to_label(), pauli_group(num)))
    values = list(
        map(lambda x: np.real(np.trace(np.dot(x.to_matrix(), rho))),
            pauli_group(num)))
    numelem = len(values)
    ind = np.arange(numelem)  # the x locations for the groups
    width = 0.5  # the width of the bars
    _, ax = plt.subplots()
    ax.grid(zorder=0)
    ax.bar(ind, values, width, color='seagreen')

    # add some text for labels, title, and axes ticks
    ax.set_ylabel('Expectation value', fontsize=12)
    ax.set_xticks(ind)
    ax.set_yticks([-1, -0.5, 0, 0.5, 1])
    ax.set_xticklabels(labels, fontsize=12, rotation=70)
    ax.set_xlabel('Pauli', fontsize=12)
    ax.set_ylim([-1, 1])
    plt.title(title)
    if filename:
        plt.savefig(filename)
    else:
        plt.show()
Ejemplo n.º 11
0
def devectorize(vectorized_mat, method='col'):
    """Devectorize a vectorized square matrix.

    Args:
        vectorized_mat (ndarray): a vectorized density matrix.
        method (str): the method of devectorization. Allowed values are
            - 'col' (default): flattens to column-major vector.
            - 'row': flattens to row-major vector.
            - 'pauli': flattens in the n-qubit Pauli basis.
            - 'pauli-weights': flattens in the n-qubit Pauli basis ordered by
               weight.

    Returns:
        ndarray: the resulting matrix.
    Raises:
        Exception: if input state is not a n-qubit state
    """
    vectorized_mat = np.array(vectorized_mat)
    dimension = int(np.sqrt(vectorized_mat.size))
    if len(vectorized_mat) != dimension * dimension:
        raise Exception('Input is not a vectorized square matrix')

    if method == 'col':
        return vectorized_mat.reshape(dimension, dimension, order='F')
    elif method == 'row':
        return vectorized_mat.reshape(dimension, dimension, order='C')
    elif method in ['pauli', 'pauli_weights']:
        num_qubits = int(np.log2(dimension))  # number of qubits
        if dimension != 2 ** num_qubits:
            raise Exception('Input state must be n-qubit state')
        if method == 'pauli_weights':
            pgroup = pauli_group(num_qubits, case=0)
        else:
            pgroup = pauli_group(num_qubits, case=1)
        pbasis = np.array([p.to_matrix() for p in pgroup]) / 2 ** num_qubits
        return np.tensordot(vectorized_mat, pbasis, axes=1)
    return None
Ejemplo n.º 12
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)