Ejemplo n.º 1
0
def test_QobjMulNonsquareDims():
    """
    Qobj: multiplication w/ non-square qobj.dims

    Checks for regression of #331.
    """
    data = np.array([[0, 1], [1, 0]])

    q1 = Qobj(data)
    q1.dims[0].append(1)
    q2 = Qobj(data)

    assert_equal((q1 * q2).dims, [[2, 1], [2]])
    assert_equal((q2 * q1.dag()).dims, [[2], [2, 1]])

    # Note that this is [[2], [2]] instead of [[2, 1], [2, 1]],
    # as matching dimensions of 1 are implicitly partial traced out.
    # (See #331.)
    assert_equal((q1 * q2 * q1.dag()).dims, [[2], [2]])
    
    # Because of the above, we also need to check for extra indices
    # that aren't of length 1.
    q1 = Qobj([[ 1.+0.j,  0.+0.j],
         [ 0.+0.j,  1.+0.j],
         [ 0.+0.j,  1.+0.j],
         [ 1.+0.j,  0.+0.j],
         [ 0.+0.j,  0.-1.j],
         [ 0.+1.j,  0.+0.j],
         [ 1.+0.j,  0.+0.j],
         [ 0.+0.j, -1.+0.j]
     ], dims=[[4, 2], [2]])

    assert_equal((q1 * q2 * q1.dag()).dims, [[4, 2], [4, 2]])
Ejemplo n.º 2
0
def test_QobjMulNonsquareDims():
    """
    Qobj: multiplication w/ non-square qobj.dims

    Checks for regression of #331.
    """
    data = np.array([[0, 1], [1, 0]])

    q1 = Qobj(data)
    q1.dims[0].append(1)
    q2 = Qobj(data)

    assert_equal((q1 * q2).dims, [[2, 1], [2]])
    assert_equal((q2 * q1.dag()).dims, [[2], [2, 1]])

    # Note that this is [[2], [2]] instead of [[2, 1], [2, 1]],
    # as matching dimensions of 1 are implicitly partial traced out.
    # (See #331.)
    assert_equal((q1 * q2 * q1.dag()).dims, [[2], [2]])

    # Because of the above, we also need to check for extra indices
    # that aren't of length 1.
    q1 = Qobj([[ 1.+0.j,  0.+0.j],
         [ 0.+0.j,  1.+0.j],
         [ 0.+0.j,  1.+0.j],
         [ 1.+0.j,  0.+0.j],
         [ 0.+0.j,  0.-1.j],
         [ 0.+1.j,  0.+0.j],
         [ 1.+0.j,  0.+0.j],
         [ 0.+0.j, -1.+0.j]
     ], dims=[[4, 2], [2]])

    assert_equal((q1 * q2 * q1.dag()).dims, [[4, 2], [4, 2]])
Ejemplo n.º 3
0
def propagator_steadystate(U):
    """Find the steady state for successive applications of the propagator
    :math:`U`.

    Parameters
    ----------
    U : qobj
        Operator representing the propagator.

    Returns
    -------
    a : qobj
        Instance representing the steady-state density matrix.

    """

    evals, evecs = la.eig(U.full())

    ev_min, ev_idx = _get_min_and_index(abs(evals - 1.0))

    evecs = evecs.T
    rho = Qobj(vec2mat(evecs[ev_idx]), dims=U.dims[0])
    rho = rho * (1.0 / rho.tr())
    rho = 0.5 * (rho + rho.dag())  # make sure rho is herm
    return rho
Ejemplo n.º 4
0
def propagator_steadystate(U):
    """Find the steady state for successive applications of the propagator
    :math:`U`.

    Parameters
    ----------
    U : qobj
        Operator representing the propagator.

    Returns
    -------
    a : qobj
        Instance representing the steady-state density matrix.

    """

    evals, evecs = la.eig(U.full())

    ev_min, ev_idx = _get_min_and_index(abs(evals - 1.0))

    evecs = evecs.T
    rho = Qobj(vec2mat(evecs[ev_idx]), dims=U.dims[0])
    rho = rho * (1.0 / rho.tr())
    rho = 0.5 * (rho + rho.dag())  # make sure rho is herm
    return rho
Ejemplo n.º 5
0
def test_QobjDagger():
    "Qobj adjoint (dagger)"
    data = _random_not_singular(5)
    A = Qobj(data)
    B = A.dag()
    assert np.all(B.data.todense() - np.matrix(data.conj().T) == 0)
    assert A.isherm == B.isherm
    assert A.type == B.type
    assert A.superrep == B.superrep
Ejemplo n.º 6
0
def test_QobjDagger():
    "Qobj adjoint (dagger)"
    data = _random_not_singular(5)
    A = Qobj(data)
    B = A.dag()
    assert_(np.all(B.data.todense() - np.matrix(data.conj().T) == 0))
    assert_equal(A.isherm, B.isherm)
    assert_equal(A.type, B.type)
    assert_equal(A.superrep, B.superrep)
Ejemplo n.º 7
0
def test_QobjDagger():
    "Qobj adjoint (dagger)"
    data = np.random.random((5, 5)) + 1j * np.random.random((5, 5)) - (0.5 + 0.5j)
    A = Qobj(data)
    B = A.dag()
    assert_(np.all(B.data.todense() - np.matrix(data.conj().T) == 0))
    assert_equal(A.isherm, B.isherm)
    assert_equal(A.type, B.type)
    assert_equal(A.superrep, B.superrep)
Ejemplo n.º 8
0
def test_QobjDagger():
    "Qobj adjoint (dagger)"
    data = np.random.random(
        (5, 5)) + 1j * np.random.random((5, 5)) - (0.5 + 0.5j)
    A = Qobj(data)
    B = A.dag()
    assert_(np.all(B.data.todense() - np.matrix(data.conj().T) == 0))
    assert_equal(A.isherm, B.isherm)
    assert_equal(A.type, B.type)
    assert_equal(A.superrep, B.superrep)
Ejemplo n.º 9
0
def steadystate_nonlinear(L_func,
                          rho0,
                          args={},
                          maxiter=10,
                          random_initial_state=False,
                          tol=1e-6,
                          itertol=1e-5,
                          use_umfpack=True,
                          verbose=False):
    """
    Steady state for the evolution subject to the nonlinear Liouvillian
    (which depends on the density matrix).

    .. note:: Experimental. Not at all certain that the inverse power method
              works for state-dependent Liouvillian operators.
    """
    use_solver(assumeSortedIndices=True, useUmfpack=use_umfpack)
    if random_initial_state:
        rhoss = rand_dm(rho0.shape[0], 1.0, dims=rho0.dims)
    elif isket(rho0):
        rhoss = ket2dm(rho0)
    else:
        rhoss = Qobj(rho0)

    v = mat2vec(rhoss.full())

    n = prod(rhoss.shape)
    tr_vec = sp.eye(rhoss.shape[0], rhoss.shape[0], format='coo')
    tr_vec = tr_vec.reshape((1, n))

    it = 0
    while it < maxiter:

        L = L_func(rhoss, args)
        L = L.data.tocsc() - (tol**2) * sp.eye(n, n, format='csc')
        L.sort_indices()

        v = spsolve(L, v, use_umfpack=use_umfpack)
        v = v / la.norm(v, np.inf)

        data = v / sum(tr_vec.dot(v))
        data = reshape(data, (rhoss.shape[0], rhoss.shape[1])).T
        rhoss.data = sp.csr_matrix(data)

        it += 1

        if la.norm(L * v, np.inf) <= tol:
            break

    if it >= maxiter:
        raise ValueError('Failed to find steady state after ' + str(maxiter) +
                         ' iterations')

    rhoss = 0.5 * (rhoss + rhoss.dag())
    return rhoss.tidyup() if qset.auto_tidyup else rhoss
Ejemplo n.º 10
0
def rand_herm(N, density=0.75, dims=None):
    """Creates a random NxN sparse Hermitian quantum object.

    Uses :math:`H=X+X^{+}` where :math:`X` is
    a randomly generated quantum operator with a given `density`.

    Parameters
    ----------
    N : int
        Shape of output quantum operator.
    density : float
        Density between [0,1] of output Hermitian operator.
    dims : list
        Dimensions of quantum object.  Used for specifying
        tensor structure. Default is dims=[[N],[N]].

    Returns
    -------
    oper : qobj
        NxN Hermitian quantum operator.

    """
    if dims:
        _check_dims(dims, N, N)
    # to get appropriate density of output
    # Hermitian operator must convert via:
    herm_density = 2.0 * arcsin(density) / pi

    X = sp.rand(N, N, herm_density, format='csr')
    X.data = X.data - 0.5
    Y = X.copy()
    Y.data = 1.0j * np.random.random(len(X.data)) - (0.5 + 0.5j)
    X = X + Y
    X.sort_indices()
    X = Qobj(X)
    if dims:
        return Qobj((X + X.dag()) / 2.0, dims=dims, shape=[N, N])
    else:
        return Qobj((X + X.dag()) / 2.0)
Ejemplo n.º 11
0
def rand_herm(N, density=0.75, dims=None):
    """Creates a random NxN sparse Hermitian quantum object.

    Uses :math:`H=X+X^{+}` where :math:`X` is
    a randomly generated quantum operator with a given `density`.

    Parameters
    ----------
    N : int
        Shape of output quantum operator.
    density : float
        Density between [0,1] of output Hermitian operator.
    dims : list
        Dimensions of quantum object.  Used for specifying
        tensor structure. Default is dims=[[N],[N]].

    Returns
    -------
    oper : qobj
        NxN Hermitian quantum operator.

    """
    if dims:
        _check_dims(dims, N, N)
    # to get appropriate density of output
    # Hermitian operator must convert via:
    herm_density = 2.0 * arcsin(density) / pi

    X = sp.rand(N, N, herm_density, format='csr')
    X.data = X.data - 0.5
    Y = X.copy()
    Y.data = 1.0j * np.random.random(len(X.data)) - (0.5 + 0.5j)
    X = X + Y
    X.sort_indices()
    X = Qobj(X)
    if dims:
        return Qobj((X + X.dag()) / 2.0, dims=dims, shape=[N, N])
    else:
        return Qobj((X + X.dag()) / 2.0)
Ejemplo n.º 12
0
def steadystate_nonlinear(L_func, rho0, args={}, maxiter=10,
                          random_initial_state=False, tol=1e-6, itertol=1e-5,
                          use_umfpack=True, verbose=False):
    """
    Steady state for the evolution subject to the nonlinear Liouvillian
    (which depends on the density matrix).

    .. note:: Experimental. Not at all certain that the inverse power method
              works for state-dependent Liouvillian operators.
    """
    use_solver(assumeSortedIndices=True, useUmfpack=use_umfpack)
    if random_initial_state:
        rhoss = rand_dm(rho0.shape[0], 1.0, dims=rho0.dims)
    elif isket(rho0):
        rhoss = ket2dm(rho0)
    else:
        rhoss = Qobj(rho0)

    v = mat2vec(rhoss.full())

    n = prod(rhoss.shape)
    tr_vec = sp.eye(rhoss.shape[0], rhoss.shape[0], format='coo')
    tr_vec = tr_vec.reshape((1, n))

    it = 0
    while it < maxiter:

        L = L_func(rhoss, args)
        L = L.data.tocsc() - (tol ** 2) * sp.eye(n, n, format='csc')
        L.sort_indices()

        v = spsolve(L, v, use_umfpack=use_umfpack)
        v = v / la.norm(v, np.inf)

        data = v / sum(tr_vec.dot(v))
        data = reshape(data, (rhoss.shape[0], rhoss.shape[1])).T
        rhoss.data = sp.csr_matrix(data)

        it += 1

        if la.norm(L * v, np.inf) <= tol:
            break

    if it >= maxiter:
        raise ValueError('Failed to find steady state after ' +
                         str(maxiter) + ' iterations')

    rhoss = 0.5 * (rhoss + rhoss.dag())
    return rhoss.tidyup() if qset.auto_tidyup else rhoss
Ejemplo n.º 13
0
 def test_NeglectSmallKraus(self):
     """
     Superoperator: Convert Kraus to Choi matrix and back. Neglect tiny Kraus operators.
     """
     zero = asarray([[1], [0]], dtype=complex)
     one = asarray([[0], [1]], dtype=complex)
     zero_log = kron(kron(zero, zero), zero)
     one_log = kron(kron(one, one), one)
     # non-square Kraus operator (isometry)
     kraus = Qobj(zero_log @ zero.T + one_log @ one.T)
     super = sprepost(kraus, kraus.dag())
     # 1 non-zero Kraus operator the rest are zero
     sixteen_kraus_ops = to_kraus(super, tol=0.0)
     # default is tol=1e-9
     one_kraus_op = to_kraus(super)
     assert_(len(sixteen_kraus_ops) == 16 and len(one_kraus_op) == 1)
     assert_((one_kraus_op[0] - kraus).norm() < tol)
Ejemplo n.º 14
0
 def test_NonSquareKrausSuperChoi(self):
     """
     Superoperator: Convert non-square Kraus operator to Super + Choi matrix and back.
     """
     zero = asarray([[1], [0]], dtype=complex)
     one = asarray([[0], [1]], dtype=complex)
     zero_log = kron(kron(zero, zero), zero)
     one_log = kron(kron(one, one), one)
     # non-square Kraus operator (isometry)
     kraus = Qobj(zero_log @ zero.T + one_log @ one.T)
     super = sprepost(kraus, kraus.dag())
     choi = to_choi(super)
     op1 = to_kraus(super)
     op2 = to_kraus(choi)
     op3 = to_super(choi)
     assert_(choi.type == "super" and choi.superrep == "choi")
     assert_(super.type == "super" and super.superrep == "super")
     assert_((op1[0] - kraus).norm() < 1e-8)
     assert_((op2[0] - kraus).norm() < 1e-8)
     assert_((op3 - super).norm() < 1e-8)