summary refs log tree commit diff stats
path: root/lib/pure/numeric.nim
diff options
context:
space:
mode:
Diffstat (limited to 'lib/pure/numeric.nim')
-rw-r--r--lib/pure/numeric.nim29
1 files changed, 12 insertions, 17 deletions
diff --git a/lib/pure/numeric.nim b/lib/pure/numeric.nim
index 593370fbb..8ef5fabda 100644
--- a/lib/pure/numeric.nim
+++ b/lib/pure/numeric.nim
@@ -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)