【问题标题】:filling sparse matrices efficiently matlab高效填充稀疏矩阵matlab
【发布时间】:2015-11-20 00:44:55
【问题描述】:

我正在处理一个非常大的稀疏矩阵:

  U = sparse(a,b)   % a and b are very large

另一方面,存在具有“a”行的单元格 Ind。在每一行中,存在一个“可变”数量的元素,例如:

  Ind{1} = [1 3 5 19 1000 1340]
  Ind{2} = [9 100 1500 1600 8000 b]
    ...
  Ind{a} = [3 5 6 90 1000 4300 5712 9480]

可以看出,Ind{i} 中的最大索引号可以是“b”。对于这些索引向量中的每一个,还存在一个内容矩阵,如 'c' :

 c = [2 3 1 6 3 5 1 3 4 1 2 ... 5]   

问题来了,对于 Ind{i} 中的每个元素,我想用 c(Ind{i}) 填充 'row = i' 和 'col=Ind{i}',即

  for i = 1 : a
      U(i,Ind{i}) = c(Ind{i}) ;
  end

问题是'a'非常大,循环需要很长时间才能计算出来。有什么避免循环的想法吗?

【问题讨论】:

    标签: matlab sparse-matrix


    【解决方案1】:

    我不确定是否有办法避免循环,但我确实获得了 2 到 20 倍的速度提升(我将 a 的范围从 3 到 5,000,b 固定为 10,000)通过构建三个大向量(两个用于行和列索引,一个用于值)并在循环后构建稀疏矩阵:

    strides = cellfun(@numel,Ind);
    n       = sum(strides);
    I(n,1)  = 0;
    J(n,1)  = 0;
    S(n,1)  = 0;
    bot     = 1;
    
    for k = 1:a
        top  = bot + strides(k) - 1 ;
        mask = bot:top              ;
        %
        I(mask) = k         ;
        J(mask) = Ind{k}    ;
        S(mask) = c(Ind{k}) ;
        %
        bot = top + 1;
    end
    U = sparse(I,J,S,a,b);
    

    这是sparse 的推荐用法,因为分配给稀疏矩阵的成本比常规数组高。

    【讨论】:

    • U = sparse(I,J,S,a,b) 非常有趣。只剩下一个小问题:假设 J=[50 300 12 9 50 12] 。如果我们想让列数等于 max(J),那是无稽之谈。在这个例子中,J 需要是:J = [3 4 2 1 3 2]。如果 J 非常大,您认为什么函数可以进行这种转换?
    • @YAS "如果我们想让列数等于 max(J)" 我完全不明白这一点。 sparse 的最后一个参数定义了稀疏矩阵的最大列数。
    • @TroyHaskin 小注。你可以做strides = cellfun(@numel, Ind);。无需使用numel 包装匿名函数,因为您可以直接调用numel
    • @rayryeng 呵呵。我没有意识到这两种形式之间存在差异。
    • 不,没有...只是少打字:) 这是我的代码高尔夫。
    猜你喜欢
    • 2012-07-28
    • 1970-01-01
    • 2018-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多