2017-01-13 19 views
0

関数にループを適用したいと思います。関数を反復処理する方法は?

function D = root(x) 
v = 1; 
D(1) = x(1) + x(2) + v - 2; 
D(2) = x(1) - x(2) + v - 1.8; 
end 

さて、私はときv = sort(rand(1,1000))根を見つけるしたいと思います:

v = 1; 
fun = @root; 
x0 = [0,0] 
options = optimset('MaxFunEvals',100000,'MaxIter', 10000); 
x = fsolve(fun,x0, options) 

また、私は別のファイルに次の機能を持っている:私は、次の「母」のコードを持っています。言い換えれば、私はvの各値の関数を繰り返していきたいと思います。

+0

を...あなたは右、これらは線形方程式であることを知っていますか?あなたはそれらを解決するために 'fsolve'を必要としません。実際、むしろ遅く、おそらく不正確になるでしょう...' root'は実例ですか、あなたの本当の*関数は解決するのでしょうか? –

答えて

1

あなたは追加の変数(v)を受け入れ、その後、あなたが機能付き

function D = root(x, v) 
    D(1) = x(1) + x(2) + v - 2; 
    D(2) = x(1) - x(2) + v - 1.8; 
end 

% Creates a function handle to root using a specific value of v 
fun = @(x)root(x, v(k)) 
0
vvec = sort(rand(1,2)); 

x0 = [0,0]; 
for v = vvec, 
    fun = @(x) root(v, x); 
    options = optimset('MaxFunEvals',100000,'MaxIter', 10000); 
    x = fsolve(fun, x0, options); 
end 

をしたいvにフィード無名関数へのルートに関数ハンドルを変更するrootを変更する必要があります定義:

function D = root(v, x) 
D(1) = x(1) + x(2) + v - 2; 
D(2) = x(1) - x(2) + v - 1.8; 
end 
1

念のためにその方程式は、実際のあなたのある式(とではないダミーの例):その方程式は線形あり、意味、あなたは簡単なmldivideですべてvのためにそれを解決することができます:

v = sort(rand(1,1000)); 
x = [1 1; 1 -1] \ bsxfun(@plus, -v, [2; 1.8]) 

そして、ケースのものですない実際の方程式、あなたは全部をベクトル化することができ、ループする必要はありません。

function x = solver() 

    options = optimset('Display' , 'off',... 
         'MaxFunEvals', 1e5,... 
         'MaxIter' , 1e4); 

    v = sort(rand(1, 1000)); 
    x0 = repmat([0 0], numel(v), 1);  
    x = fsolve(@(x)root(x,v'), x0, options); 

end 

function D = root(x,v) 

    D = [x(:,1) + x(:,2) + v - 2 
     x(:,1) - x(:,2) + v - 1.8]; 

end 

これは、またはループよりも高速であってもなくてもよい、それはあなたの実際の式に依存します。

fsolveは2×2,1000回(4k要素)の代わりに2000×2000(4M要素)のヤコビアンを計算する必要があるため、処理が遅くなることがあります。

しかし、起動コストがfsolveと大きいため、多くのコールのオーバーヘッドが実際にはより大きなヤコビアンを計算するコストを上回る可能性があるため、速度が速くなる可能性があります。いずれの場合においても

、第二の出力は、むしろ非常にすべてをスピードアップとしてヤコビアンを提供する:

function solver() 

    options = optimset('Display' , 'off',... 
         'MaxFunEvals', 1e5,... 
         'MaxIter' , 1e4,...      
         'Jacobian' , 'on'); 

    v = sort(rand(1, 1000)); 
    x0 = repmat([1 1], numel(v), 1);  
    x = fsolve(@(x)root(x,v'), x0, options); 

end 

function [D, J] = root(x,v) 

    % Jacobian is constant: 
    persistent J_out 
    if isempty(J_out) 
     one = speye(numel(v));  
     J_out = [+one +one 
       +one -one]; 
    end 

    % Function values at x 
    D = [x(:,1) + x(:,2) + v - 2 
     x(:,1) - x(:,2) + v - 1.8]; 

    % Jacobian at x: 
    J = J_out; 

end 
関連する問題