使用逻辑索引进行稀疏矩阵赋值的结果很差

时间:2015-02-06 20:13:02

标签: julia

在Matlab / Octave中,我可以使用逻辑索引在符合矩阵A中某个要求的每个位置为矩阵B赋值。

octave:1> A = [.1;.2;.3;.4;.11;.13;.14;.01;.04;.09];
octave:2> C = A < .12
C =

   1
   0
   0
   0
   1
   0
   0
   1
   1
   1

octave:3> B = spalloc(10,1);
octave:4> B(C) = 1
B =

Compressed Column Sparse (rows = 10, cols = 1, nnz = 5 [50%])

  (1, 1) ->  1
  (5, 1) ->  1
  (8, 1) ->  1
  (9, 1) ->  1
  (10, 1) ->  1

但是,如果我在Julia中尝试基本相同的代码,结果是不正确的:

julia> A = [.1;.2;.3;.4;.11;.13;.14;.01;.04;.09];

julia> B = spzeros(10,1)
10x1 sparse matrix with 0 Float64 entries:

julia> C = A .< .12
10-element BitArray{1}:
  true
 false
 false
 false
  true
 false
 false
  true
  true
  true

julia> B[C] = 1
1

julia> B
10x1 sparse matrix with 5 Float64 entries:
    [0 ,  1]  =  1.0
    [0 ,  1]  =  1.0
    [1 ,  1]  =  1.0
    [1 ,  1]  =  1.0
    [1 ,  1]  =  1.0

我在某处的语法中犯了错误,我是否误解了某些内容,或者这是一个错误?注意,如果我在Julia中使用完整矩阵,我得到了正确的结果,但由于我的应用程序中的矩阵非常稀疏(有限元模拟中的基本边界条件),我更倾向于使用稀疏矩阵

1 个答案:

答案 0 :(得分:3)

看起来sparseBitArray有一些问题。

julia> VERSION
v"0.3.5"
julia> A = [.1;.2;.3;.4;.11;.13;.14;.01;.04;.09]
julia> B = spzeros(10,1)
julia> C = A .< .12
julia> B[C] = 1
julia> B
10x1 sparse matrix with 5 Float64 entries:
        [0 ,  1]  =  1.0
        [0 ,  1]  =  1.0
        [1 ,  1]  =  1.0
        [1 ,  1]  =  1.0
        [1 ,  1]  =  1.0

所以我和提问者一样。但是,当我做事情的时候&#34;我的方式&#34;

julia> B = sparse(C)
ERROR: `sparse` has no method matching sparse(::BitArray{1})

julia> B = sparse(float(C))
10x1 sparse matrix with 5 Float64 entries:
        [1 ,  1]  =  1.0
        [5 ,  1]  =  1.0
        [8 ,  1]  =  1.0
        [9 ,  1]  =  1.0
        [10,  1]  =  1.0

如果您将BitArray转换为Float,这样就行了。我认为这种解决方法可以帮助您实现目标,但似乎sparse似乎可以与BitArray一起使用。

一些额外的想法(编辑)

正如我对此进一步思考的那样,我发现BitArray没有sparse()方法的一个原因是,对于已经非常紧凑的类型实现稀疏存储并不是非常有用。考虑来自上方的BC

julia> sizeof(C)
8

julia> sizeof(B)
40

因此,对于这些数据,sparse版本比原始版本大得多。它实际上比这个简单(可能是简单的)检查乍一看更糟糕。 sizeof(::BitArray{1})似乎是整个数组的大小,但sizeof(::SparseMatrixCSC{})显示了存储的每个元素的大小。因此,实际大小差异就像8对200字节。

当然,如果数据足够稀疏(略低于1%true),稀疏存储开始赢得胜利,尽管它的开销很高。

julia> C = rand(10^6) .< 0.01

julia> B = sparse(float(C))

julia> sizeof(C)
125000

julia> sum(C)*sizeof(B)
394520

julia> C = rand(10^6) .< 0.001

julia> B = sparse(float(C))

julia> sizeof(C)
125000

julia> sum(C)*sizeof(B)
40280

因此,sparse()没有BitArray方法可能不是疏忽。它可能代表节省大量空间的情况可能不像乍看之下那么普遍。