web-dev-qa-db-ja.com

MATLABで行列要素を合計する方法は何ですか?

与えられた行列:

A = [1 2 3; 4 5 6; 7 8 9];
  1. どのようにforループを使用して、行列の要素の合計を計算できますか?
  2. 関数sumを使用して1行のMATLABコマンドを記述し、Aの行列要素を合計します。

私の答え:

1)

for j=1:3,
    for i=j:3,
        A(i,:) = A(i,:)+A(j+1,:)+A(j+2,:)
    end
end

2)

sum(A)

これらは正しい答えですか? ifwhileforの使い方を知りませんでした。誰かが私にそれを説明できますか?

11
izzat

非常に大きな行列の場合、sum(sum(A))を使用するとsum(A(:))よりも高速になる場合があります。

>> A = Rand(20000);
>> tic; B=sum(A(:)); toc; tic; C=sum(sum(A)); toc
Elapsed time is 0.407980 seconds.
Elapsed time is 0.322624 seconds.
30

1)

total = 0;
for i=1:size(A,1)
  for j=1:size(A,2)
    total = total + A(i,j);
  end
end

2)

total = sum(A(:));
18
merv

最初の質問に対する別の答えは、ループにoneを使用して、関数---を使用して配列に linear indexing を実行することです [〜#〜] numel [〜#〜] 要素の総数を取得するには:

total = 0;
for i = 1:numel(A)
  total = total+A(i);
end
10
gnovice

可能な限りforループは避けてください。

sum(A(:))

ただし、論理的なインデックス作成が行われている場合は(:)を使用できませんが、

% Sum all elements under 45 in the matrix
sum ( sum ( A *. ( A < 45 ) )

Sumは列を合計し、最初の合計で作成された行ベクトルを合計します。これは、行列が2次元の場合にのみ機能することに注意してください。

3
Reed Richards

ベストプラクティスは、Matlabでループや再帰を回避することです。

sum(A(:))sum(sum(A))の間。私の経験では、Matlabの配列は、スタックされた列ベクトルとしてメモリの連続ブロックに格納されているようです。したがって、Aの形状はsum()ではまったく問題になりません。 (reshape()をテストして、Matlabで再整形が高速かどうかを確認できます。高速である場合、配列の形状がデータの格納方法と操作方法に直接関係していないと考える理由があります。)

そのため、sum(sum(A))が高速になる理由はありません。 MatlabがAの各列の合計を最初に記録し、次に列全体で合計する行ベクトルを実際に作成する場合、速度は遅くなります。しかし、sum(sum(A))はユーザーの間で非常に広まっていると思います。 sum(sum(A))sum(A(:))と同じように1つのループにハードコードする可能性があります。

以下に、いくつかのテスト結果を示します。各テストでは、A = Rand(size)およびサイズが表示されたテキストで指定されています。

まず、tic tocを使用します。

_Size 100x100
sum(A(:))
Elapsed time is 0.000025 seconds.
sum(sum(A))
Elapsed time is 0.000018 seconds.

Size 10000x1
sum(A(:))
Elapsed time is 0.000014 seconds.
sum(A)
Elapsed time is 0.000013 seconds.

Size 1000x1000
sum(A(:))
Elapsed time is 0.001641 seconds.
sum(A)
Elapsed time is 0.001561 seconds.

Size 1000000
sum(A(:))
Elapsed time is 0.002439 seconds.
sum(A)
Elapsed time is 0.001697 seconds.

Size 10000x10000
sum(A(:))
Elapsed time is 0.148504 seconds.
sum(A)
Elapsed time is 0.155160 seconds.

Size 100000000
Error using Rand
Out of memory. Type HELP MEMORY for your options.

Error in test27 (line 70)
A=Rand(100000000,1);
_

以下はcputimeを使用しています

_Size 100x100
The cputime for sum(A(:)) in seconds is 
0
The cputime for sum(sum(A)) in seconds is 
0

Size 10000x1
The cputime for sum(A(:)) in seconds is 
0
The cputime for sum(sum(A)) in seconds is 
0

Size 1000x1000
The cputime for sum(A(:)) in seconds is 
0
The cputime for sum(sum(A)) in seconds is 
0

Size 1000000
The cputime for sum(A(:)) in seconds is 
0
The cputime for sum(sum(A)) in seconds is 
0

Size 10000x10000
The cputime for sum(A(:)) in seconds is 
0.312
The cputime for sum(sum(A)) in seconds is 
0.312

Size 100000000
Error using Rand
Out of memory. Type HELP MEMORY for your options.

Error in test27_2 (line 70)
A=Rand(100000000,1);
_

私の経験では、両方のタイマーは.1までしか意味がありません。したがって、Matlabタイマーで同様の経験がある場合、どのテストもsum(A(:))sum(sum(A))を識別できません。

コンピューターで許容される最大サイズをさらに数回試しました。

_Size 10000x10000
sum(A(:))
Elapsed time is 0.151256 seconds.
sum(A)
Elapsed time is 0.143937 seconds.

Size 10000x10000
sum(A(:))
Elapsed time is 0.149802 seconds.
sum(A)
Elapsed time is 0.145227 seconds.

Size 10000x10000
The cputime for sum(A(:)) in seconds is 
0.2808
The cputime for sum(sum(A)) in seconds is 
0.312

Size 10000x10000
The cputime for sum(A(:)) in seconds is 
0.312
The cputime for sum(sum(A)) in seconds is 
0.312

Size 10000x10000
The cputime for sum(A(:)) in seconds is 
0.312
The cputime for sum(sum(A)) in seconds is 
0.312
_

それらは同等に見えます。どちらでもいいです。ただし、sum(sum(A))では、配列の次元が2であることを知っている必要があります。

2
Argyll

2次元配列のすべての要素を合計しようとしています

Matlabでの使用

Array_Sum = sum(sum(Array_Name));

0
Riz