2017-02-03 18 views
0

任意の正方行列とそのインデックスの非ゼロ要素のみを保存することを目的としたコードを作成して修正するのに役立つ人はいますか?基本的には、MATLABでは 'sparse'と同じ機能を果たすスクリプトを書く必要があります。MATLABにゼロ以外のエントリを抽出して格納する

`%Consider a 3x3 matrix 
A=[ 0 0 9 ;-1 8 0;0 -5 0 ]; 
n=3; %size of matrix 

%initialise following arrays: 
RI= zeros(n,1); %row index 
CI = zeros(n,1); %column index 
V = zeros(n,1); %value in the matrix 
for k = 1:n %row 1 to n 
    for j = 1:n %column 1 to n 
     if A(k,j)~=0 
     RI(k)=k; 
     CI(j)=j; 
     V(k,j)=A(k,j); 
     end 
    end 
end` 
+0

[検索](https://www.mathworks.com/help/matlab/ref/find.html)?私はあなたが期待している出力がわからない。 – beaker

+0

スパース(A)を書くのと同じ出力が必要です。 –

+0

それでは、あなたは 'sparse'を使わないのですか? – beaker

答えて

0

find functionを使用して、すべての非ゼロ要素を見つけることができます。

ので、

[RI, CI, V] = find(A); 
%  2  1 -1 
%  2  2  8 
%  3  2 -5 
%  1  3  9 

EDIT:

私はあなたの目標は、MATLABでのコーディングを学ぶことでしたあなたのコメントから実現し、期待どおりのコードは動作しませんでしたなぜあなたは不思議に思うかもしれません。だからあなたに似たサンプルコードとともにこの問題を説明しようとします。

% Given: 

A = [0 0 9; -1 8 0; 0 -5 0];

まず、手動でサイズをn = 3と指定する代わりに、組み込みのsize機能を使用することをおすすめします。

sz = size(A); 
% note that this contains 2 elements: 
% [number of rows, number of columns] 

次に、我々は彼らの大きさを知っていただきたいと思い配列RICIVを初期化します。ゼロ以外の要素の数がわからないので、 には2つのオプションがあります。(1)ゼロ以外の要素の数以上であることが保証されている大きい数を選択します。たとえば、prod(sz) 。 (なぜそれは本当ですか?)。 (2)Matlabを初期化しないで、必要に応じて動的にメモリを割り当てます。私は以下のコードの2番目のオプションに従います。

% we'll keep a count of non-zero elements as we find them 
numNZ = 0; % this will increment every time a non-zero element is found 
for iCol = 1:sz(2) %column 1 to end 
    for iRow = 1:sz(1) %row 1 to end 
     if A(iRow,iCol)~=0 
      numNZ = numNZ + 1; 
      RI(numNZ) = iRow; 
      CI(numNZ) = iCol; 
      V(numNZ) = A(iRow,iCol); 
     end 
    end 
end 

disp([RI, CI, V]) 
%  2  1 -1 
%  2  2  8 
%  3  2 -5 
%  1  3  9 

意味がありますか?

0

私は、これはあまり知られていないプログラミング言語を学ぶことだということを確認しました。最も簡単な解決策は、sparse自体を使用することですが、それはプログラミングについての洞察を与えません。同様に使用できるfindもありません。

ここでは、使用開始したのと同じルートを使用できます:手続きforifを各行と各列に渡します。ほぼすべてのプログラミング言語ですが、句読点のいくつかの癖があります。しかし、たとえあなたが間違いを訂正したとしても(nは行数ではなく、非ゼロの項目数でなければなりません)、これはMatlabで数値作業を行うのが非常に遅い方法です。ここで

は、うまくいけばそのままMATLABはほど強力になり、物事の一つである物事の「ベクトル化」の方法、にいくつかの洞察を提供します、別の(まだ非効率的な、しかしそれほど)方法です:

function [RI, CI, V] = mysparse(A)  % first: use functions! 


[nRows, nCols] = size(A); 
[allRowIndices, allColIndices] = ndgrid(1:nRows, 1:nCols) % let's leave the semicolon off so you can see for yourself what it does. 
                  % It's very similar to `meshgrid` which you'll see more often (it's heavily used in Matlab graphics) 
                  % but `ndgrid` is "simpler" in that it's more in tune with the fundamental conventions of Matlab (rows, then columns) 

isNonZero = A ~= 0; % this gives you a "logical array" which is a very powerful thing: it can be used as a subscript to select elements from another array, in one shot... 

RI = allRowIndices(isNonZero); % like this 
CI = allColIndices(isNonZero); % or this 
V = A(isNonZero);    % or even this 

RI = RI(:); % have to do this explicitly, because the lines above will reshape the values into a single long string under some circumstances but not others 
CI = CI(:); 
V = V(:); 
0

N x 3行列を使用します。ここで、Nは、行列内の非ゼロ要素の数です。

% Define a matrix A as follows: 
A = randi([0 1],[4 4]) 
for i=1:16 
    if A(i) ~= 0 
     A(i) = rand; 
    end 
end 

[row,col] = find(A); 
elms = A(A~=0); % MATLAB always works in column-major order and is consistent, 
       % so no need to use sub2ind to access elements given by find 

newSparse_A = [row col elms]; 

出力:

newSparse_A = 

1.0000 1.0000 0.9027 
2.0000 1.0000 0.9448 
3.0000 1.0000 0.4909 
1.0000 2.0000 0.4893 
2.0000 2.0000 0.3377 
4.0000 2.0000 0.9001 

>> sparse(A) 

ans = 



    (1,1)  0.9027 
    (2,1)  0.9448 
    (3,1)  0.4909 
    (1,2)  0.4893 
    (2,2)  0.3377 
    (4,2)  0.9001 
関連する問題