2007年4月16日月曜日

matlab: end+1

Matlab では,配列の最終要素のインデクスを表す end という指定法がある.
この end にまつわる小ネタ.

配列に次々要素を追加していく,という処理をスクリプト中に書く場合,番号を決め打ちする書き方

a(1) = 1;
a(2) = 2;
a(3) = 3;

をすると,順番を入れ替えたいときや,間に要素を挟みたいときに一大事になる.

そこで,こんな書き方が楽チンだ.

a(1) = 1;
a(end+1) = 2;
a(end+1) = 3;

これなら入れ替えや追加をコピペで簡単に行える.

ちなみにこう書いた場合,リストは横に,つまり2次元目に伸びていく.上の例では,a は 1 x 3 のサイズになる.
もともとが 3 x 1 だったりした場合,4 x 1 に伸びる.もともとが 3 x 2 だったりした場合,

>> a=rand(3,2);
>> a(end+1)=3
???  In an assignment  A(I) = B, a matrix A cannot be resized.

のように怒られる.この場合でも,伸ばす次元が明示的になるような書き方,すなわち

>> a=rand(3,2);
>> a(3,end+1)=3
a =
    0.1934    0.5417         0
    0.6822    0.1509         0
    0.3028    0.6979    3.0000
>>

のようにすれば,各次元についての end としてちゃんと解釈される.

実は上記の怒られ方は end に限ったことではない.つまり,

>> a=rand(3,2);
>> a(7)=3
???  In an assignment  A(I) = B, a matrix A cannot be resized.

とこういうことなのだ.しかし,

>> a=rand(3,2);
>> a(5)=3
a =
    0.3412    0.3093
    0.5341    3.0000
    0.7271    0.5681

とこういうことでもある.ここで a(end-1) としてももちろん同じ.結局,
  • linear index で問題ないものはそのように解釈される
  • linear index で曖昧さが出る状況では怒られる
  • end は,それが解釈される次元における末尾のインデクスの数字と単純に置き換え
というルールだと思っていいのだろう.

補足.もちろん,end+1 に限らず end+10 のような指定も可能です.