Example #1
0
def test_minimum_fidelity_over_amplitude_damping():
    r"""Test Minimum fidelity over amplitude-damping channel."""
    # Example obtained from Nielsen and Chaung.
    prob = np.arange(0., 1., 0.5)

    for p in prob:
        # With Kraus Operators
        k0 = np.array([[1., 0.], [0., np.sqrt(1. - p)]])
        k1 = np.array([[0., np.sqrt(p)], [0., 0.]])

        kraus = [k0, k1]
        chan = AnalyticQChan(kraus, [1, 1], 2, 2)
        desired = np.sqrt(1 - p)

        actual = chan.optimize_fidelity(n=1, maxiter=100)
        assert np.all(np.abs(desired - actual["optimal_val"]) < 1e-3)

        # With Choi-Matrix
        choi_mat = sum([
            np.outer(np.ravel(x, order="F"), np.conj(np.ravel(x, order="F")))
            for x in kraus
        ])
        chan = AnalyticQChan(choi_mat, [1, 1], 2, 2)
        actual = chan.optimize_fidelity(n=1, maxiter=100)
        assert np.all(np.abs(desired - actual["optimal_val"]) < 1e-3)
        assert_raises(AssertionError, chan.optimize_fidelity, 2)
Example #2
0
def test_minimum_fidelity_over_depolarizing_channel():
    r"""Test Minimum fidelity over depolarizing channel."""
    # Example obtained from nielsen and Chaung.
    prob = np.arange(0., 1., 0.01)

    for p in prob:
        # With Kraus Operators
        I = np.sqrt(1 - p) * np.array([[1., 0.], [0., 1.]])
        X = np.sqrt(p / 3.) * np.array([[0., 1.], [1., 0.]])
        Y = np.sqrt(p / 3.) * np.array([[0., complex(0., -1.)],
                                        [complex(0., 1.), 0.]])
        Z = np.sqrt(p / 3.) * np.array([[1., 0.], [0., -1.]])

        kraus = [I, X, Y, Z]
        chan = AnalyticQChan(kraus, [1, 1], 2, 2)
        desired = np.sqrt(1 - 2. * p / 3.)
        actual = chan.optimize_fidelity(n=1)
        assert np.all(np.abs(desired - actual["optimal_val"]) < 1e-5)

        # With Choi-Matrix
        choi_mat = sum([
            np.outer(np.ravel(x, order="F"), np.conj(np.ravel(x, order="F")))
            for x in kraus
        ])
        chan = AnalyticQChan(choi_mat, [1, 1], 2, 2)
        actual = chan.optimize_fidelity(n=1)
        assert np.all(np.abs(desired - actual["optimal_val"]) < 1e-5)
Example #3
0
def test_minimum_fidelity_over_bit_flip():
    r"""Test Minimum fidelity over bit-flip channel."""
    # Example obtained from "Quantum Computing Explained."
    prob = np.arange(0., 1., 0.01)

    for p in prob:
        # With Kraus Operators
        I = np.sqrt(1 - p) * np.array([[1., 0.], [0., 1.]])
        X = np.sqrt(p) * np.array([[0., 1.], [1., 0.]])

        kraus = [I, X]
        chan = AnalyticQChan(kraus, [1, 1], 2, 2)
        desired = np.sqrt(1 - p)
        actual = chan.optimize_fidelity()
        assert np.all(np.abs(desired - actual) < 1e-5)

        # With Choi-Matrix
        choi_mat = sum([
            np.outer(np.ravel(x, order="F"), np.conj(np.ravel(x, order="F")))
            for x in kraus
        ])
        chan = AnalyticQChan(choi_mat, [1, 1], 2, 2)
        actual = chan.optimize_fidelity()
        assert np.all(np.abs(desired - actual) < 1e-5)
Example #4
0
def test_minimum_fidelity_over_identity_channel():
    k0 = np.array([[1., 0.], [0., 1.]])
    chan = AnalyticQChan([k0], [1, 1], 2, 2)
    for n in range(1, 3):
        actual = chan.optimize_fidelity(n, maxiter=100)
        assert np.all(np.abs(1. - actual["optimal_val"]) < 1e-3)
Example #5
0
def effective_channel_with_stabilizers(stabilizer,
                                       code_param,
                                       pauli_errors,
                                       optimize="coherent",
                                       sparse=False,
                                       options=None):
    r"""
    Calculate the effective channel with respect to a set of pauli-errors and stabilizer elements.

    Parameters
    ----------
    stabilizer : list
        List of strings representing stabilizer elements.
    code_param : tuple
        A tuple (n, k) where n is the number of encoded qubits and k is the number of logical
        qubits.
    pauli_errors : list
        List of krauss operators as numpy arrays that are scalar multiples of the pauli group and
        hence represent a Pauli Channel.
    optimize : str
        If optimize is "coherent" (default), then it optimizes the coherent information.
        If optimize is "fidelity", then it optimizes the minimum fidelity.
    sparse : bool
        If True, then pauli elements of stabilizer code are sparse.
    options : None or dict
        Dictionary of parameters for 'AnalyticQCodes.optimize_coherent' and
        'AnalyticQCodes.optimize_fidelity' optimizations procedures. Should have parameters,
        'param' : str
            Parameterization of density matrix, default is 'overparam'. Can also be 'cholesky.'
            Can also provide own's own parameterization by being a subclass of ParameterizationABC.
        'lipschitz': int
            Integer of number of samplers to be used for lipschitz sampler. Default is 50
        'use_pool' : int
            The number of pool proccesses to be used by the multiprocessor library. Default is 3.
        'maxiter' : int
            Maximum number of iterations. Default is 500.
        'samples' : list, optional
            List of vectors that satisfy the parameterization from "param", that are served as
            initial guesses for the optimization procedure. Optional, unless 'lipschitz' is zero.

    Returns
    -------
    dict :
        The result is a dictionary with fields:

            optimal_rho : np.ndarray
                The density matrix of the optimal solution.
            optimal_val : float
                The optimal value of either coherent information or fidelity.
            method : str
                Either diffev or slsqp.
            success : bool
                True if optimizer converges.
            objective : str
                Either coherent or fidelity
            lipschitz : bool
                True if uses lipschitz properties to find initial guesses.

    """
    if not isinstance(optimize, str):
        raise TypeError("Optimize should be a string.")
    if not (optimize == "coherent" or optimize == "fidelity"):
        raise TypeError("Optimize should either be coherent or fidelity.")
    if 2**code_param[1] != pauli_errors[0].shape[1]:
        raise TypeError(
            "Number of Columns of Pauli error does not match 2**k.")

    # Parameters for optimization
    # TODO: add coherent information parameters.

    # Set up the objects, stabilizer code, pauli-channel error, respectively.
    stab = StabilizerCode(stabilizer, code_param[0], code_param[1])

    # Figure out the dimensions of channel later.
    error_chan = AnalyticQChan(pauli_errors, [1, 1], 2, 2, sparse=sparse)
    error_chan.krauss.update_kraus_operators(code_param[0] // code_param[1])

    # Get Kraus Operator for encoder.
    encoder = stab.encode_krauss_operators()

    # Get the kraus operators for the stabilizers that anti-commute with each kraus operator.
    kraus = stab.kraus_operators_correcting_errors(
        error_chan.krauss.nth_kraus_ops, sparse=sparse)
    # Multiply by the encoder to get the full approximate error-correcting.
    kraus = [x.dot(encoder) for x in kraus]

    # Construct new kraus operators.
    total_chan = AnalyticQChan(kraus, [code_param[1], code_param[0]],
                               2,
                               2,
                               sparse=True)

    # Solve the objective function
    if optimize == "coherent":
        result = total_chan.optimize_coherent(n=1,
                                              rank=2,
                                              optimizer="slsqp",
                                              param="overparam",
                                              lipschitz=25,
                                              use_pool=3,
                                              maxiter=250)
    else:
        result = total_chan.optimize_fidelity(n=1,
                                              optimizer="slsqp",
                                              param="overparam",
                                              lipschitz=25,
                                              use_pool=3,
                                              maxiter=250)
    return result