브렌트의 방법을 시도하려는 경우 아래의 원래 알고리즘에 대한 번역을 시도해 볼 수 있습니다. 이것은 원래 C 코드를 MATLAB으로 번역 한 것입니다. 원래의 C 코드에 대한 모든 테스트 케이스가 번역에서 동일한 결과를 산출한다는 것을 확인했습니다.
아래 코드에서 This
은 함수 핸들이고 a
및 b
은 검색 범위입니다.
function x = brent(This,a,b)
tol = 1e-2 ;
maxit = 1e+3 ;
displayIter = true ;
Fa = This(a) ;
Fb = This(b) ;
c = a ;
Fc = Fa ;
it = 0 ;
if displayIter
fprintf(1,'Searching for a root in the interval [%g,%g] using Brent''s method...\n',a,b) ;
end
while it<maxit
it = it + 1 ;
prevStep = b - a ;
if abs(Fc) < abs(Fb)
% swap for b to be best approximation
a = b ;
b = c ;
c = a ;
Fa = Fb ;
Fb = Fc ;
Fc = Fa ;
end
tolAct = 2*eps*abs(b) + tol/2 ;
newStep = (c-b)/2 ;
if abs(newStep) <= tolAct || abs(Fb)<eps
% acceptable solution found
x = b ;
return
end
if abs(prevStep) >= tolAct && Fa == Fb
% previous step was large enough and in the right direction, try
% interpolation
cb = c-b ;
if abs(a-c)<eps
% if only two distinct points, interpolate linearly
t1 = Fb/Fa ;
p = cb*t1 ;
q = 1 - t1 ;
else
% three points, do quadratic inverse interpolation
a = Fa/Fc ;
t1 = Fb/Fc ;
t2 = Fb/Fa ;
p = t2*(cb*q*(q-t1) - (b-a)*(t1-1)) ;
q = (q-1)*(t1-1)*(t2-1) ;
end
if p>0
q = -q ;
else
p = -p ;
end
if p < (0.75*cb*q-abs(tolAct*q)/2) && p < abs(prevStep*q/2)
newStep = p/q ;
end
end
% step must be at least as large as tolerance
if abs(newStep)<tolAct
if newStep>0
newStep = tolAct ;
else
newStep = -tolAct ;
end
end
a = b ;
Fa = Fb ;
b = b + newStep ;
Fb = This(b) ;
if (Fb > 0 && Fc > 0) || (Fb < 0 && Fc < 0)
c = a ;
Fc = Fa ;
end
if displayIter
fprintf(1,'[%g] Gap = %g, dx = %g\n',it,abs(Fb),newStep) ;
end
end
fprintf(1,'[%g] Gap = %g, dx = %g\n',it,abs(Fb),newStep) ;
end
코드 주셔서 감사합니다 (3). 나는 브렌트의 방법을 테스트했는데, 'fzero' 외에 (1) 나는 [this] (https://people.sc.fsu.edu/~jburkardt/m_src/brent/zero.m)을 사용하고있다. (2) Matlab 구현 게다가. 'tolx = 1e-2'와 함께'fun = @ (x) exp (-exp (-x)) - x'와'x0 = [0, 1]'을 사용한 빠른 테스트는 다음과 같은 함수 평가 번호를 보여준다.) 5; (2) 4; (3) 7. 나는 더 효율적인 것을 찾고있다. :) – Arpi