0

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

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

4

2 回答 2

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 中的效率差不多。

测试这个实现与内置的sparseforA = rand(500); A(A<0.5) = 0;给出:

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

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

不要在 MATLAB 中做这种事情!

于 2013-10-24T07:28:54.577 回答
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]
于 2013-10-28T18:18:39.997 回答