00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef O2SCL_GSL_MMIN_CONP_H
00024 #define O2SCL_GSL_MMIN_CONP_H
00025
00026 #include <gsl/gsl_blas.h>
00027 #include <gsl/gsl_multimin.h>
00028 #include <o2scl/gsl_mmin_conf.h>
00029
00030 #ifndef DOXYGENP
00031 namespace o2scl {
00032 #endif
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 template<class param_t, class func_t=multi_funct<param_t> ,
00058 class vec_t=ovector_view, class alloc_vec_t=ovector,
00059 class alloc_t=ovector_alloc, class dfunc_t=grad_funct<param_t,vec_t> >
00060 class gsl_mmin_conp :
00061 public gsl_mmin_conf<param_t,func_t,vec_t,alloc_vec_t,alloc_t,dfunc_t> {
00062
00063 public:
00064
00065
00066 virtual int iterate() {
00067
00068 if (this->dim==0) {
00069 set_err_ret("Memory not allocated in iterate().",gsl_efailed);
00070 }
00071
00072 gsl_vector *x=this->ugx;
00073 gsl_vector *gradient=this->ugg;
00074 gsl_vector *dx=this->udx;
00075
00076 double fa = this->it_min, fb, fc;
00077 double dir;
00078 double stepa = 0.0, stepb, stepc=this->step;
00079
00080 double g1norm;
00081 double pg;
00082
00083 if (this->pnorm == 0.0 || this->g0norm == 0.0) {
00084 gsl_vector_set_zero(dx);
00085 this->it_info=1;
00086 return 0;
00087 }
00088
00089
00090
00091 gsl_blas_ddot (this->p, gradient, &pg);
00092
00093 dir = (pg >= 0.0) ? +1.0 : -1.0;
00094
00095
00096
00097
00098 take_step (x, this->p, stepc, dir / this->pnorm, this->x1, dx);
00099
00100
00101
00102 for(size_t i=0;i<this->dim;i++) {
00103 this->avt5[i]=gsl_vector_get(this->x1,i);
00104 }
00105 (*this->func)(this->dim,this->avt5,fc,*this->params);
00106
00107 if (fc < fa) {
00108
00109 this->step = stepc * 2.0;
00110 this->it_min = fc;
00111 gsl_vector_memcpy (x, this->x1);
00112
00113 for(size_t i=0;i<this->dim;i++) {
00114 this->avt6[i]=gsl_vector_get(this->x1,i);
00115 }
00116
00117
00118 this->it_info=0;
00119 return gsl_success;
00120 }
00121
00122
00123
00124
00125
00126 this->intermediate_point(x, this->p, dir / this->pnorm, pg,
00127 stepa, stepc, fa, fc, this->x1, this->dx1,
00128 gradient, &stepb, &fb);
00129
00130 if (stepb == 0.0) {
00131 this->it_info=2;
00132 return 0;
00133 }
00134
00135 minimize(x,this->p,dir / this->pnorm,stepa,stepb,stepc, fa,
00136 fb, fc, this->tol, this->x1, this->dx1, this->x2,
00137 dx, gradient, &(this->step), &(this->it_min), &g1norm);
00138
00139 gsl_vector_memcpy (x,this->x2);
00140
00141
00142
00143 this->iter = (this->iter + 1) % x->size;
00144
00145 if (this->iter == 0) {
00146 gsl_vector_memcpy (this->p, gradient);
00147 this->pnorm = g1norm;
00148 } else {
00149
00150 double g0g1, beta;
00151
00152
00153 gsl_blas_daxpy (-1.0, gradient, this->g0);
00154
00155 gsl_blas_ddot(this->g0, gradient, &g0g1);
00156
00157 beta = g0g1 / (this->g0norm*this->g0norm);
00158
00159 gsl_blas_dscal (-beta, this->p);
00160 gsl_blas_daxpy (1.0, gradient, this->p);
00161 this->pnorm = gsl_blas_dnrm2 (this->p);
00162 }
00163
00164 this->g0norm = g1norm;
00165 gsl_vector_memcpy (this->g0, gradient);
00166
00167 this->it_info=0;
00168 return gsl_success;
00169 }
00170
00171
00172 virtual const char *type() { return "gsl_mmin_conp";}
00173
00174 };
00175
00176 #ifndef DOXYGENP
00177 }
00178 #endif
00179
00180 #endif