0

MATLAB を使用して、別の関数内で作成した関数を区別しようとする小さなプログラムを作成しようとしていますが、エラーが発生し続けます。

私のファイルは次のとおりです。

newton.m:

function [ y, iter ] = newton( f, fp, x0 )

    iter = 0;
    xprev = x0;
    x = xprev - f(xprev)/fp(xprev);

    iter = iter + 1;

    while abs(x-xprev) > eps*abs(x)
        xprev = x;
        x = x - f(x)/fp(x);
        iter = iter + 1;
        y = x;
    end
end  

fm:

function y = f(x)
    y = tan(x) - 2*x;
end  

fp.m:

function y = fp(f)
    y = diff(f);
end

私は以下を実行しています:

[y, iter] = newton(@f, @fp, 1.4)  

そして取得:

使用エラー /
マトリックスの次元は一致する必要があります。

newton のエラー (6 行目) x = xprev - f(xprev)/fp(xprev);

yfp.m での値をチェックしていると、取得し続け[]ます。

4

1 に答える 1

1

diff関数を区別するために使用しようとしています。すぐdiffに使用できる要素のペア間の差分操作を実行します。あなたはこれを望んでいません。代わりに、fandfpを実際の関数ハンドルとして作成してください。最初に関数 のシンボリック定義を作成し、シンボリック バージョン(それ自体で呼び出すことができます)fを使用してこのシンボリック表現を微分し、これを使用して MATLAB 関数を作成します。diffdiffmatlabFunction

%// Define symbolic variable
syms x;

%// Define function symbolically
y = tan(x) - 2*x;

%// Define function handles (numerical) to the original and derivative
f = matlabFunction(y); 
fp = matlabFunction(diff(y));

%// Now call Newton's Method
[y, iter] = newton(f, fp, 1.4);  

ffpはすでに関数ハンドルであることに注意してください。それが返されるので、ニュートンのメソッド関数への入力としてmatlabFunctionハンドル via を作成する必要はもうありません。@

この変更をコードに実行すると、最初の推定値とx = 1.4それにかかった反復回数を使用して、ルートについて次のようになります。

>> format long g
>> y

y =

          1.16556118520721

>> iter

iter =

     8

Symbolic Mathematics Toolbox がない場合...

何らかの理由で、Symbolic Mathematics Toolbox がない場合、私が提案したことは機能しません。そのため、導関数の離散近似を使用してこれを機能させる以外に選択肢はありません。ただし、上で書いたコードを使用することはできますが、fp別の方法で定義する必要があります。

思い出すと、導関数の定義は次のようになります。

これを個別のケースで機能させるには、非常に小さくします...たとえば、 Δx次のようにします。1e-10

そのため、代わりに無名関数を使用してこれを行います。

%// Define function
f = @(x) tan(x) - 2*x;

%// Define derivative
h = 1e-10;
fp = @(x) (f(x + h) - f(x)) / h;

%// Now call Newton's Method
[y, iter] = newton(f, fp, 1.4); 

これで、私は得る:

>> format long g;
>> y

y =

          1.16556118520721

>> iter

iter =

     8

私はそれがかなり近いと思います!

于 2015-11-20T17:39:04.777 に答える