-1

Matlab で Python に記述したバック ステップ コードを使用してニュートン法をコーディングしようとしていますが、Python 構文に問題があります。Matlab では約 5 回の反復が必要ですが、私の Python コードは最大反復回数 1000 までループし、バック ステップ メカニズムが機能しない (負の対数を計算しようとする) ため、ドメイン エラーが発生します。私はしばらく Python を使用していないので、何らかの構文を混乱させている可能性が高いです。

正しく動作する Matlab コードは次のとおりです。

x = 10;                                               %defines x
f = @(x) log(x);                                        %defines objective function
df = @(x) 1/x;                                          %defines first derivative
tol = .00001;                                           %defines our tolerance level
maxit = 1000;                                           %defines maximum iteration steps
maxsteps = 200;                                         %defines maximum backsteps
for i=1:maxit                                           %starts loop
    fval = f(x);                                        %value of function at f(x)
    fjac = df(x);                                       %value of jacobian at f(x)
    fnorm = norm(fval);                                 %calculates norm value at fval
    if fnorm<tol, return, end                           %if fnorm less than tol, end
    x
    d = -(fjac\fval);                                   %forms second part of iteration rule
    d
    fnormold = inf;                                     %sets arbitrary fnormold
    for backstep=1:maxsteps
        fvalnew = f(x+d);                               %calculates f(x+d)
        fnormnew = norm(fvalnew);                       %calculates norm of fvalnew
        if fnormnew<fnorm, break, end                   %implements 1st backstepping rule
        if fnormold<fnormnew, d=2*d; break, end         %implements 2nd backstepping rule
        fnormold = fnormnew;                            %updates fnormold
        d=d/2;
    end
    x=x+d;
end
disp(x)

Python コードは次のとおりです。

from math import log

x = 10

def f(x):
    f = x* log(x)
    return f

def df(x):
    df = 1/x
    return df

tol = .00001
maxit = 1000
maxsteps = 200
maxsteps = 200

for i in range(1, maxit):
    fval = f(x)
    fjac = df(x)
    fnorm = abs(fval)
    if fnorm < tol:
        print x
    d = -(fjac/fval)
    fnormold = float('Inf')
    for backstep in range(1, maxsteps):
        fvalnew = f(x+d)
        fnormnew = abs(fvalnew)
        if fnormnew < fnorm:
            break
        if fnormold < fnormnew:
            d= 2*d
            break
        fnormold = fnormnew
        d = d/2
    x = x+d
print x
4

1 に答える 1

0
  • Python 2.x では整数に対する除算が整数を返すため、df の 1/x はほとんどの場合 0 になる可能性があります。
  • 範囲ベースのインデックスが 1 つ少なすぎます
于 2014-06-24T22:01:09.283 に答える