aboutsummaryrefslogtreecommitdiffstats
path: root/methods/linmin/brent.hpp
diff options
context:
space:
mode:
authorastrojhgu <astrojhgu@ed2142bd-67ad-457f-ba7c-d818d4011675>2010-06-03 17:55:42 +0000
committerastrojhgu <astrojhgu@ed2142bd-67ad-457f-ba7c-d818d4011675>2010-06-03 17:55:42 +0000
commit109473cacf85c7e2a2831d56531399ab4621654e (patch)
treeb26e7137d482a5711edf893af88c4487bc875783 /methods/linmin/brent.hpp
parent492fc9d5677bad71986ff437c62f17a28d7b5996 (diff)
downloadopt-utilities-109473cacf85c7e2a2831d56531399ab4621654e.tar.bz2
git-svn-id: file:///home/svn/opt_utilities@118 ed2142bd-67ad-457f-ba7c-d818d4011675
Diffstat (limited to 'methods/linmin/brent.hpp')
-rw-r--r--methods/linmin/brent.hpp111
1 files changed, 111 insertions, 0 deletions
diff --git a/methods/linmin/brent.hpp b/methods/linmin/brent.hpp
new file mode 100644
index 0000000..1a0ee39
--- /dev/null
+++ b/methods/linmin/brent.hpp
@@ -0,0 +1,111 @@
+#ifndef BRENT_HPP
+#define BRENT_HPP
+#define OPT_HEADER
+#include <iostream>
+#include "bas_util.hpp"
+//#include "optimizer.hpp"
+namespace opt_utilities
+{
+ template<typename T>
+ T brent(T ax,T bx,T cx,func_obj<T,T>& f,T tol,T& xmin)
+ {
+ const int ITMAX=100;
+ const T CGOLD=0.3819660;
+ const T ZEPS=std::numeric_limits<T>::epsilon()*1.e-3;
+
+ int iter;
+ T a=0,b=0,d(0),etemp=0,fu=0,fv=0,fw=0,fx=0,p=0,q=0
+ ,r=0,tol1=0,tol2=0,u=0,v=0,w=0,x=0,xm=0;
+ T e=0.;
+ a=(ax<cx?ax:cx);
+ b=(ax>cx?ax:cx);
+ x=w=v=bx;
+ fw=fv=fx=f.eval(x);
+ for(iter=0;iter<ITMAX;++iter)
+ {
+ xm=.5*(a+b);
+ tol2=2.*(tol1=tol*tabs(x)+ZEPS);
+ if(tabs(T(x-xm))<=(tol2-.5*(b-a)))
+ {
+ xmin=x;
+ return fx;
+ }
+ if(tabs(e)>tol1)
+ {
+ r=(x-w)*(fx-fv);
+ q=(x-v)*(fx-fw);
+ p=(x-v)*q-(x-w)*r;
+ q=2.*(q-r);
+ if(q>0.)
+ {
+ p=-p;
+ }
+ q=tabs(q);
+ etemp=e;
+ e=d;
+ if(tabs(p)>=tabs(T(T(.5)*p*etemp))||p<=q*(a-x)||p>=q*(b-x))
+ {
+ d=CGOLD*(e=(x>=xm?a-x:b-x));
+ }
+ else
+ {
+ d=p/q;
+ u=x+d;
+ if(u-a<tol2||b-u<tol2)
+ {
+ d=sign(tol1,T(xm-x));
+ }
+ }
+
+ }
+ else
+ {
+ d=CGOLD*(e=(x>=xm?a-x:b-x));
+ }
+ u=(tabs(d)>=tol1?x+d:x+sign(tol1,d));
+ fu=f.eval(u);
+ if(fu<=fx)
+ {
+ if(u>=x)
+ {
+ a=x;
+ }
+ else
+ {
+ b=x;
+ }
+ shft3(v,w,x,u);
+ shft3(fv,fw,fx,fu);
+ }
+ else
+ {
+ if(u<x)
+ {
+ a=u;
+ }
+ else
+ {
+ b=u;
+ }
+ if(fu<=fw||w==x)
+ {
+ v=w;
+ w=u;
+ fv=fw;
+ fw=fu;
+ }
+ else if(fu<=fv||v==x||v==w)
+ {
+ v=u;
+ fv=fu;
+ }
+ }
+ }
+ std::cerr<<"Too many iterations in brent"<<std::endl;
+ xmin=x;
+ return fx;
+
+ }
+}
+
+#endif