-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
  • 在大多数情况下,df 中的 1/x 可以为 0,因为在 python 2.x 中,整数除法返回整数
  • 基于范围的索引太少
于 2014-06-24T22:01:09.283 回答