00001 /* 00002 ------------------------------------------------------------------- 00003 00004 Copyright (C) 2006, 2007, 2008, 2009, Andrew W. Steiner 00005 00006 This file is part of O2scl. 00007 00008 O2scl is free software; you can redistribute it and/or modify 00009 it under the terms of the GNU General Public License as published by 00010 the Free Software Foundation; either version 3 of the License, or 00011 (at your option) any later version. 00012 00013 O2scl is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 GNU General Public License for more details. 00017 00018 You should have received a copy of the GNU General Public License 00019 along with O2scl. If not, see <http://www.gnu.org/licenses/>. 00020 00021 ------------------------------------------------------------------- 00022 */ 00023 #ifndef O2SCL_FUNCT_H 00024 #define O2SCL_FUNCT_H 00025 00026 #include <string> 00027 #include <o2scl/collection.h> 00028 00029 #ifndef DOXYGENP 00030 namespace o2scl { 00031 #endif 00032 00033 /** 00034 \brief One-dimensional function [abstract base] 00035 00036 This class generalizes a function y(x). 00037 00038 This class is one of a large number of function object classes 00039 in \o2 designed to provide a mechanism for the user to 00040 supply functions to solvers, minimizers, integrators, etc. 00041 See \ref funct_section for a general description. 00042 00043 */ 00044 template<class param_t> class funct { 00045 00046 public: 00047 00048 /* 00049 This empty constructor is required for the child funct classes 00050 */ 00051 funct() {} 00052 00053 virtual ~funct() {} 00054 00055 /** \brief Compute the function at point \c x, with result \c y 00056 */ 00057 virtual int operator()(double x, double &y, param_t &pa)=0; 00058 00059 /** \brief Compute the function at point \c x, returning the result 00060 */ 00061 virtual double operator()(double x, param_t &pa) { 00062 double y; 00063 operator()(x,y,pa); 00064 return y; 00065 } 00066 00067 #ifndef DOXYGENP 00068 00069 private: 00070 00071 funct(const funct &); 00072 00073 funct& operator=(const funct&); 00074 00075 #endif 00076 00077 }; 00078 00079 /** \brief Function pointer to a function 00080 */ 00081 template<class param_t> class funct_fptr : public funct<param_t> { 00082 00083 public: 00084 00085 /** \brief Specify the function pointer 00086 */ 00087 funct_fptr(int (*fp)(double x, double &y, param_t &pa)) { 00088 fptr=fp; 00089 } 00090 00091 virtual ~funct_fptr() {} 00092 00093 /** \brief Compute the function at point \c x, with result \c y 00094 */ 00095 virtual int operator()(double x, double &y, param_t &pa) { 00096 return fptr(x,y,pa); 00097 } 00098 00099 /** \brief Compute the function at point \c x, returning the result 00100 00101 \comment 00102 This is here because if we overload operator()(double,double,void*), 00103 we have to reimplement all operator()'s 00104 \endcomment 00105 */ 00106 virtual double operator()(double x, param_t &pa) { 00107 double y; 00108 operator()(x,y,pa); 00109 return y; 00110 } 00111 00112 #ifndef DOXYGEN_INTERNAL 00113 00114 protected: 00115 00116 friend class io_tlate<funct_fptr>; 00117 00118 /// Storage for the function pointer 00119 int (*fptr)(double x, double &y, param_t &pa); 00120 00121 #endif 00122 #ifndef DOXYGENP 00123 00124 private: 00125 00126 funct_fptr(const funct_fptr &); 00127 funct_fptr& operator=(const funct_fptr&); 00128 00129 #endif 00130 00131 }; 00132 00133 /** \brief Function pointer to a function returning the function value 00134 */ 00135 template<class param_t> 00136 class funct_fptr_noerr : public funct<param_t> { 00137 public: 00138 00139 /** \brief Specify the function pointer 00140 */ 00141 funct_fptr_noerr(double (*fp)(double x, param_t &pa)) { 00142 fptr=fp; 00143 } 00144 00145 virtual ~funct_fptr_noerr() {} 00146 00147 /** \brief Compute the function at point \c x, with result \c y 00148 */ 00149 virtual int operator()(double x, double &y, param_t &pa) { 00150 y=fptr(x,pa); 00151 return 0; 00152 } 00153 00154 /** \brief Compute the function at point \c x, returning the result 00155 00156 \comment 00157 This is here because if we overload operator()(double,double,void*), 00158 we have to reimplement all operator()'s 00159 \endcomment 00160 */ 00161 virtual double operator()(double x, param_t &pa) { 00162 double y; 00163 operator()(x,y,pa); 00164 return y; 00165 } 00166 00167 #ifndef DOXYGEN_INTERNAL 00168 00169 protected: 00170 00171 /// Storage for the function pointer 00172 double (*fptr)(double x, param_t &pa); 00173 00174 #endif 00175 #ifndef DOXYGENP 00176 00177 private: 00178 00179 funct_fptr_noerr(const funct_fptr_noerr &); 00180 funct_fptr_noerr& operator=(const funct_fptr_noerr&); 00181 00182 #endif 00183 00184 }; 00185 00186 /** \brief Function pointer to a function with no parameters 00187 */ 00188 template<class param_t> 00189 class funct_fptr_nopar : public funct<param_t> { 00190 00191 public: 00192 00193 /** \brief Specify the function pointer 00194 */ 00195 funct_fptr_nopar(double (*fp)(double x)) { 00196 fptr=fp; 00197 } 00198 00199 virtual ~funct_fptr_nopar() {} 00200 00201 /** \brief Compute the function at point \c x, with result \c y 00202 */ 00203 virtual int operator()(double x, double &y, param_t &pa) { 00204 y=fptr(x); 00205 return 0; 00206 } 00207 00208 /** \brief Compute the function at point \c x, returning the result 00209 00210 \comment 00211 This is here because if we overload operator()(double,double,void*), 00212 we have to reimplement all operator()'s 00213 \endcomment 00214 */ 00215 virtual double operator()(double x, param_t &pa) { 00216 double y; 00217 operator()(x,y,pa); 00218 return y; 00219 } 00220 00221 #ifndef DOXYGEN_INTERNAL 00222 00223 protected: 00224 00225 /// Storage for the function pointer 00226 double (*fptr)(double x); 00227 00228 #endif 00229 #ifndef DOXYGENP 00230 00231 private: 00232 00233 funct_fptr_nopar(const funct_fptr_nopar &); 00234 funct_fptr_nopar& operator=(const funct_fptr_nopar&); 00235 00236 #endif 00237 00238 }; 00239 00240 /** 00241 \brief Member function pointer to a one-dimensional function 00242 */ 00243 template <class tclass, class param_t> class funct_mfptr : 00244 public funct<param_t> { 00245 public: 00246 00247 /** \brief Specify the member function pointer 00248 */ 00249 funct_mfptr(tclass *tp, int (tclass::*fp)(double x, double &y, 00250 param_t &pa)) { 00251 tptr=tp; 00252 fptr=fp; 00253 } 00254 00255 virtual ~funct_mfptr() {}; 00256 00257 /** \brief Compute the function at point \c x, with result \c y 00258 */ 00259 virtual int operator()(double x, double &y, param_t &pa) { 00260 return (*tptr.*fptr)(x,y,pa); 00261 } 00262 00263 /** \brief Compute the function at point \c x, returning the result 00264 00265 \comment 00266 This is here because if we overload operator()(double,double,void*), 00267 we have to reimplement all operator()'s 00268 \endcomment 00269 */ 00270 virtual double operator()(double x, param_t &pa) { 00271 double y; 00272 operator()(x,y,pa); 00273 return y; 00274 } 00275 00276 #ifndef DOXYGEN_INTERNAL 00277 00278 protected: 00279 00280 /// Storage for the member function pointer 00281 int (tclass::*fptr)(double x, double &y, param_t &pa); 00282 00283 /// Store the pointer to the class instance 00284 tclass *tptr; 00285 00286 #endif 00287 #ifndef DOXYGENP 00288 00289 private: 00290 00291 funct_mfptr(const funct_mfptr &); 00292 funct_mfptr& operator=(const funct_mfptr&); 00293 00294 #endif 00295 00296 }; 00297 00298 /** 00299 \brief Const member function pointer to a one-dimensional function 00300 00301 \note While this is designed to accept a pointer to a const 00302 member function, the choice of whether the class pointer 00303 given in the template type <tt>tclass</tt> is const or 00304 not is up to the user. 00305 */ 00306 template <class tclass, class param_t> class funct_cmfptr : 00307 public funct<param_t> { 00308 public: 00309 00310 /** \brief Specify the member function pointer 00311 */ 00312 funct_cmfptr(tclass *tp, int (tclass::*fp)(double x, double &y, 00313 param_t &pa) const) { 00314 tptr=tp; 00315 fptr=fp; 00316 } 00317 00318 virtual ~funct_cmfptr() {}; 00319 00320 /** \brief Compute the function at point \c x, with result \c y 00321 */ 00322 virtual int operator()(double x, double &y, param_t &pa) { 00323 return (*tptr.*fptr)(x,y,pa); 00324 } 00325 00326 /** \brief Compute the function at point \c x, returning the result 00327 00328 \comment 00329 This is here because if we overload operator()(double,double,void*), 00330 we have to reimplement all operator()'s 00331 \endcomment 00332 */ 00333 virtual double operator()(double x, param_t &pa) { 00334 double y; 00335 operator()(x,y,pa); 00336 return y; 00337 } 00338 00339 #ifndef DOXYGEN_INTERNAL 00340 00341 protected: 00342 00343 /// Storage for the const member function pointer 00344 int (tclass::*fptr)(double x, double &y, param_t &pa) const; 00345 00346 /// Store the pointer to the class instance 00347 tclass *tptr; 00348 00349 #endif 00350 #ifndef DOXYGENP 00351 00352 private: 00353 00354 funct_cmfptr(const funct_cmfptr &); 00355 funct_cmfptr& operator=(const funct_cmfptr&); 00356 00357 #endif 00358 00359 }; 00360 00361 /** \brief Member function pointer to a one-dimensional function 00362 returning the function value 00363 */ 00364 template <class tclass, class param_t> class funct_mfptr_noerr : 00365 public funct<param_t> { 00366 public: 00367 00368 /** \brief Specify the member function pointer 00369 */ 00370 funct_mfptr_noerr(tclass *tp, 00371 double (tclass::*fp)(double x, param_t &pa)) { 00372 tptr=tp; 00373 fptr=fp; 00374 } 00375 00376 virtual ~funct_mfptr_noerr() {}; 00377 00378 /** \brief Compute the function at point \c x, with result \c y 00379 */ 00380 virtual int operator()(double x, double &y, param_t &pa) { 00381 y=(*tptr.*fptr)(x,pa); 00382 return 0; 00383 } 00384 00385 /** \brief Compute the function at point \c x, returning the result 00386 00387 \comment 00388 This is here because if we overload operator()(double,double,void*), 00389 we have to reimplement all operator()'s 00390 \endcomment 00391 */ 00392 virtual double operator()(double x, param_t &pa) { 00393 double y; 00394 operator()(x,y,pa); 00395 return y; 00396 } 00397 00398 #ifndef DOXYGEN_INTERNAL 00399 00400 protected: 00401 00402 /// Storage for the member function pointer 00403 double (tclass::*fptr)(double x, param_t &pa); 00404 00405 /// Store the pointer to the class instance 00406 tclass *tptr; 00407 00408 #endif 00409 #ifndef DOXYGENP 00410 00411 private: 00412 00413 funct_mfptr_noerr(const funct_mfptr_noerr &); 00414 funct_mfptr_noerr& operator=(const funct_mfptr_noerr&); 00415 00416 #endif 00417 00418 }; 00419 00420 /** \brief Const member function pointer to a one-dimensional function 00421 returning the function value 00422 00423 \note While this is designed to accept a pointer to a const 00424 member function, the choice of whether the class pointer 00425 given in the template type <tt>tclass</tt> is const or 00426 not is up to the user. 00427 */ 00428 template <class tclass, class param_t> class funct_cmfptr_noerr : 00429 public funct<param_t> { 00430 public: 00431 00432 /** \brief Specify the member function pointer 00433 */ 00434 funct_cmfptr_noerr(tclass *tp, 00435 double (tclass::*fp)(double x, param_t &pa) const) { 00436 tptr=tp; 00437 fptr=fp; 00438 } 00439 00440 virtual ~funct_cmfptr_noerr() {}; 00441 00442 /** \brief Compute the function at point \c x, with result \c y 00443 */ 00444 virtual int operator()(double x, double &y, param_t &pa) { 00445 y=(*tptr.*fptr)(x,pa); 00446 return 0; 00447 } 00448 00449 /** \brief Compute the function at point \c x, returning the result 00450 00451 \comment 00452 This is here because if we overload operator()(double,double,void*), 00453 we have to reimplement all operator()'s 00454 \endcomment 00455 */ 00456 virtual double operator()(double x, param_t &pa) { 00457 double y; 00458 operator()(x,y,pa); 00459 return y; 00460 } 00461 00462 #ifndef DOXYGEN_INTERNAL 00463 00464 protected: 00465 00466 /// Storage for the const member function pointer 00467 double (tclass::*fptr)(double x, param_t &pa) const; 00468 00469 /// Store the pointer to the class instance 00470 tclass *tptr; 00471 00472 #endif 00473 #ifndef DOXYGENP 00474 00475 private: 00476 00477 funct_cmfptr_noerr(const funct_cmfptr_noerr &); 00478 funct_cmfptr_noerr& operator=(const funct_cmfptr_noerr&); 00479 00480 #endif 00481 00482 }; 00483 00484 /** \brief Member function pointer to a one-dimensional function 00485 with no parameters 00486 */ 00487 template <class tclass, class param_t> class funct_mfptr_nopar : 00488 public funct<param_t> { 00489 public: 00490 00491 /** \brief Specify the member function pointer 00492 */ 00493 funct_mfptr_nopar(tclass *tp, double (tclass::*fp)(double x)) { 00494 tptr=tp; 00495 fptr=fp; 00496 } 00497 00498 virtual ~funct_mfptr_nopar() {}; 00499 00500 /** \brief Compute the function at point \c x, with result \c y 00501 */ 00502 virtual int operator()(double x, double &y, param_t &pa) { 00503 y=(*tptr.*fptr)(x); 00504 return 0; 00505 } 00506 00507 /** \brief Compute the function at point \c x, returning the result 00508 00509 \comment 00510 This is here because if we overload operator()(double,double,void*), 00511 we have to reimplement all operator()'s 00512 \endcomment 00513 */ 00514 virtual double operator()(double x, param_t &pa) { 00515 double y; 00516 operator()(x,y,pa); 00517 return y; 00518 } 00519 00520 #ifndef DOXYGEN_INTERNAL 00521 00522 protected: 00523 00524 /// Storage for the member function pointer 00525 double (tclass::*fptr)(double x); 00526 /// Store the pointer to the class instance 00527 tclass *tptr; 00528 00529 #endif 00530 #ifndef DOXYGENP 00531 00532 private: 00533 00534 funct_mfptr_nopar(const funct_mfptr_nopar &); 00535 funct_mfptr_nopar& operator=(const funct_mfptr_nopar&); 00536 00537 #endif 00538 00539 }; 00540 00541 /** \brief Const member function pointer to a one-dimensional function 00542 with no parameters 00543 00544 \note While this is designed to accept a pointer to a const 00545 member function, the choice of whether the class pointer 00546 given in the template type <tt>tclass</tt> is const or 00547 not is up to the user. 00548 */ 00549 template <class tclass, class param_t> class funct_cmfptr_nopar : 00550 public funct<param_t> { 00551 public: 00552 00553 /** \brief Specify the member function pointer 00554 */ 00555 funct_cmfptr_nopar(tclass *tp, double (tclass::*fp)(double x) const) { 00556 tptr=tp; 00557 fptr=fp; 00558 } 00559 00560 virtual ~funct_cmfptr_nopar() {}; 00561 00562 /** \brief Compute the function at point \c x, with result \c y 00563 */ 00564 virtual int operator()(double x, double &y, param_t &pa) { 00565 y=(*tptr.*fptr)(x); 00566 return 0; 00567 } 00568 00569 /** \brief Compute the function at point \c x, returning the result 00570 00571 \comment 00572 This is here because if we overload operator()(double,double,void*), 00573 we have to reimplement all operator()'s 00574 \endcomment 00575 */ 00576 virtual double operator()(double x, param_t &pa) { 00577 double y; 00578 operator()(x,y,pa); 00579 return y; 00580 } 00581 00582 #ifndef DOXYGEN_INTERNAL 00583 00584 protected: 00585 00586 /// Storage for the const member function pointer 00587 double (tclass::*fptr)(double x) const; 00588 /// Store the pointer to the class instance 00589 tclass *tptr; 00590 00591 #endif 00592 #ifndef DOXYGENP 00593 00594 private: 00595 00596 funct_cmfptr_nopar(const funct_cmfptr_nopar &); 00597 funct_cmfptr_nopar& operator=(const funct_cmfptr_nopar&); 00598 00599 #endif 00600 00601 }; 00602 00603 #ifndef DOXYGENP 00604 } 00605 #endif 00606 00607 #endif
Documentation generated with Doxygen and provided under the GNU Free Documentation License. See License Information for details.
Project hosting provided by
,
O2scl Sourceforge Project Page