我正在尝试使用我在 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