Example #1
0
    def test_diags_vs_diag(self):
        # Check that
        #
        #    diags([a, b, ...], [i, j, ...]) == diag(a, i) + diag(b, j) + ...
        #

        np.random.seed(1234)

        for n_diags in [1, 2, 3, 4, 5, 10]:
            n = 1 + n_diags // 2 + np.random.randint(0, 10)

            offsets = np.arange(-n + 1, n - 1)
            np.random.shuffle(offsets)
            offsets = offsets[:n_diags]

            diagonals = [np.random.rand(n - abs(q)) for q in offsets]

            mat = construct.diags(diagonals, offsets)
            dense_mat = sum(
                [np.diag(x, j) for x, j in zip(diagonals, offsets)])

            assert_array_almost_equal_nulp(mat.todense(), dense_mat)

            if len(offsets) == 1:
                mat = construct.diags(diagonals[0], offsets[0])
                dense_mat = np.diag(diagonals[0], offsets[0])
                assert_array_almost_equal_nulp(mat.todense(), dense_mat)
Example #2
0
    def test_diags_vs_diag(self):
        # Check that
        #
        #    diags([a, b, ...], [i, j, ...]) == diag(a, i) + diag(b, j) + ...
        #

        np.random.seed(1234)

        for n_diags in [1, 2, 3, 4, 5, 10]:
            n = 1 + n_diags//2 + np.random.randint(0, 10)

            offsets = np.arange(-n+1, n-1)
            np.random.shuffle(offsets)
            offsets = offsets[:n_diags]

            diagonals = [np.random.rand(n - abs(q)) for q in offsets]

            mat = construct.diags(diagonals, offsets)
            dense_mat = sum([np.diag(x, j) for x, j in zip(diagonals, offsets)])

            assert_array_almost_equal_nulp(mat.todense(), dense_mat)

            if len(offsets) == 1:
                mat = construct.diags(diagonals[0], offsets[0])
                dense_mat = np.diag(diagonals[0], offsets[0])
                assert_array_almost_equal_nulp(mat.todense(), dense_mat)
Example #3
0
    def test_diags(self):
        a = array([1, 2, 3, 4, 5])
        b = array([6, 7, 8, 9, 10])
        c = array([11, 12, 13, 14, 15])

        cases = []
        cases.append((a[:1], 0, (1, 1), [[1]]))
        cases.append(([a[:1]], [0], (1, 1), [[1]]))
        cases.append(([a[:1]], [0], (2, 1), [[1],[0]]))
        cases.append(([a[:1]], [0], (1, 2), [[1,0]]))
        cases.append(([a[:1]], [1], (1, 2), [[0,1]]))
        cases.append(([a[:2]], [0], (2, 2), [[1,0],[0,2]]))
        cases.append(([a[:1]],[-1], (2, 2), [[0,0],[1,0]]))
        cases.append(([a[:3]], [0], (3, 4), [[1,0,0,0],[0,2,0,0],[0,0,3,0]]))
        cases.append(([a[:3]], [1], (3, 4), [[0,1,0,0],[0,0,2,0],[0,0,0,3]]))
        cases.append(([a[:3]], [2], (3, 5), [[0,0,1,0,0],[0,0,0,2,0],[0,0,0,0,3]]))

        cases.append(([a[:3],b[:1]], [0,2], (3, 3), [[1,0,6],[0,2,0],[0,0,3]]))
        cases.append(([a[:2],b[:3]], [-1,0], (3, 4), [[6,0,0,0],[1,7,0,0],[0,2,8,0]]))
        cases.append(([a[:4],b[:3]], [2,-3], (6, 6), [[0,0,1,0,0,0],
                                                     [0,0,0,2,0,0],
                                                     [0,0,0,0,3,0],
                                                     [6,0,0,0,0,4],
                                                     [0,7,0,0,0,0],
                                                     [0,0,8,0,0,0]]))

        cases.append(([a[:4],b,c[:4]], [-1,0,1], (5, 5), [[6,11, 0, 0, 0],
                                                            [1, 7,12, 0, 0],
                                                            [0, 2, 8,13, 0],
                                                            [0, 0, 3, 9,14],
                                                            [0, 0, 0, 4,10]]))
        cases.append(([a[:2],b[:3],c], [-4,2,-1], (6, 5), [[0, 0, 6, 0, 0],
                                                          [11, 0, 0, 7, 0],
                                                          [0,12, 0, 0, 8],
                                                          [0, 0,13, 0, 0],
                                                          [1, 0, 0,14, 0],
                                                          [0, 2, 0, 0,15]]))

        # scalar case: broadcasting
        cases.append(([1,-2,1], [1,0,-1], (3, 3), [[-2, 1, 0],
                                                    [1, -2, 1],
                                                    [0, 1, -2]]))

        for d, o, shape, result in cases:
            try:
                assert_equal(construct.diags(d, o, shape=shape).todense(),
                             result)

                if shape[0] == shape[1] and hasattr(d[0], '__len__'):
                    # should be able to find the shape automatically
                    assert_equal(construct.diags(d, o).todense(), result)
            except:
                print("%r %r %r" % (d, o, shape))
                raise
Example #4
0
    def test_diags(self):
        a = array([1, 2, 3, 4, 5])
        b = array([6, 7, 8, 9, 10])
        c = array([11, 12, 13, 14, 15])

        cases = []
        cases.append((a[:1], 0, (1, 1), [[1]]))
        cases.append(([a[:1]], [0], (1, 1), [[1]]))
        cases.append(([a[:1]], [0], (2, 1), [[1],[0]]))
        cases.append(([a[:1]], [0], (1, 2), [[1,0]]))
        cases.append(([a[:1]], [1], (1, 2), [[0,1]]))
        cases.append(([a[:2]], [0], (2, 2), [[1,0],[0,2]]))
        cases.append(([a[:1]],[-1], (2, 2), [[0,0],[1,0]]))
        cases.append(([a[:3]], [0], (3, 4), [[1,0,0,0],[0,2,0,0],[0,0,3,0]]))
        cases.append(([a[:3]], [1], (3, 4), [[0,1,0,0],[0,0,2,0],[0,0,0,3]]))
        cases.append(([a[:3]], [2], (3, 5), [[0,0,1,0,0],[0,0,0,2,0],[0,0,0,0,3]]))

        cases.append(([a[:3],b[:1]], [0,2], (3, 3), [[1,0,6],[0,2,0],[0,0,3]]))
        cases.append(([a[:2],b[:3]], [-1,0], (3, 4), [[6,0,0,0],[1,7,0,0],[0,2,8,0]]))
        cases.append(([a[:4],b[:3]], [2,-3], (6, 6), [[0,0,1,0,0,0],
                                                     [0,0,0,2,0,0],
                                                     [0,0,0,0,3,0],
                                                     [6,0,0,0,0,4],
                                                     [0,7,0,0,0,0],
                                                     [0,0,8,0,0,0]]))

        cases.append(([a[:4],b,c[:4]], [-1,0,1], (5, 5), [[6,11, 0, 0, 0],
                                                            [1, 7,12, 0, 0],
                                                            [0, 2, 8,13, 0],
                                                            [0, 0, 3, 9,14],
                                                            [0, 0, 0, 4,10]]))
        cases.append(([a[:2],b[:3],c], [-4,2,-1], (6, 5), [[0, 0, 6, 0, 0],
                                                          [11, 0, 0, 7, 0],
                                                          [0,12, 0, 0, 8],
                                                          [0, 0,13, 0, 0],
                                                          [1, 0, 0,14, 0],
                                                          [0, 2, 0, 0,15]]))

        # scalar case: broadcasting
        cases.append(([1,-2,1], [1,0,-1], (3, 3), [[-2, 1, 0],
                                                    [1, -2, 1],
                                                    [0, 1, -2]]))

        for d, o, shape, result in cases:
            try:
                assert_equal(construct.diags(d, o, shape=shape).todense(),
                             result)

                if shape[0] == shape[1] and hasattr(d[0], '__len__'):
                    # should be able to find the shape automatically
                    assert_equal(construct.diags(d, o).todense(), result)
            except:
                print("%r %r %r" % (d, o, shape))
                raise
Example #5
0
def is_reversible(T, mu=None, tol=1e-15):
    r"""
    checks whether T is reversible in terms of given stationary distribution.
    If no distribution is given, it will be calculated out of T.

    performs follwing check:
    :math:`\pi_i P_{ij} = \pi_j P_{ji}
    Parameters
    ----------
    T : scipy.sparse matrix
        Transition matrix
    mu : numpy.ndarray vector
        stationary distribution
    tol : float
        tolerance to check with

    Returns
    -------
    Truth value : bool
        True, if T is a stochastic matrix
        False, otherwise
    """
    if not is_transition_matrix(T, tol):
        raise ValueError("given matrix is not a valid transition matrix.")

    T = T.tocsr()

    if mu is None:
        from .decomposition import stationary_distribution
        mu = stationary_distribution(T)

    Mu = diags(mu, 0)
    prod = Mu * T

    return allclose_sparse(prod, prod.transpose(), rtol=tol)
Example #6
0
def expected_counts_stationary(T, n, mu=None):
    r"""Expected transition counts for Markov chain in equilibrium.

    Since mu is stationary for T we have

    .. math::

        E(C^{(n)})=n diag(mu)*T.

    Parameters
    ----------
    T : (M, M) sparse matrix
        Transition matrix.
    n : int
        Number of steps for chain.
    mu : (M,) ndarray (optional)
        Stationary distribution for T. If mu is not specified it will be
        computed via diagonalization of T.

    Returns
    -------
    EC : (M, M) sparse matrix
        Expected value for transition counts after N steps.

    """
    if (n <= 0):
        EC = coo_matrix(T.shape, dtype=float)
        return EC
    else:
        if mu is None:
            mu = stationary_distribution(T)
        D_mu = diags(mu, 0)
        EC = n * D_mu.dot(T)
        return EC
Example #7
0
def getMatrix(n=10, isDiagDom=True):
    '''
    Return an nxn matrix which is the discretization matrix
    from finite difference for a diffusion problem.
    To visualize A: use plt.spy(A.toarray())
    '''
    # Representation of sparse matrix and right-hand side
    assert n >= 2
    n -= 1
    diagonal  = np.zeros(n+1)
    lower     = np.zeros(n)
    upper     = np.zeros(n)

    # Precompute sparse matrix
    if isDiagDom:
        diagonal[:] = 2 + 1/n**2
    else:
        diagonal[:] = 2
    lower[:] = -1  #1
    upper[:] = -1  #1
    # Insert boundary conditions
    # diagonal[0] = 1
    # upper[0] = 0
    # diagonal[n] = 1
    # lower[-1] = 0

    
    A = diags(
        diagonals=[diagonal, lower, upper],
        offsets=[0, -1, 1], shape=(n+1, n+1),
        format='csr')

    return A
Example #8
0
def is_rate_matrix(K, tol):
    """
    True if K is a rate matrix
    Parameters
    ----------
    K : scipy.sparse matrix
        Matrix to check
    tol : float
        tolerance to check with

    Returns
    -------
    Truth value : bool
        True, if K negated diagonal is positive and row sums up to zero.
        False, otherwise
    """
    K = K.tocsr()

    # check rows sum up to zero.
    row_sum = K.sum(axis=1)
    sum_eq_zero = np.allclose(row_sum, np.zeros(shape=row_sum.shape), atol=tol)

    # store copy of original diagonal
    org_diag = K.diagonal()

    # substract diagonal
    K = K - diags(org_diag, 0)

    # check off diagonals are > 0
    values = K.data
    values_gt_zero = np.allclose(values, np.abs(values), atol=tol)

    # add diagonal
    K = K + diags(org_diag, 0)

    return values_gt_zero and sum_eq_zero
Example #9
0
def expected_counts(p0, T, N):
    r"""Compute expected transition counts for Markov chain after N steps.

    Expected counts are computed according to ..math::

    E[C_{ij}^{(n)}]=\sum_{k=0}^{N-1} (p_0^T T^{k})_{i} p_{ij}

    Parameters
    ----------
    p0 : (M,) ndarray
        Starting (probability) vector of the chain.
    T : (M, M) sparse matrix
        Transition matrix of the chain.
    N : int
        Number of steps to take from initial state.

    Returns
    --------
    EC : (M, M) sparse matrix
        Expected value for transition counts after N steps.

    """
    if (N <= 0):
        EC = coo_matrix(T.shape, dtype=float)
        return EC
    else:
        """Probability vector after (k=0) propagations"""
        p_k = 1.0 * p0
        """Sum of vectors after (k=0) propagations"""
        p_sum = 1.0 * p_k
        """Transpose T to use sparse dot product"""
        Tt = T.transpose()
        for k in np.arange(N - 1):
            """Propagate one step p_{k} -> p_{k+1}"""
            p_k = Tt.dot(p_k)
            """Update sum"""
            p_sum += p_k
        D_psum = diags(p_sum, 0)
        EC = D_psum.dot(T)
        return EC
Example #10
0
 def test_diags_dtype(self):
     x = construct.diags([2.2], [0], shape=(2, 2), dtype=int)
     assert_equal(x.dtype, int)
     assert_equal(x.todense(), [[2, 0], [0, 2]])
Example #11
0
    def test_diags(self):
        a = array([1, 2, 3, 4, 5])
        b = array([6, 7, 8, 9, 10])
        c = array([11, 12, 13, 14, 15])

        cases = []
        cases.append((a[:1], 0, (1, 1), [[1]]))
        cases.append(([a[:1]], [0], (1, 1), [[1]]))
        cases.append(([a[:1]], [0], (2, 1), [[1], [0]]))
        cases.append(([a[:1]], [0], (1, 2), [[1, 0]]))
        cases.append(([a[:1]], [1], (1, 2), [[0, 1]]))
        cases.append(([a[:2]], [0], (2, 2), [[1, 0], [0, 2]]))
        cases.append(([a[:1]], [-1], (2, 2), [[0, 0], [1, 0]]))
        cases.append(([a[:3]], [0], (3, 4), [[1, 0, 0, 0], [0, 2, 0, 0],
                                             [0, 0, 3, 0]]))
        cases.append(([a[:3]], [1], (3, 4), [[0, 1, 0, 0], [0, 0, 2, 0],
                                             [0, 0, 0, 3]]))
        cases.append(([a[:1]], [-2], (3, 5), [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0],
                                              [1, 0, 0, 0, 0]]))
        cases.append(([a[:2]], [-1], (3, 5), [[0, 0, 0, 0, 0], [1, 0, 0, 0, 0],
                                              [0, 2, 0, 0, 0]]))
        cases.append(([a[:3]], [0], (3, 5), [[1, 0, 0, 0, 0], [0, 2, 0, 0, 0],
                                             [0, 0, 3, 0, 0]]))
        cases.append(([a[:3]], [1], (3, 5), [[0, 1, 0, 0, 0], [0, 0, 2, 0, 0],
                                             [0, 0, 0, 3, 0]]))
        cases.append(([a[:3]], [2], (3, 5), [[0, 0, 1, 0, 0], [0, 0, 0, 2, 0],
                                             [0, 0, 0, 0, 3]]))
        cases.append(([a[:2]], [3], (3, 5), [[0, 0, 0, 1, 0], [0, 0, 0, 0, 2],
                                             [0, 0, 0, 0, 0]]))
        cases.append(([a[:1]], [4], (3, 5), [[0, 0, 0, 0, 1], [0, 0, 0, 0, 0],
                                             [0, 0, 0, 0, 0]]))
        cases.append(([a[:1]], [-4], (5, 3), [[0, 0, 0], [0, 0, 0], [0, 0, 0],
                                              [0, 0, 0], [1, 0, 0]]))
        cases.append(([a[:2]], [-3], (5, 3), [[0, 0, 0], [0, 0, 0], [0, 0, 0],
                                              [1, 0, 0], [0, 2, 0]]))
        cases.append(([a[:3]], [-2], (5, 3), [[0, 0, 0], [0, 0, 0], [1, 0, 0],
                                              [0, 2, 0], [0, 0, 3]]))
        cases.append(([a[:3]], [-1], (5, 3), [[0, 0, 0], [1, 0, 0], [0, 2, 0],
                                              [0, 0, 3], [0, 0, 0]]))
        cases.append(([a[:3]], [0], (5, 3), [[1, 0, 0], [0, 2, 0], [0, 0, 3],
                                             [0, 0, 0], [0, 0, 0]]))
        cases.append(([a[:2]], [1], (5, 3), [[0, 1, 0], [0, 0, 2], [0, 0, 0],
                                             [0, 0, 0], [0, 0, 0]]))
        cases.append(([a[:1]], [2], (5, 3), [[0, 0, 1], [0, 0, 0], [0, 0, 0],
                                             [0, 0, 0], [0, 0, 0]]))

        cases.append(([a[:3], b[:1]], [0, 2], (3, 3), [[1, 0, 6], [0, 2, 0],
                                                       [0, 0, 3]]))
        cases.append(([a[:2], b[:3]], [-1, 0], (3, 4), [[6, 0, 0, 0],
                                                        [1, 7, 0, 0],
                                                        [0, 2, 8, 0]]))
        cases.append(([a[:4], b[:3]], [2, -3], (6, 6), [[0, 0, 1, 0, 0, 0],
                                                        [0, 0, 0, 2, 0, 0],
                                                        [0, 0, 0, 0, 3, 0],
                                                        [6, 0, 0, 0, 0, 4],
                                                        [0, 7, 0, 0, 0, 0],
                                                        [0, 0, 8, 0, 0, 0]]))

        cases.append(([a[:4], b, c[:4]], [-1, 0, 1], (5, 5), [[6, 11, 0, 0, 0],
                                                              [1, 7, 12, 0, 0],
                                                              [0, 2, 8, 13, 0],
                                                              [0, 0, 3, 9, 14],
                                                              [0, 0, 0, 4,
                                                               10]]))
        cases.append(([a[:2], b[:3], c], [-4, 2,
                                          -1], (6, 5), [[0, 0, 6, 0, 0],
                                                        [11, 0, 0, 7, 0],
                                                        [0, 12, 0, 0, 8],
                                                        [0, 0, 13, 0, 0],
                                                        [1, 0, 0, 14, 0],
                                                        [0, 2, 0, 0, 15]]))

        # too long arrays are OK
        cases.append(([a], [0], (1, 1), [[1]]))
        cases.append(([a[:3], b], [0, 2], (3, 3), [[1, 0, 6], [0, 2, 0],
                                                   [0, 0, 3]]))
        cases.append((np.array([[1, 2, 3],
                                [4, 5, 6]]), [0, -1], (3, 3), [[1, 0, 0],
                                                               [4, 2, 0],
                                                               [0, 5, 3]]))

        # scalar case: broadcasting
        cases.append(([1, -2, 1], [1, 0, -1], (3, 3), [[-2, 1, 0], [1, -2, 1],
                                                       [0, 1, -2]]))

        for d, o, shape, result in cases:
            err_msg = "%r %r %r %r" % (d, o, shape, result)
            assert_equal(construct.diags(d, o, shape=shape).todense(),
                         result,
                         err_msg=err_msg)

            if shape[0] == shape[1] and hasattr(
                    d[0], '__len__') and len(d[0]) <= max(shape):
                # should be able to find the shape automatically
                assert_equal(construct.diags(d, o).todense(),
                             result,
                             err_msg=err_msg)
Example #12
0
 def test_diags_empty(self):
     x = construct.diags([])
     assert_equal(x.shape, (0, 0))
Example #13
0
 def test_diags_one_diagonal(self):
     d = list(range(5))
     for k in range(-5, 6):
         assert_equal(
             construct.diags(d, k).toarray(),
             construct.diags([d], [k]).toarray())
Example #14
0
 def test_diags_dtype(self):
     x = construct.diags([2.2], [0], shape=(2, 2), dtype=int)
     assert_equal(x.dtype, int)
     assert_equal(x.todense(), [[2, 0], [0, 2]])
Example #15
0
    print "Predicting the probs"
    
    t0 = time()
    probs = clf.predict_proba(X_test)
    
    duration = time() - t0

    print
    print "Predicting probs took %0.2fs." % duration
    print
    
    total_evi = neg_evi + pos_evi
    
    evi_sorted = np.argsort(total_evi)
    
    coef_diags = diags(clf.coef_[0], 0)
    
    # Most negative
    
    print
    print "Most negative"
    print
    i = evi_sorted[0]
    print total_evi[i], neg_evi[i], pos_evi[i], probs[i]
    print test_corpus[i]
    ind_evi = (X_test[i] * coef_diags).toarray()[0]
    ind_evi_sorted = np.argsort(ind_evi)
    print "Negative words"
    for j in ind_evi_sorted:
        if ind_evi[j] >= 0:
            break
Example #16
0
 def test_diags_one_diagonal(self):
     d = list(range(5))
     for k in range(-5, 6):
         assert_equal(construct.diags(d, k).toarray(),
                      construct.diags([d], [k]).toarray())
Example #17
0
 def test_diags_default(self):
     a = array([1, 2, 3, 4, 5])
     assert_equal(construct.diags(a).todense(), np.diag(a))
Example #18
0
 def test_diags_empty(self):
     x = construct.diags([])
     assert_equal(x.shape, (0, 0))
Example #19
0
 def test_diags_default(self):
     a = array([1, 2, 3, 4, 5])
     assert_equal(construct.diags(a).todense(), np.diag(a))
Example #20
0
    def test_diags(self):
        a = array([1, 2, 3, 4, 5])
        b = array([6, 7, 8, 9, 10])
        c = array([11, 12, 13, 14, 15])

        cases = []
        cases.append((a[:1], 0, (1, 1), [[1]]))
        cases.append(([a[:1]], [0], (1, 1), [[1]]))
        cases.append(([a[:1]], [0], (2, 1), [[1],[0]]))
        cases.append(([a[:1]], [0], (1, 2), [[1,0]]))
        cases.append(([a[:1]], [1], (1, 2), [[0,1]]))
        cases.append(([a[:2]], [0], (2, 2), [[1,0],[0,2]]))
        cases.append(([a[:1]],[-1], (2, 2), [[0,0],[1,0]]))
        cases.append(([a[:3]], [0], (3, 4), [[1,0,0,0],[0,2,0,0],[0,0,3,0]]))
        cases.append(([a[:3]], [1], (3, 4), [[0,1,0,0],[0,0,2,0],[0,0,0,3]]))
        cases.append(([a[:1]], [-2], (3, 5), [[0,0,0,0,0],[0,0,0,0,0],[1,0,0,0,0]]))
        cases.append(([a[:2]], [-1], (3, 5), [[0,0,0,0,0],[1,0,0,0,0],[0,2,0,0,0]]))
        cases.append(([a[:3]], [0], (3, 5), [[1,0,0,0,0],[0,2,0,0,0],[0,0,3,0,0]]))
        cases.append(([a[:3]], [1], (3, 5), [[0,1,0,0,0],[0,0,2,0,0],[0,0,0,3,0]]))
        cases.append(([a[:3]], [2], (3, 5), [[0,0,1,0,0],[0,0,0,2,0],[0,0,0,0,3]]))
        cases.append(([a[:2]], [3], (3, 5), [[0,0,0,1,0],[0,0,0,0,2],[0,0,0,0,0]]))
        cases.append(([a[:1]], [4], (3, 5), [[0,0,0,0,1],[0,0,0,0,0],[0,0,0,0,0]]))
        cases.append(([a[:1]], [-4], (5, 3), [[0,0,0],[0,0,0],[0,0,0],[0,0,0],[1,0,0]]))
        cases.append(([a[:2]], [-3], (5, 3), [[0,0,0],[0,0,0],[0,0,0],[1,0,0],[0,2,0]]))
        cases.append(([a[:3]], [-2], (5, 3), [[0,0,0],[0,0,0],[1,0,0],[0,2,0],[0,0,3]]))
        cases.append(([a[:3]], [-1], (5, 3), [[0,0,0],[1,0,0],[0,2,0],[0,0,3],[0,0,0]]))
        cases.append(([a[:3]], [0], (5, 3), [[1,0,0],[0,2,0],[0,0,3],[0,0,0],[0,0,0]]))
        cases.append(([a[:2]], [1], (5, 3), [[0,1,0],[0,0,2],[0,0,0],[0,0,0],[0,0,0]]))
        cases.append(([a[:1]], [2], (5, 3), [[0,0,1],[0,0,0],[0,0,0],[0,0,0],[0,0,0]]))

        cases.append(([a[:3],b[:1]], [0,2], (3, 3), [[1,0,6],[0,2,0],[0,0,3]]))
        cases.append(([a[:2],b[:3]], [-1,0], (3, 4), [[6,0,0,0],[1,7,0,0],[0,2,8,0]]))
        cases.append(([a[:4],b[:3]], [2,-3], (6, 6), [[0,0,1,0,0,0],
                                                     [0,0,0,2,0,0],
                                                     [0,0,0,0,3,0],
                                                     [6,0,0,0,0,4],
                                                     [0,7,0,0,0,0],
                                                     [0,0,8,0,0,0]]))

        cases.append(([a[:4],b,c[:4]], [-1,0,1], (5, 5), [[6,11, 0, 0, 0],
                                                            [1, 7,12, 0, 0],
                                                            [0, 2, 8,13, 0],
                                                            [0, 0, 3, 9,14],
                                                            [0, 0, 0, 4,10]]))
        cases.append(([a[:2],b[:3],c], [-4,2,-1], (6, 5), [[0, 0, 6, 0, 0],
                                                          [11, 0, 0, 7, 0],
                                                          [0,12, 0, 0, 8],
                                                          [0, 0,13, 0, 0],
                                                          [1, 0, 0,14, 0],
                                                          [0, 2, 0, 0,15]]))

        # too long arrays are OK
        cases.append(([a], [0], (1, 1), [[1]]))
        cases.append(([a[:3],b], [0,2], (3, 3), [[1, 0, 6], [0, 2, 0], [0, 0, 3]]))
        cases.append((np.array([[1, 2, 3], [4, 5, 6]]), [0,-1], (3, 3), [[1, 0, 0], [4, 2, 0], [0, 5, 3]]))

        # scalar case: broadcasting
        cases.append(([1,-2,1], [1,0,-1], (3, 3), [[-2, 1, 0],
                                                    [1, -2, 1],
                                                    [0, 1, -2]]))

        for d, o, shape, result in cases:
            err_msg = "%r %r %r %r" % (d, o, shape, result)
            assert_equal(construct.diags(d, o, shape=shape).todense(),
                         result, err_msg=err_msg)

            if shape[0] == shape[1] and hasattr(d[0], '__len__') and len(d[0]) <= max(shape):
                # should be able to find the shape automatically
                assert_equal(construct.diags(d, o).todense(), result,
                             err_msg=err_msg)