2016-10-14 21 views
0

は、次のように私はコードセグメントを持って考えてみましょう。このようにMATLABのリスト操作

ケース1

n = 20; 
for i = 2 : n 
    mat = rand([2,i]); 
    mat = [mat, mat(:,1)]; %add the first column to the last 
    %feed the variable 'mat' to a function 
end 

ケース2

n = 10; 
list = []; 
for i = 1 : n 
    a = rand([2,1]); 
    b = rand([2,2]) 
    list = [list, [a,b]]; 
end 

、MATLABは、以下の提案を与えます:

変数 'mat'は、すべてのループでサイズを変更するように見えます。スピードアップのために事前割り当てを検討してください。

変数 'list'は、すべてのループでサイズを変更するように見えます。スピードアップのために事前割り当てを検討してください。

私はMATLAB newconerですので、この問題に対処する方法を知りたいと思います。どのようにするかネイティブのMATLABスタイル?前もって感謝します。

+0

あなたのコードをもっと表示できますか?欠落している欠点、特にループがあります。また、あなたはどういう意味ですか?_最後の "_"に最初の列を追加しますか? 'plus'のように、を追加するか、最後の列を置き換えるか、別の列として追加して、行列を展開しますか(これはあなたが今行っていることです)? –

+0

何が問題なのですか? – Bort

+0

@StewieGriffinあなたの提案をありがとう。実際、私はループを忘れてしまった。 – user123

答えて

2

それは理にかなっているだけだと、私は、後者の場合に焦点を当てます:

n = 10; 
list = []; 
for i = 1 : n 
    a = rand([2,1]); 
    b = rand([2,2]) 
    list = [list, [a,b]]; 
end 

あなたがここでやっている、各ループのために、ランダムな数字を持つ2つのベクトルを作成することで、abaは、寸法が2x1であり、bは、寸法が2x2である。次に、これらの2つを行列listで連結します。

randへの各呼び出しは独立しているため、rand(2,3)は同じ方法で動作します([rand(2,2), rand(2,1)])。

今度はループ回数が10回になり、毎回rand(2,3)を追加するので、実質的には[rand(2,2), rand(2,1), rand(2,2), rand(2,1) ...]となります。これは、はるかに高速ですrand(2,30)に相当します。したがって、「スピードアップのために事前割り当てを検討する」


今、あなたの連結がランダム行列が含まれていますが、実際にはない出力したい全体の行列は、その後、事前に割り当てとインデックスを使用して行列にそれを挿入することができ、いくつかの機能から出力されていない場合:

はのは、いくつかの関数を定義してみましょう:

function x = loopfun(n) 
x = n*[1; 2]; 
end 


function list = myfun1(n) 
list = zeros(2, n); 
for ii = 1:n 
    list(:,ii) = loopfun(ii); 
end 
end 

function list = myfun2(n)  
list = []; 
for ii = 1:n 
    list = [list, loopfun(ii)]; 
end 
end 

f1 = @() myfun1(100000); f2 = @() myfun2(100000); 
fprintf('Preallocated: %f\nNot preallocated: %f\n', timeit(f1), timeit(f2)) 

Preallocated: 0.141617 
Not preallocated: 0.318272 

あなたが見ることができるように、事前割り当てを持つ関数が増加サイズの行列を持つ関数の2倍の速さです。反復回数が少ないとその差は小さくなりますが、一般的な考え方は同じです。

f1 = @() myfun1(5); f2 = @() myfun2(5); 
fprintf('Preallocated: %f\nNot preallocated: %f\n', timeit(f1), timeit(f2)) 

Preallocated: 0.000010 
Not preallocated: 0.000018 
+0

あなたの答えをありがとう。私は単純に自分の質問に 'rand'を使います。実際、 'a'と' b'は他の関数の戻り値から来ます。私の実装によれば、 'a'は' 2 xi'の行列で、 'b'は' 2xj'の行列です。ここで 'i'と' j'は1から5までです。 – user123

+0

更新された回答。 –