【问题标题】:Error in scipy sparse diags matrix constructionscipy稀疏诊断矩阵构造中的错误
【发布时间】:2015-11-10 15:41:20
【问题描述】:

在使用 scipy.sparse.spdiags 或 scipy.sparse.diags 时,我注意到希望我认为这是例程中的一个错误,例如

scipy.sparse.spdiags([1.1,1.2,1.3],1,4,4).toarray()

返回

array([[ 0. ,  1.2,  0. ,  0. ],
       [ 0. ,  0. ,  1.3,  0. ],
       [ 0. ,  0. ,  0. ,  0. ],
       [ 0. ,  0. ,  0. ,  0. ]])

对于正对角线,它会丢弃前 k 个数据。有人可能会争辩说,这有一些宏大的编程原因,我只需要用零填充。好吧,这可能很烦人,可以使用 scipy.sparse.diags 给出正确的结果。然而,这个例程有一个无法解决的错误

scipy.sparse.diags([1.1,1.2],0,(4,2)).toarray()

给予

array([[ 1.1,  0. ],
       [ 0. ,  1.2],
       [ 0. ,  0. ],
       [ 0. ,  0. ]])

不错,而且

scipy.sparse.diags([1.1,1.2],-2,(4,2)).toarray()

给予

array([[ 0. ,  0. ],
       [ 0. ,  0. ],
       [ 1.1,  0. ],
       [ 0. ,  1.2]])

但是

scipy.sparse.diags([1.1,1.2],-1,(4,2)).toarray()

给出一个错误,提示 ValueError: Diagonal length (index 0: 2 at offset -1) does not agree with matrix size (4, 2)。显然答案是

array([[ 0. ,  0. ],
       [ 1.1,  0. ],
       [ 0. ,  1.2],
       [ 0. ,  0. ]])

对于额外的随机行为,我们有

scipy.sparse.diags([1.1],-1,(4,2)).toarray()

给予

array([[ 0. ,  0. ],
       [ 1.1,  0. ],
       [ 0. ,  1.1],
       [ 0. ,  0. ]])

有人知道是否有一个构造对角稀疏矩阵的函数确实有效吗?

【问题讨论】:

  • 这似乎是scipy.sparse.diags 中的一个错误。查看source,我们可以看到对角线长度计算为m, n = shape ... length = min(m + offset, n - offset),这是不对的。这值得一个错误报告。
  • 更多代码在我的回答中。我想知道length = min(m + k, n - k) 是否是正确的lengthoffset=-2 案例有效可能只是巧合。
  • 我记得有一个 SO 问题将 spdiags 与 Matlab 等价物进行对比。

标签: python scipy sparse-matrix


【解决方案1】:

执行摘要:spdiags 工作正常,即使矩阵输入不是最直观的。 diags 有一个错误,会影响矩形矩阵中的一些偏移量。 scipy github上有一个bug修复。


spdiags 的示例是:

>>> data = array([[1,2,3,4],[1,2,3,4],[1,2,3,4]])
>>> diags = array([0,-1,2])
>>> spdiags(data, diags, 4, 4).todense()
matrix([[1, 0, 3, 0],
        [1, 2, 0, 4],
        [0, 2, 3, 0],
        [0, 0, 3, 4]])

注意data的第3列总是出现在sparse的第3列。其他列也排成一行。但它们在“从边缘掉下来”的地方被省略了。

这个函数的输入是一个矩阵,而diags 的输入是一个参差不齐的列表。稀疏矩阵的对角线都有不同数量的值。因此,规范必须以一种或另一种方式适应这一点。 spdiags 通过忽略某些值来做到这一点,diags 通过接受列表输入来实现。

sparse.diags([1.1,1.2],-1,(4,2)) 错误令人费解。

spdiags 等效项确实有效:

In [421]: sparse.spdiags([[1.1,1.2]],-1,4,2).A
Out[421]: 
array([[ 0. ,  0. ],
       [ 1.1,  0. ],
       [ 0. ,  1.2],
       [ 0. ,  0. ]])

此代码块中引发了错误:

for j, diagonal in enumerate(diagonals):
    offset = offsets[j]
    k = max(0, offset)
    length = min(m + offset, n - offset)
    if length <= 0:
        raise ValueError("Offset %d (index %d) out of bounds" % (offset, j))
    try:
        data_arr[j, k:k+length] = diagonal
    except ValueError:
        if len(diagonal) != length and len(diagonal) != 1:
            raise ValueError(
                "Diagonal length (index %d: %d at offset %d) does not "
                "agree with matrix size (%d, %d)." % (
                j, len(diagonal), offset, m, n))
        raise

diags中实际的矩阵构造函数是:

dia_matrix((data_arr, offsets), shape=(m, n))

这与spdiags 使用的构造函数相同,但没有任何操作。

In [434]: sparse.dia_matrix(([[1.1,1.2]],-1),shape=(4,2)).A
Out[434]: 
array([[ 0. ,  0. ],
       [ 1.1,  0. ],
       [ 0. ,  1.2],
       [ 0. ,  0. ]])

dia 格式中,输入完全按照spdiags 给出的方式存储(包含带有额外值的矩阵):

In [436]: M.data
Out[436]: array([[ 1.1,  1.2]])
In [437]: M.offsets
Out[437]: array([-1], dtype=int32)

正如@user2357112 指出的那样,length = min(m + offset, n - offset 是错误的,在测试用例中产生了3。将其更改为 length = min(m + k, n - k) 会使此 (4,2) 矩阵的所有情况都有效。但是转置失败了:diags([1.1,1.2], 1, (2, 4))

截至 10 月 5 日,对此问题的更正如下:

https://github.com/pv/scipy-work/commit/529cbde47121c8ed87f74fa6445c05d71353eb6c

length = min(m + offset, n - offset, min(m,n))

通过此修复,diags([1.1,1.2], 1, (2, 4)) 可以正常工作。

【讨论】:

  • 是的,但请查看 scipy.sparse.diags([1.1,1.2],-1,(4,2)).toarray() 示例。那个应该可以工作,但它在diags 实现中遇到了不正确的对角线长度计算。
  • 谁想提交错误报告,或者至少搜索现有的? :) 我为numpy 做出了贡献,但还没有为scipy 做出贡献。
  • 我一直没有时间创建 GitHub 帐户,因此无法提交报告。你也可以这样做。不过,我不认为将 offset 更改为 k 可以修复该错误。失败的测试用例的转置仍然会出现问题:scipy.sparse.diags([1.1,1.2], 1, (2, 4)).toarray()
  • 我在 scipy github 上找到了一个 bug 修复。
  • 这不完全是 SciPy GitHub;那是一位开发人员的私人分叉。 I found the pull request, though. 看来要修复了。
猜你喜欢
  • 1970-01-01
  • 2014-05-14
  • 1970-01-01
  • 2013-11-29
  • 1970-01-01
  • 2017-02-17
  • 2017-03-26
  • 2017-03-31
  • 2023-04-10
相关资源
最近更新 更多