MATLAB Language
Forループ
サーチ…
備考
列ベクトルを反復する
一般的なバグの原因は、列ベクトルの要素をループすることです。列ベクトルは、1つの列を持つ行列のように扱われます。 (実際にはMATLABで区別がありません。) for
ループをカラムに設定され、ループ変数で一度実行されます。
% Prints once: [3, 1]
my_vector = [1; 2; 3];
for i = my_vector
display(size(i))
end
繰り返し変数の変更
反復変数を変更すると、現在の反復の値が変更されますが、それ以降の反復では値には影響しません。
% Prints 1, 2, 3, 4, 5
for i = 1:5
display(i)
i = 5; % Fail at trying to terminate the loop
end
右側のa:b
特殊ケースのパフォーマンス
基本的な例では、行ベクトルを作成し、それを反復する通常のインスタンスとして1:n
を扱います。パフォーマンス上の理由から、Matlabは実際にはa:b
またはa:c:b
扱いますa:b
、行ベクトルを完全には作成せず、各要素を一度に1つずつ作成するようにします。
これは構文を少し変更することで検出できます。
% Loops forever
for i = 1:1e50
end
% Crashes immediately
for i = [1:1e50]
end
ループ1〜n
最も単純なケースは、固定された既知の回数だけタスクを実行することです。 1からnまでの数値を表示したいとすれば、次のように書くことができます:
n = 5;
for k = 1:n
display(k)
end
ループは内側の文を実行し、 for
とend
間のすべてをn
回実行します(この例では5)。
1
2
3
4
5
もう一つの例があります:
n = 5;
for k = 1:n
disp(n-k+1:-1:1) % DISP uses more "clean" way to print on the screen
end
今回は、ループ内のn
とk
両方を使用して、「ネスト」表示を作成します。
5 4 3 2 1
4 3 2 1
3 2 1
2 1
1
ベクトルの要素を反復する
for
ループの代入の右側は、任意の行ベクトルにすることができます。代入の左側には任意の有効な変数名を使用できます。 for
ループは、このベクトルの別の要素をそれぞれ実行する変数に割り当てます。
other_row_vector = [4, 3, 5, 1, 2];
for any_name = other_row_vector
display(any_name)
end
出力が表示されます
4
3
5
1
2
(Matlab 1:n
は、 [1, 2, ..., n]
行ベクトルを作成するための構文なので、 1:n
バージョンはこれの通常のケースです)。
したがって、次の2つのコードブロックは同じです。
A = [1 2 3 4 5];
for x = A
disp(x);
end
そして
for x = 1:5
disp(x);
end
以下も同じです:
A = [1 3 5 7 9];
for x = A
disp(x);
end
そして
for x = 1:2:9
disp(x);
end
任意の行ベクトルが行います。彼らは数字である必要はありません。
my_characters = 'abcde';
for my_char = my_characters
disp(my_char)
end
出力する
a
b
c
d
e
行列の列を反復する
代入の右辺が行列の場合、各反復で変数にはこの行列の後続の列が割り当てられます。
some_matrix = [1, 2, 3; 4, 5, 6]; % 2 by 3 matrix
for some_column = some_matrix
display(some_column)
end
(行ベクトルバージョンはこれの通常の場合です。Matlabでは行ベクトルは列のサイズが1の行列に過ぎないからです)
出力が表示されます
1
4
2
5
3
6
すなわち反復行列の各列が表示され、各列は各display
呼び出しで印刷される。
ループオーバーインデックス
my_vector = [0, 2, 1, 3, 9];
for i = 1:numel(my_vector)
my_vector(i) = my_vector(i) + 1;
end
for
ループで行われるほとんどの簡単な処理は、ベクトル化された操作によって、より迅速かつ簡単に実行できます。たとえば、上記のループは、 my_vector = my_vector + 1
置き換えることができます。
ネストループ
ループを入れ子にして、反復タスクを別の反復タスク内で実行することができます。次のループを考えてみましょう。
ch = 'abc';
m = 3;
for c = ch
for k = 1:m
disp([c num2str(k)]) % NUM2STR converts the number stored in k to a charachter,
% so it can be concataneted with the letter in c
end
end
2つのイテレータを使用して、 abc
と1:m
の要素のすべての組み合わせを表示します。
a1
a2
a3
b1
b2
b3
c1
c2
c3
また、ネストされたループを使用して、毎回実行するタスクと複数の反復で1回実行するタスクを結合することもできます。
N = 10;
n = 3;
a1 = 0; % the first element in Fibonacci series
a2 = 1; % the secound element in Fibonacci series
for j = 1:N
for k = 1:n
an = a1 + a2; % compute the next element in Fibonacci series
a1 = a2; % save the previous element for the next iteration
a2 = an; % save ht new element for the next iteration
end
disp(an) % display every n'th element
end
ここではすべてのフィボナッチ系列を計算したいが、毎回n
番目の要素のみを表示するので、
3
13
55
233
987
4181
17711
75025
317811
1346269
私たちができるもう一つのことは、内側のループの中で最初の(外側の)イテレータを使うことです。もう一つの例があります:
N = 12;
gap = [1 2 3 4 6];
for j = gap
for k = 1:j:N
fprintf('%d ',k) % FPRINTF prints the number k proceeding to the next the line
end
fprintf('\n') % go to the next line
end
今回は、ネストされたループを使用して出力をフォーマットし、エレメント間の新しいギャップ( j
)が導入されたときにのみラインを制動します。外側ループのギャップ幅をループし、それを内側ループ内で使用して、ベクトルを反復処理します。
1 2 3 4 5 6 7 8 9 10 11 12
1 3 5 7 9 11
1 4 7 10
1 5 9
1 7
注意:奇妙な同じカウンターネストループ。
これは他のプログラミング環境では見られません。私は何年か前にそれを見てきました。なぜそれが起こったのか理解できませんでしたが、しばらくの間MATLABを使って作業をした後、私はそれを理解することができました。以下のコードスニペットを見てください:
for x = 1:10
for x = 1:10
fprintf('%d,', x);
end
fprintf('\n');
end
これが正しく動作するとは思っていませんが、正しく動作することは期待できません。次の出力が生成されます。
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
その理由は、MATLABの他のすべてのものと同様に、 x
カウンタは行列でもあり、これは正確なベクトルです。したがって、 x
は、すべての結果的なループ(ネストされているか否か)によって適切に参照される「配列」(コヒーレントな連続したメモリ構造)への参照に過ぎない。ネストされたループが同じ識別子を使用するという事実は、その配列からの値がどのように参照されるかに違いはありません。唯一の問題は、入れ子にされたループの中で、外側のx
はネストされた(ローカルの) x
によって隠されているため、参照できないということです。ただし、ネストされたループ構造の機能はそのまま残っています。