Fixed a mixed bag of stuff poly and numeric
This commit is contained in:
parent
d1a90c6ec6
commit
2cae55ae04
2 changed files with 42 additions and 51 deletions
|
|
@ -10,15 +10,16 @@
|
|||
|
||||
type TOneVarFunction* =proc (x:float):float
|
||||
|
||||
proc brent*(xmin,xmax:float ,function:TOneVarFunction, rootx,rooty:var float,tol:float,maxiter=1000):bool=
|
||||
proc brent*(xmin,xmax:float ,function:TOneVarFunction, tol:float,maxiter=1000):
|
||||
tuple[rootx, rooty: float, success: bool]=
|
||||
## Searches `function` for a root between `xmin` and `xmax`
|
||||
## using brents method. If the function value at `xmin`and `xmax` has the
|
||||
## same sign, `rootx`/`rooty` is set too the extrema value closest to x-axis
|
||||
## and false is returned.
|
||||
## Otherwise there exists at least one root and true is always returned.
|
||||
## and succes is set to false.
|
||||
## Otherwise there exists at least one root and success is set to true.
|
||||
## This root is searched for at most `maxiter` iterations.
|
||||
## If `tol` tolerance is reached within `maxiter` iterations
|
||||
## the root refinement stops and true is returned.
|
||||
## the root refinement stops and success=true.
|
||||
|
||||
# see http://en.wikipedia.org/wiki/Brent%27s_method
|
||||
var
|
||||
|
|
@ -37,13 +38,9 @@ proc brent*(xmin,xmax:float ,function:TOneVarFunction, rootx,rooty:var float,tol
|
|||
|
||||
if fa*fb>=0:
|
||||
if abs(fa)<abs(fb):
|
||||
rootx=a
|
||||
rooty=fa
|
||||
return false
|
||||
return (a,fa,false)
|
||||
else:
|
||||
rootx=b
|
||||
rooty=fb
|
||||
return false
|
||||
return (b,fb,false)
|
||||
|
||||
if abs(fa)<abs(fb):
|
||||
swap(fa,fb)
|
||||
|
|
@ -55,13 +52,13 @@ proc brent*(xmin,xmax:float ,function:TOneVarFunction, rootx,rooty:var float,tol
|
|||
else: #secant rule
|
||||
s = b - fb * (b - a) / (fb - fa)
|
||||
tmp2 = (3.0 * a + b) / 4.0
|
||||
if (not(((s > tmp2) and (s < b)) or ((s < tmp2) and (s > b)))) or
|
||||
(mflag and (abs(s - b) >= (abs(b - c) / 2.0))) or
|
||||
(not mflag and (abs(s - b) >= (abs(c - d) / 2.0))):
|
||||
if not((s > tmp2 and s < b) or (s < tmp2 and s > b)) or
|
||||
(mflag and abs(s - b) >= (abs(b - c) / 2.0)) or
|
||||
(not mflag and abs(s - b) >= abs(c - d) / 2.0):
|
||||
s=(a+b)/2.0
|
||||
mflag=true
|
||||
else:
|
||||
if ((mflag and (abs(b - c) < tol)) or (not mflag and (abs(c - d) < tol))):
|
||||
if (mflag and (abs(b - c) < tol)) or (not mflag and (abs(c - d) < tol)):
|
||||
s=(a+b)/2.0
|
||||
mflag=true
|
||||
else:
|
||||
|
|
@ -83,6 +80,4 @@ proc brent*(xmin,xmax:float ,function:TOneVarFunction, rootx,rooty:var float,tol
|
|||
if i>maxiter:
|
||||
break
|
||||
|
||||
rootx=b
|
||||
rooty=fb
|
||||
return true
|
||||
return (b,fb,true)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue