matlab:任何矩阵的稀疏函数

时间:2013-10-24 04:14:49

标签: matlab matrix sparse-matrix sparse-array

我正在尝试为任何矩阵大小编写稀疏函数代码。例如,如果我有一个矩阵:

A = [ 0   0   0   5
      0   2   0   0
      1   3   0   0
      0   0   4   0];
  a=size(A);
  b=size(A);
  c=0;
  position=0;
  for i=1:a for j=1:b if A(i,j) ~=0
              c=c+1;
              position=position+1;
              S(c,:)=[position,i,j,A(i,j)];
          end
      end
  end
S

S - >是A矩阵的所有非零元素的存储矩阵。 除了这些信息(索引,行号,列号,值)之外,如何在矩阵中包含另外两列,这些列显示行和列中的下一个元素。列中的下一个元素。

2 个答案:

答案 0 :(得分:2)

这是一些学术手淫的成果:)

1)它使用的数组增长方案比在每次迭代时增长数组要高效得多 2)通过使用索引的最小必要数据类

来优化内存占用/使用
K      = 1.1;
inds   = zeros(10,2, 'uint8');
values = zeros(10,1, class(A));

count = 1;
for ii = 1:numel(A)    
    if A(ii)

        %// grow arrays and/or change type when necessary
        if count > size(inds,1)

            %// Re-cast datatype of inds
            if count > intmax(class(inds))
                switch class(inds)
                    case 'uint8'
                        inds = uint8(inds);
                    case 'uint16'
                        inds = uint32(inds);
                    case 'uint32'
                        inds = uint64(inds);
                    case 'uint64'
                        error('There are too many non-zero elements.');
                    otherwise
                        error('...huh?!');
                end
            end

            %// now grow the arrays
            inds   = [inds;   zeros(ceil((K-1)*count), 2, class(inds))  ]; %#ok<AGROW>
            values = [values; zeros(ceil((K-1)*count), 1, class(values))]; %#ok<AGROW>

        end

        %// assign the indices and values
        inds(count,:) = [mod(ii-1,size(A,1))+1; ceil(ii/size(A,1))];
        values(count) = A(ii);
        count = count + 1;

    end
end

%// chop-off any remaining zeros
inds   = inds  (1:count-1,:);
values = values(1:count-1,:);

除了你可以做的一些相对较小的优化之外,这和你在MATLAB中的效率一样高效。

测试此实现与sparse的内置A = rand(500); A(A<0.5) = 0;相比:

Elapsed time is 1.802105 seconds.  %// implementation above
Elapsed time is 0.006877 seconds.  %// sparse

所以慢了大约250倍。所有这一切都证明了一件事:

不要在MATLAB中做这件事!

答案 1 :(得分:0)

A = [ -1   0  -2   0   0
       2   8   0   1   0
       0   0   3   0  -2
       0  -3   2   0   0
       1   2   0   0  -4];

  a=size(A);
  b=size(A);
  c=0;
  position=0;
  for i=1:a 
      for j=1:b 
          if A(i,j) ~=0
              c=c+1;
              position=position+1;
              S(c,:)=[position,i,j,A(i,j)];
          end
      end
  end

  index=size(S,1);
  NIR = [];
for i = 1:index
    for j = 1:index
        if i ~= j
            if S(i,2) == S(j,2)if S(i,3) < S(j,3)if length(NIR) < i
                        NIR(i,1) = S(j,1);
                    end
                end
            end
        end
    end
    if length(NIR) < i
        NIR(i,1) = 0;
    end
end

%finding NIC
NIC = [];
for i = 1:index
    for j = 1:index
        if i ~= j
            if S(i,3) == S(j,3)if S(i,2) < S(j,2)if length(NIC) < i
                        NIC(i,1) = S(j,1);
                    end
                end
            end
        end
    end
    if length(NIC) < i
        NIC(i,1) = 0;
    end
end

Sprs=[S,NIR,NIC]

n=nnz(A);
r=size(A);
m=r(1,1);
position=zeros(n,1);
t=1;
FIR= zeros(m,1);
FIC= zeros(m,1);
for i= 1: n
    position(i,1)= i;
end

for i= 1: m
    for j= 1: m
        if (A(i,j)~= 0)
            value(var,1)= A(i,j);
            row(var,1)= i;
            col(var,1)= j;
            var= var+ 1;
        end
    end
end
for j= 1: m
    for i= t: n
        if row(i,1)== j
            FIR(j,1)= position(i,1);
            t= i+1;
            break;
        end
    end
end
for k= 1: m
for l= 1: n
    if (col(l,1)== k)
        FIC(k,1)= position(l,1);
        break;
    end
end
end

S1=[FIR, FIC]