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_DERIV_H
00024 #define O2SCL_DERIV_H
00025
00026 #include <iostream>
00027 #include <cmath>
00028 #include <o2scl/collection.h>
00029 #include <o2scl/funct.h>
00030
00031 #ifndef DOXYGENP
00032 namespace o2scl {
00033 #endif
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 template<class param_t, class func_t> class deriv {
00055
00056 #ifndef DOXYGEN_INTERNAL
00057
00058 protected:
00059
00060
00061 typedef struct {
00062 public:
00063
00064 func_t *func;
00065
00066 param_t *up;
00067 } dpars;
00068
00069
00070 bool from_calc;
00071
00072 #endif
00073
00074 public:
00075
00076 deriv() {
00077 verbose=0;
00078 from_calc=false;
00079 }
00080
00081 virtual ~deriv() {}
00082
00083
00084
00085
00086
00087
00088
00089 virtual double calc(double x, param_t &pa, func_t &func) {
00090 double dx;
00091 from_calc=true;
00092 calc_err(x,pa,func,dx,derr);
00093 from_calc=false;
00094 return dx;
00095 }
00096
00097
00098
00099 virtual double calc2(double x, param_t &pa, func_t &func) {
00100 double val;
00101 dpars dp={&func,&pa};
00102 funct_mfptr_noerr<deriv,dpars> mf(this,&deriv::derivfun);
00103 val=calc_int(x,dp,mf);
00104 return val;
00105 }
00106
00107
00108
00109 virtual double calc3(double x, param_t &pa, func_t &func) {
00110 double val;
00111 dpars dp={&func,&pa};
00112 funct_mfptr_noerr<deriv,dpars> mf(this,&deriv::derivfun2);
00113 val=calc_int(x,dp,mf);
00114 return val;
00115 }
00116
00117
00118
00119 virtual double get_err() {
00120 return derr;
00121 }
00122
00123
00124
00125 int verbose;
00126
00127
00128
00129
00130 virtual int calc_err(double x, param_t &pa, func_t &func, double &dfdx,
00131 double &err) {
00132 if (from_calc==true) {
00133 set_err_ret("No method specified in calc_err().",gsl_nobase);
00134 }
00135 dfdx=calc(x,pa,func);
00136 err=0.0;
00137 return 0;
00138 }
00139
00140
00141
00142
00143 virtual int calc2_err(double x, param_t &pa, func_t &func,
00144 double &d2fdx2, double &err) {
00145 int ret;
00146 dpars dp={&func,&pa};
00147 funct_mfptr_noerr<deriv,dpars> mf(this,&deriv::derivfun);
00148 ret=calc_err_int(x,dp,mf,d2fdx2,err);
00149 return 0;
00150 }
00151
00152
00153
00154
00155 virtual int calc3_err(double x, param_t &pa, func_t &func,
00156 double &d3fdx3, double &err) {
00157 int ret;
00158 dpars dp={&func,&pa};
00159 funct_mfptr_noerr<deriv,dpars> mf(this,&deriv::derivfun2);
00160 ret=calc_err_int(x,dp,mf,d3fdx3,err);
00161 return 0;
00162 }
00163
00164
00165 virtual const char *type() { return "deriv"; }
00166
00167 protected:
00168
00169 #ifndef DOXYGEN_INTERNAL
00170
00171
00172
00173
00174
00175
00176
00177 virtual double calc_int(double x, dpars &pa, o2scl::funct<dpars> &func) {
00178 double dx;
00179 from_calc=true;
00180 calc_err_int(x,pa,func,dx,derr);
00181 from_calc=false;
00182 return dx;
00183 }
00184
00185
00186
00187
00188
00189
00190
00191 virtual int calc_err_int(double x, dpars &pa, o2scl::funct<dpars> &func,
00192 double &dfdx, double &err) {
00193 if (from_calc==true) {
00194 set_err_ret("No method specified in calc_err_int().",gsl_nobase);
00195 }
00196 dfdx=calc_int(x,pa,func);
00197 err=0.0;
00198 return 0;
00199 }
00200
00201
00202 double derr;
00203
00204
00205 double derivfun(double x, dpars &dp) {
00206 return calc(x,*(dp.up),*(dp.func));
00207 }
00208
00209
00210 double derivfun2(double x, dpars &dp) {
00211 funct_mfptr_noerr<deriv,dpars> mf(this,&deriv::derivfun);
00212 double val=calc_int(x,dp,mf);
00213 return val;
00214 }
00215
00216 #endif
00217
00218 };
00219
00220 #ifndef DOXYGENP
00221 }
00222 #endif
00223
00224 #endif