aboutsummaryrefslogtreecommitdiffstats
path: root/methods/powell/powell_method.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'methods/powell/powell_method.hpp')
-rw-r--r--methods/powell/powell_method.hpp251
1 files changed, 251 insertions, 0 deletions
diff --git a/methods/powell/powell_method.hpp b/methods/powell/powell_method.hpp
new file mode 100644
index 0000000..bec12b7
--- /dev/null
+++ b/methods/powell/powell_method.hpp
@@ -0,0 +1,251 @@
+#ifndef POWELL_METHOD
+#define POWELL_METHOD
+#include <core/optimizer.hpp>
+//#include <blitz/array.h>
+#include <limits>
+#include <cassert>
+#include <cmath>
+#include "linmin.hpp"
+#include <algorithm>
+/*
+ *
+*/
+#include <iostream>
+
+namespace opt_utilities
+{
+ /*
+ template <typename T>
+ T tabs(T x)
+ {
+ return x<0?-x:x;
+ }
+ */
+
+ template <typename rT,typename pT>
+ class powell_method
+ :public opt_method<rT,pT>
+ {
+ public:
+ typedef pT array1d_type;
+ typedef rT T;
+ private:
+ func_obj<rT,pT>* p_fo;
+ optimizer<rT,pT>* p_optimizer;
+
+ //typedef blitz::Array<rT,2> array2d_type;
+
+
+ private:
+ array1d_type start_point;
+ array1d_type end_point;
+
+ private:
+ int ncom;
+ array1d_type pcom_p;
+ array1d_type xicom_p;
+ rT threshold;
+ T** xi;
+ T* xi_1d;
+ private:
+ rT func(const pT& x)
+ {
+ assert(p_fo!=0);
+ return p_fo->eval(x);
+ }
+
+
+ private:
+ void clear_xi()
+ {
+ if(xi_1d!=0)
+ {
+ delete[] xi_1d;
+ }
+ if(xi!=0)
+ {
+ delete[] xi;
+ }
+ }
+
+ void init_xi(int n)
+ {
+ clear_xi();
+ xi_1d=new T[n*n];
+ xi=new T*[n];
+ for(int i=0;i!=n;++i)
+ {
+ xi[i]=xi_1d+i*n;
+ }
+ for(int i=0;i!=n;++i)
+ {
+ for(int j=0;j!=n;++j)
+ {
+ xi[i][j]=(j==i?1:0);
+ }
+ }
+ }
+
+
+
+ void powell(array1d_type& p,const T ftol,
+ int& iter,T& fret)
+ {
+ const int ITMAX=200;
+ const T TINY=std::numeric_limits<T>::epsilon();
+ int i,j,ibig;
+ T del,fp,fptt,t;
+ int n=(int)get_size(p);
+ array1d_type pt(n);
+ array1d_type ptt(n);
+ array1d_type xit(n);
+ fret=p_fo->eval(p);
+
+ for(j=0;j<n;++j)
+ {
+ //get_element(pt,j)=get_element(p,j);
+ set_element(pt,j,get_element(p,j));
+ }
+ for(iter=0;;++iter)
+ {
+ fp=fret;
+ ibig=0;
+ del=0.0;
+ for(i=0;i<n;++i)
+ {
+ for(j=0;j<n;++j)
+ {
+ //get_element(xit,j)=xi[j][i];
+ set_element(xit,j,xi[j][i]);
+ }
+ fptt=fret;
+ linmin(p,xit,fret,(*p_fo));
+ if((fptt-fret)>del)
+ {
+ del=fptt-fret;
+ ibig=i+1;
+ }
+ }
+ if(T(2.)*(fp-fret)<=ftol*(tabs(fp)+tabs(fret))+TINY)
+ {
+ return;
+ }
+ if(iter==ITMAX)
+ {
+ std::cerr<<"powell exceeding maximun iterations."<<std::endl;
+ return;
+ }
+ for(j=0;j<n;++j)
+ {
+ //get_element(ptt,j)=T(2.)*get_element(p,j)-get_element(pt,j);
+ set_element(ptt,j,T(2.)*get_element(p,j)-get_element(pt,j));
+ //get_element(xit,j)=
+ //get_element(p,j)-get_element(pt,j);
+ set_element(xit,j,get_element(p,j)-get_element(pt,j));
+ //get_element(pt,j)=get_element(p,j);
+ set_element(pt,j,get_element(p,j));
+ }
+ fptt=func(ptt);
+ if(fptt<fp)
+ {
+ t=T(2.)*(fp-T(2.)*fret+fptt)*sqr(T(fp-fret-del))-del*sqr(T(fp-fptt));
+ if(t<T(0.))
+ {
+ linmin(p,xit,fret,*p_fo);
+ for(j=0;j<n;++j)
+ {
+ xi[j][ibig-1]=xi[j][n-1];
+ xi[j][n-1]=get_element(xit,j);
+
+ }
+ }
+ }
+ }
+ }
+
+
+ public:
+
+ powell_method()
+ :threshold(1e-4),xi(0),xi_1d(0)
+ {}
+
+ virtual ~powell_method()
+ {
+ clear_xi();
+ };
+
+ powell_method(const powell_method<rT,pT>& rhs)
+ :p_fo(rhs.p_fo),p_optimizer(rhs.p_optimizer),
+ start_point(rhs.start_point),
+ end_point(rhs.end_point),
+ ncom(rhs.ncom),
+ threshold(rhs.threshold),xi(0),xi_1d(0)
+ {
+ }
+
+ powell_method<rT,pT>& operator=(const powell_method<rT,pT>& rhs)
+ {
+ threshold=rhs.threshold;
+ xi=0;
+ xi_1d=0;
+ p_fo=rhs.p_fo;
+ p_optimizer=rhs.p_optimizer;
+ start_point=rhs.start_point;
+ end_point=rhs.end_point;
+ ncom=rhs.ncom;
+ threshold=rhs.threshold;
+ }
+
+ opt_method<rT,pT>* do_clone()const
+ {
+ return new powell_method<rT,pT>(*this);
+ }
+
+ void do_set_start_point(const array1d_type& p)
+ {
+ resize(start_point,get_size(p));
+ opt_eq(start_point,p);
+
+ }
+
+ void do_set_precision(rT t)
+ {
+ threshold=t;
+ }
+
+ void do_set_optimizer(optimizer<rT,pT>& o)
+ {
+ p_optimizer=&o;
+ p_fo=p_optimizer->ptr_func_obj();
+ }
+
+
+
+ pT do_optimize()
+ {
+
+ init_xi((int)get_size(start_point));
+
+
+ for(int i=0;i<(int)get_size(start_point);++i)
+ {
+ for(int j=0;j<(int)get_size(start_point);++j)
+ {
+ xi[i][j]=(i==j)?1:0;
+ }
+ }
+
+ int iter=100;
+ opt_eq(end_point,start_point);
+ rT fret;
+ powell(end_point,threshold,iter,fret);
+ return end_point;
+ }
+ };
+
+};
+
+
+#endif
+//EOF