私はwhileループの結果を出力できる2つの列を持つ可変長のゼロ行列を設定しようとしています(調整された時間ステップを持つオイラーの方法からのステップデータを格納するために使用する予定です) 。長さは、ループの反復回数によって決まります。MATLABで長さが不明な行列はありますか?
ループを実行している間にこれを行う方法があるかどうか、またはそれを設定する必要があるかどうか、それをどうやって行うかについては疑問に思っています。
私はwhileループの結果を出力できる2つの列を持つ可変長のゼロ行列を設定しようとしています(調整された時間ステップを持つオイラーの方法からのステップデータを格納するために使用する予定です) 。長さは、ループの反復回数によって決まります。MATLABで長さが不明な行列はありますか?
ループを実行している間にこれを行う方法があるかどうか、またはそれを設定する必要があるかどうか、それをどうやって行うかについては疑問に思っています。
列の数は、(ループ内で)あなたは常にあなたの行列に行を追加することができます固定されている場合
例えば当然の
while (....)
.....
new_row =[x y] ; % new row with values x & y
mat = [mat ; new_row];
あなたはそれを事前に割り当てるマトリックス
MATLABは、自動メモリ管理による動的な型指定を使用します。つまり、使用する前に固定サイズの行列を宣言する必要はありません。移動するにつれて変更することができ、MATLABは動的にメモリを割り当てます。
BUTそれを使用し、次いで第1の行列のためのメモリーを割り当てることがは、より効率的な方法とあります。しかし、あなたのプログラムがこの種の柔軟性を必要とするなら、それに行きましょう。
あなたの行列に行を追加し続ける必要があると思います。次のコードは動作するはずです。ここで
Matrix = [];
while size(Matrix,1) <= 10
Matrix = [Matrix;rand(1,2)];
end
disp(Matrix);
、我々は動的Matrix
のために新しい行を追加するたびに必要なスペースを再割り当てしています。あらかじめ、行数の上限を知っている場合は、Matrix = zeros(20,2)
を宣言してから、各行を徐々に行列に挿入してください。
% Allocate space using the upper bound of rows (20)
Matrix = zeros(20,2);
k = 1;
for k = 1:10
Matrix(k,:) = rand(1,2);
end
% Remove the rest of the dummy rows
Matrix(k+1:end,:) = [];
にヤコブが掲載同じものの別の味がより効率的ですwhileループの前に反復回数を知っていれば。
for counter = 1:10
Matrix(counter,:) = rand(1,2);
end
disp(Matrix);
これについて「良い」ことは、パフォーマンスに役立つ最小のサイズを推測できることです。
これは、同様に参考になります。まだスペース効率になろうとしながら、心の中で性能を有するhttp://www.mathworks.com/help/matlab/math/resizing-and-reshaping-matrices.html#f1-88760
+1 - クリーナー – Jacob
別のアプローチは、必要に応じてよりバッチを追加し、大規模なバッチでメモリを事前に割り当てることです。これはあらかじめいくつのことを知らなくても大量のアイテムを追加する必要がある場合に適しています。
BLOCK_SIZE = 2000; % initial capacity (& increment size)
listSize = BLOCK_SIZE; % current list capacity
list = zeros(listSize, 2); % actual list
listPtr = 1; % pointer to last free position
while rand<1-1e-5 % (around 1e5 iterations on avrg)
% push items on list
list(listPtr,:) = [rand rand]; % store new item
listPtr = listPtr + 1; % increment position pointer
% add new block of memory if needed
if(listPtr+(BLOCK_SIZE/10) > listSize) % less than 10%*BLOCK_SIZE free slots
listSize = listSize + BLOCK_SIZE; % add new BLOCK_SIZE slots
list(listPtr+1:listSize,:) = 0;
end
end
list(listPtr:end,:) = []; % remove unused slots
EDIT:時間比較として、以下のケースを考慮してください
list = zeros(50000,2); list(k,:) = [x y];
list = []; list(k,:) = [x y];
私のマシンでは、結果は次の通りであった:
1)経過時間が0.080214秒あります。
2)経過時間は0.065513秒です。
3)経過時間は24.433315秒です。
コメントでの議論の後、私は最新のR2014bのリリースを使用していくつかのテストを再実行してきました。結論として、MATLABの最新バージョンでは、自動アレイの成長のパフォーマンスが大幅に向上しました。
しかし、キャッチがあります。配列は最後の次元(2D行列の場合は列)を超えて成長している必要があります。そのため、もともと意図したような行の追加は、事前割り当てなしではまだ遅すぎます。これは、上記の提案されたソリューションが実際に役立つことができる場所です(配列をバッチで拡張することによって)。
は、テストのフルセットは、ここを参照してください:またhttps://gist.github.com/amroamroamro/0f104986796f2e0aa618
woohoo!洞察力のある点+それを裏付ける測定値。ありがとう。 –
p.s.ほとんどの可変サイズメソッド(文字列クラスなど)は固定ブロックサイズを使用せず、倍率K(通常はK = 2)だけサイズを増やします。これはO(log N)に割り当てステップ数を制限し、メモリ効率を気にするならば、常にK = 1.2または1.1を選択し、効率/割り当てステップ数をトレードオフするために計算のヒット数を扱うことができます。 –
あなたはおそらく正しいでしょう。あなたはそのようなコードを簡単に変更することができます。いくつかのパラメータを調整することもできます:サイズを増やすタイミング、増強するタイミング(K = 1.1から2まで増やす) – Amro
、これはクラスの割り当てのためであり、あなたが反復を示す必要がある場合。オイラーの実装でsprintfを使用することができます。 – ccook
もう一つの関連する質問:[空のMATLAB行列にベクトルを追加する](0120-18753) – Amro