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_ROOT_STEF_H
00024 #define O2SCL_GSL_ROOT_STEF_H
00025
00026 #include <gsl/gsl_math.h>
00027 #include <gsl/gsl_roots.h>
00028 #include <o2scl/root.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, class dfunc_t> class gsl_root_stef :
00058 public o2scl::root<param_t,func_t,dfunc_t> {
00059
00060 protected:
00061
00062
00063 double f;
00064
00065
00066 double df;
00067
00068
00069 double x_1;
00070
00071
00072 double x;
00073
00074
00075 int count;
00076
00077
00078 func_t *fp;
00079
00080
00081 dfunc_t *dfp;
00082
00083
00084 param_t *params;
00085
00086 public:
00087
00088 gsl_root_stef() {
00089 this->over_de=true;
00090 test_residual=false;
00091 tolf2=1.0e-12;
00092 }
00093
00094
00095 virtual const char *type() { return "gsl_root_stef"; }
00096
00097
00098 double root;
00099
00100
00101
00102
00103 double tolf2;
00104
00105
00106
00107
00108
00109
00110
00111 int iterate() {
00112
00113 double x_new, f_new, df_new;
00114
00115 double x_1t = x_1;
00116 double xt = x;
00117
00118 if (df == 0.0) {
00119 set_err_ret("Derivative is zero in gsl_root_stef::iterate().",
00120 o2scl::gsl_ezerodiv);
00121 }
00122
00123 x_new = xt - (f / df);
00124
00125
00126
00127
00128 (*dfp)(x_new,df_new,*params);
00129 (*fp)(x_new,f_new,*params);
00130
00131 x_1 = xt;
00132 x = x_new;
00133
00134 f = f_new;
00135 df = df_new;
00136
00137 if (!finite (f_new)) {
00138 set_err_ret
00139 ("Function not continuous in gsl_root_stef::iterate().",
00140 o2scl::gsl_ebadfunc);
00141 }
00142
00143 if (count < 3) {
00144 root = x_new;
00145 count++;
00146 } else {
00147 double u = (xt - x_1t);
00148 double v = (x_new - 2 * xt + x_1t);
00149
00150 if (v == 0) {
00151 root = x_new;
00152 } else {
00153 root = x_1t - u * u / v;
00154 }
00155 }
00156
00157 if (!finite(df_new)) {
00158 set_err_ret
00159 ("Function not differentiable in gsl_root_stef::iterate().",
00160 o2scl::gsl_ebadfunc);
00161 }
00162
00163 return o2scl::gsl_success;
00164 }
00165
00166
00167
00168
00169 virtual int solve_de(double &xx, param_t &pa, func_t &fun, dfunc_t &dfun) {
00170
00171 int status1, status2=gsl_continue, iter=0;
00172
00173 status1=set(fun,dfun,xx,pa);
00174
00175 while (status1==gsl_success && status2==gsl_continue &&
00176 iter<this->ntrial) {
00177 iter++;
00178
00179 status1=iterate();
00180
00181
00182 status2=gsl_root_test_delta(root,xx,this->tolx,tolf2);
00183
00184 if (test_residual && status2==gsl_success) {
00185 double y;
00186 fun(root,y,pa);
00187 if (fabs(y)>=this->tolf) status2=gsl_continue;
00188 }
00189
00190 if (this->verbose>0) {
00191 double fval;
00192 fun(root,fval,pa);
00193 print_iter(root,fval,iter,fabs(root-xx),this->tolx*root,
00194 "gsl_root_stef");
00195 }
00196 xx=root;
00197 }
00198
00199 this->last_ntrial=iter;
00200
00201 if (status1!=gsl_success || status2!=gsl_success) {
00202 int ret=o2scl::err_hnd->get_errno();
00203 return ret;
00204 }
00205 if (iter>=this->ntrial) {
00206 set_err_ret("solve_de() exceeded maximum number of iterations.",
00207 gsl_emaxiter);
00208 }
00209
00210 return o2scl::gsl_success;
00211 }
00212
00213
00214 bool test_residual;
00215
00216
00217
00218
00219
00220
00221
00222 int set(func_t &fun, dfunc_t &dfun, double guess, param_t &pa) {
00223
00224 fp=&fun;
00225 dfp=&dfun;
00226 params=&pa;
00227 root=guess;
00228
00229 dfun(root,df,pa);
00230 fun(root,f,pa);
00231
00232 x=root;
00233 x_1=0.0;
00234 count=1;
00235
00236 return o2scl::gsl_success;
00237
00238 }
00239
00240 };
00241
00242 #ifndef DOXYGENP
00243 template<> int io_tlate<gsl_root_stef<void *,funct<void *>,
00244 funct<void *> > >::input(cinput *co, in_file_format *ins,
00245 gsl_root_stef<void *, funct<void *>,
00246 funct<void *> > *ro);
00247 template<> int io_tlate<gsl_root_stef<void *,funct<void *>,
00248 funct<void *> > >::output(coutput *co, out_file_format *outs,
00249 gsl_root_stef<void *, funct<void *>,
00250 funct<void *> > *ro);
00251 template<> const char *io_tlate<gsl_root_stef<void *,
00252 funct<void *>, funct<void *> > >::type();
00253 #endif
00254
00255 typedef io_tlate<gsl_root_stef<void *,funct<void *>, funct<void *> > >
00256 gsl_root_stef_io_type;
00257
00258 #ifndef DOXYGENP
00259 }
00260 #endif
00261
00262 #endif
00263