multi_funct.h

00001 /*
00002   -------------------------------------------------------------------
00003   
00004   Copyright (C) 2006, 2007, 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_MULTI_FUNCT_H
00024 #define O2SCL_MULTI_FUNCT_H
00025 
00026 #include <string>
00027 #include <o2scl/collection.h>
00028 
00029 #ifndef DOXYGENP
00030 namespace o2scl {
00031 #endif
00032 
00033   /** 
00034       \brief Multi-dimensional function base
00035 
00036       This class generalizes one function of several variables,
00037       i.e. \f$ y(x_0,x_1,...,x_{nv-1}) \f$ where \c nv is the number
00038       of variables in the function y. 
00039   */
00040 
00041   template<class param_t, class vec_t=ovector_view> class multi_funct {
00042 
00043     public:  
00044 
00045     multi_funct() {}
00046 
00047     virtual ~multi_funct() {}
00048 
00049     /** \brief Compute a function \c y of \c nv variables stored in \c x
00050         with parameter \c pa.
00051     */
00052     virtual int operator()(size_t nv, const vec_t &x, double &y, param_t &pa) {
00053 
00054     /** \brief Compute a function \c y of \c nv variables stored in \c x
00055         with parameter \c pa.
00056     */
00057       set_err_ret("Missing base in mm_funct::operator().",gsl_nobase);
00058     }
00059 
00060 
00061     /** \brief Return the value of a function of \c nv variables
00062         stored in \c x with parameter \c pa.
00063 
00064         Note that this is reimplemented in all children because 
00065         if one member function operator() is reimplemented, all must be.
00066     */
00067     virtual double operator()(size_t nv, const vec_t &x, param_t &pa) {
00068       double y;
00069       operator()(nv,x,y,pa);
00070       return y;
00071     }
00072   
00073 #ifndef DOXYGENP
00074 
00075     private:
00076 
00077     multi_funct(const multi_funct &);
00078     multi_funct& operator=(const multi_funct&);
00079 
00080 #endif
00081 
00082   };
00083 
00084   /** \brief Function pointer to a multi-dimensional function
00085    */
00086   template<class param_t, class vec_t=ovector_view>
00087     class multi_funct_fptr : public multi_funct<param_t,vec_t> {
00088 
00089     public:
00090 
00091     /** \brief Specify the function pointer
00092      */
00093     multi_funct_fptr(int (*fp)(size_t nv, const vec_t &x, double &y, 
00094                                param_t &pa)) {
00095       fptr=fp;
00096     }
00097     
00098 
00099     virtual ~multi_funct_fptr() {};
00100 
00101     /** \brief Compute a function \c y of \c nv variables stored in \c x
00102         with parameter \c pa.
00103     */
00104     virtual int operator()(size_t nv, const vec_t &x, double &y, param_t &pa) {
00105       return fptr(nv,x,y,pa);
00106     }
00107 
00108     /** \brief Return the value of a function of \c nv variables
00109         stored in \c x with parameter \c pa.
00110 
00111         Note that this is reimplemented in all children because 
00112         if one member function operator() is reimplemented, all must be.
00113     */
00114     virtual double operator()(size_t nv, const vec_t &x, param_t &pa) {
00115       double y;
00116       operator()(nv,x,y,pa);
00117       return y;
00118     }
00119 
00120 #ifndef DOXYGEN_INTERNAL
00121 
00122     protected:
00123     
00124     friend class io_tlate<multi_funct_fptr>;
00125 
00126     /// Store the function pointer
00127     int (*fptr)(size_t nv, const vec_t &x, double &y, param_t &pa);
00128 
00129     multi_funct_fptr() {}
00130 
00131 #ifndef DOXYGENP
00132 #endif
00133 
00134     private:
00135 
00136     multi_funct_fptr(const multi_funct_fptr &);
00137     multi_funct_fptr& operator=(const multi_funct_fptr&);
00138 
00139 #endif
00140 
00141   };
00142 
00143   /** \brief Function pointer to a gsl_multimin_function
00144    */
00145   template<class param_t, class vec_t=ovector_view>
00146     class multi_funct_gsl : public multi_funct<param_t,vec_t> {
00147     public:
00148 
00149     /** \brief Specify the function pointer
00150      */
00151     multi_funct_gsl(double (*fp)(const gsl_vector *x, param_t &pa)) {
00152       fptr=fp;
00153     }
00154     
00155     virtual ~multi_funct_gsl() {}
00156 
00157     /** \brief Compute a function \c y of \c nv variables stored in \c x
00158         with parameter \c pa.
00159     */
00160     virtual int operator()(size_t nv, const vec_t &x, double &y, param_t &pa) {
00161       const gsl_vector *gx=(const gsl_vector *)(&x);
00162       y=fptr(gx,pa);
00163       return 0;
00164     }
00165 
00166     /** \brief Return the value of a function of \c nv variables
00167         stored in \c x with parameter \c pa.
00168 
00169         Note that this is reimplemented in all children because 
00170         if one member function operator() is reimplemented, all must be.
00171     */
00172     virtual double operator()(size_t nv, const vec_t &x, param_t &pa) {
00173       double y;
00174       operator()(nv,x,y,pa);
00175       return y;
00176     }
00177 
00178 #ifndef DOXYGEN_INTERNAL
00179 
00180     protected:
00181   
00182     friend class io_tlate<multi_funct_gsl>;
00183     
00184     /// Store the function pointer
00185     double (*fptr)(const gsl_vector *x, param_t &pa);
00186     
00187     multi_funct_gsl() {}
00188 
00189 #ifndef DOXYGENP
00190 #endif
00191 
00192     private:
00193 
00194     multi_funct_gsl(const multi_funct_gsl &);
00195     multi_funct_gsl& operator=(const multi_funct_gsl&);
00196 
00197 #endif
00198 
00199   };
00200 
00201   /** \brief Function pointer to a multi-dimensional function without
00202       error control
00203   */
00204   template<class param_t, class vec_t=ovector_view>
00205     class multi_funct_fptr_noerr : public multi_funct<param_t,vec_t> {
00206     public:
00207 
00208     /** \brief Specify the function pointer
00209      */
00210     multi_funct_fptr_noerr(double (*fp)(size_t nv, const vec_t &x, 
00211                                         param_t &pa)) {
00212       fptr=fp;
00213     }
00214 
00215     virtual ~multi_funct_fptr_noerr() {}
00216     
00217     /** \brief Compute a function \c y of \c nv variables stored in \c x
00218         with parameter \c pa.
00219     */
00220     virtual int operator()(size_t nv, const vec_t &x, double &y, param_t &pa) {
00221       y=fptr(nv,x,pa);
00222       return 0;
00223     }
00224 
00225     /** \brief Return the value of a function of \c nv variables
00226         stored in \c x with parameter \c pa.
00227 
00228         Note that this is reimplemented in all children because 
00229         if one member function operator() is reimplemented, all must be.
00230     */
00231     virtual double operator()(size_t nv, const vec_t &x, param_t &pa) {
00232       double y;
00233       operator()(nv,x,y,pa);
00234       return y;
00235     }
00236 
00237 #ifndef DOXYGEN_INTERNAL
00238 
00239     protected:
00240 
00241     friend class io_tlate<multi_funct_fptr_noerr>;
00242   
00243     multi_funct_fptr_noerr() {}
00244 
00245     /// Store the function pointer
00246     double (*fptr)(size_t nv, const vec_t &x, param_t &pa);
00247 
00248 #ifndef DOXYGENP
00249 #endif
00250 
00251     private:
00252 
00253     multi_funct_fptr_noerr(const multi_funct_fptr_noerr &);
00254     multi_funct_fptr_noerr& operator=(const multi_funct_fptr_noerr&);
00255 
00256 #endif
00257 
00258   };
00259 
00260   /** \brief Member function pointer to a multi-dimensional function
00261    */
00262   template<class tclass, class param_t, class vec_t=ovector_view>
00263     class multi_funct_mfptr : public multi_funct<param_t,vec_t> {
00264     public:
00265   
00266     /** \brief Specify the member function pointer
00267      */
00268     multi_funct_mfptr(tclass *tp, int (tclass::*fp)
00269                       (size_t nv, const vec_t &x, double &y, param_t &pa)) {
00270       tptr=tp;
00271       fptr=fp;
00272     }
00273   
00274     virtual ~multi_funct_mfptr() {}
00275   
00276     /** \brief Compute a function \c y of \c nv variables stored in \c x
00277         with parameter \c pa.
00278     */
00279     virtual int operator()(size_t nv, const vec_t &x, double &y, param_t &pa) {
00280       return (*tptr.*fptr)(nv,x,y,pa);
00281     }
00282 
00283     /** \brief Return the value of a function of \c nv variables
00284         stored in \c x with parameter \c pa.
00285 
00286         Note that this is reimplemented in all children because 
00287         if one member function operator() is reimplemented, all must be.
00288     */
00289     virtual double operator()(size_t nv, const vec_t &x, param_t &pa) {
00290       double y;
00291       operator()(nv,x,y,pa);
00292       return y;
00293     }
00294   
00295 #ifndef DOXYGEN_INTERNAL
00296   
00297     protected:
00298   
00299     /// Store the function pointer
00300     int (tclass::*fptr)(size_t nv, const vec_t &x, double &y, param_t &pa);
00301     /// Store a pointer to the class instance
00302     tclass *tptr;
00303   
00304 #ifndef DOXYGENP
00305 #endif
00306 
00307     private:
00308 
00309     multi_funct_mfptr(const multi_funct_mfptr &);
00310     multi_funct_mfptr& operator=(const multi_funct_mfptr&);
00311 
00312 #endif
00313 
00314   };
00315 
00316   /** \brief Member function pointer to a multi-dimensional function
00317    */
00318   template<class tclass, class param_t, class vec_t=ovector_view>
00319     class multi_funct_mfptr_noerr : public multi_funct<param_t,vec_t> {
00320     public:
00321   
00322     /** \brief Specify the member function pointer
00323      */
00324     multi_funct_mfptr_noerr(tclass *tp, double (tclass::*fp)
00325                             (size_t nv, const vec_t &x, param_t &pa)) {
00326       tptr=tp;
00327       fptr=fp;
00328     }
00329   
00330     virtual ~multi_funct_mfptr_noerr() {}
00331   
00332     /** \brief Compute a function \c y of \c nv variables stored in \c x
00333         with parameter \c pa.
00334     */
00335     virtual int operator()(size_t nv, const vec_t &x, double &y, param_t &pa) {
00336       y=(*tptr.*fptr)(nv,x,pa);
00337       return 0;
00338     }
00339 
00340     /** \brief Return the value of a function of \c nv variables
00341         stored in \c x with parameter \c pa.
00342 
00343         Note that this is reimplemented in all children because 
00344         if one member function operator() is reimplemented, all must be.
00345     */
00346     virtual double operator()(size_t nv, const vec_t &x, param_t &pa) {
00347       double y;
00348       operator()(nv,x,y,pa);
00349       return y;
00350     }
00351   
00352 #ifndef DOXYGEN_INTERNAL
00353   
00354     protected:
00355   
00356     /// Store the function pointer
00357     double (tclass::*fptr)(size_t nv, const vec_t &x, param_t &pa);
00358     /// Store a pointer to the class instance
00359     tclass *tptr;
00360   
00361 #ifndef DOXYGENP
00362 #endif
00363 
00364     private:
00365 
00366     multi_funct_mfptr_noerr(const multi_funct_mfptr_noerr &);
00367     multi_funct_mfptr_noerr& operator=(const multi_funct_mfptr_noerr&);
00368 
00369 #endif
00370 
00371   };
00372   
00373   // ---------------------------------------------------------------------
00374   // ---------------------------------------------------------------------
00375 
00376   /** 
00377       \brief Multi-dimensional function base with arrays
00378 
00379       This class generalizes one function of several variables,
00380       i.e.  \f$ y(x_0,x_1,...,x_{nv-1}) \f$  where \c nv  is the number
00381       of variables in the function y. 
00382   */
00383   template<class param_t, size_t nvar> class multi_vfunct {
00384 
00385     public:  
00386 
00387     multi_vfunct() {}
00388 
00389     virtual ~multi_vfunct() {}
00390     
00391     /** \brief Compute a function \c y of \c nv variables stored in \c x
00392         with parameter \c pa.
00393     */
00394     virtual int operator()(size_t nv, const double x[nvar], double &y, 
00395                            param_t &pa) {
00396       set_err_ret("Missing base in mm_vfunct::operator().",gsl_nobase);
00397     }
00398     
00399     /** \brief Return the value of a function of \c nv variables
00400         stored in \c x with parameter \c pa.
00401 
00402         Note that this is reimplemented in all children because 
00403         if one member function operator() is reimplemented, all must be.
00404     */
00405     virtual double operator()(size_t nv, const double x[nvar], param_t &pa) {
00406       double y;
00407       operator()(nv,x,y,pa);
00408       return y;
00409     }
00410   
00411 #ifndef DOXYGENP
00412 
00413     private:
00414 
00415     multi_vfunct(const multi_vfunct &);
00416     multi_vfunct& operator=(const multi_vfunct&);
00417 
00418 #endif
00419 
00420   };
00421 
00422   /** \brief Function pointer to a multi-dimensional function with arrays
00423    */
00424   template<class param_t, size_t nvar>
00425     class multi_vfunct_fptr : public multi_vfunct<param_t,nvar> {
00426 
00427     public:
00428 
00429     /** \brief Specify the function pointer
00430      */
00431     multi_vfunct_fptr(int (*fp)(size_t nv, const double x[nvar], double &y, 
00432                                param_t &pa)) {
00433       fptr=fp;
00434     }
00435     
00436 
00437     virtual ~multi_vfunct_fptr() {}
00438 
00439     /** \brief Compute a function \c y of \c nv variables stored in \c x
00440         with parameter \c pa.
00441     */
00442     virtual int operator()(size_t nv, const double x[nvar], double &y, 
00443                            param_t &pa) {
00444       return fptr(nv,x,y,pa);
00445     }
00446     
00447     /** \brief Return the value of a function of \c nv variables
00448         stored in \c x with parameter \c pa.
00449 
00450         Note that this is reimplemented in all children because 
00451         if one member function operator() is reimplemented, all must be.
00452     */
00453     virtual double operator()(size_t nv, const double x[nvar], param_t &pa) {
00454       double y;
00455       operator()(nv,x,y,pa);
00456       return y;
00457     }
00458 
00459 #ifndef DOXYGEN_INTERNAL
00460 
00461     protected:
00462     
00463     friend class io_tlate<multi_vfunct_fptr>;
00464 
00465     /// Store the function pointer
00466     int (*fptr)(size_t nv, const double x[nvar], double &y, param_t &pa);
00467 
00468     multi_vfunct_fptr() {}
00469 
00470 #ifndef DOXYGENP
00471 #endif
00472 
00473     private:
00474 
00475     multi_vfunct_fptr(const multi_vfunct_fptr &);
00476     multi_vfunct_fptr& operator=(const multi_vfunct_fptr&);
00477 
00478 #endif
00479 
00480   };
00481 
00482   /** \brief Function pointer to a gsl_multimin_function with arrays
00483    */
00484   template<class param_t, size_t nvar>
00485     class multi_vfunct_gsl : public multi_vfunct<param_t,nvar> {
00486     public:
00487 
00488     /** \brief Specify the function pointer
00489      */
00490     multi_vfunct_gsl(double (*fp)(const gsl_vector *x, param_t &pa)) {
00491       fptr=fp;
00492     }
00493     
00494     virtual ~multi_vfunct_gsl() {}
00495 
00496     /** \brief Compute a function \c y of \c nv variables stored in \c x
00497         with parameter \c pa.
00498     */
00499     virtual int operator()(size_t nv, const double x[nvar], double &y, 
00500                            param_t &pa) {
00501       const gsl_vector *gx=(const gsl_vector *)(&x);
00502       y=fptr(gx,pa);
00503       return 0;
00504     }
00505 
00506     /** \brief Return the value of a function of \c nv variables
00507         stored in \c x with parameter \c pa.
00508 
00509         Note that this is reimplemented in all children because 
00510         if one member function operator() is reimplemented, all must be.
00511     */
00512     virtual double operator()(size_t nv, const double x[nvar], param_t &pa) {
00513       double y;
00514       operator()(nv,x,y,pa);
00515       return y;
00516     }
00517 
00518 #ifndef DOXYGEN_INTERNAL
00519 
00520     protected:
00521   
00522     friend class io_tlate<multi_vfunct_gsl>;
00523     
00524     /// Store the function pointer
00525     double (*fptr)(const gsl_vector *x, param_t &pa);
00526     
00527     multi_vfunct_gsl() {}
00528 
00529 #ifndef DOXYGENP
00530 #endif
00531 
00532     private:
00533 
00534     multi_vfunct_gsl(const multi_vfunct_gsl &);
00535     multi_vfunct_gsl& operator=(const multi_vfunct_gsl&);
00536 
00537 #endif
00538 
00539   };
00540 
00541   /** \brief Function pointer to a multi-dimensional function with
00542       arrays and without error control
00543   */
00544   template<class param_t, size_t nvar>
00545     class multi_vfunct_fptr_noerr : public multi_vfunct<param_t,nvar> {
00546     public:
00547     
00548     /** \brief Specify the function pointer
00549      */
00550     multi_vfunct_fptr_noerr(double (*fp)(size_t nv, const double x[nvar], 
00551                                          param_t &pa)) {
00552       fptr=fp;
00553     }
00554     
00555     virtual ~multi_vfunct_fptr_noerr() {}
00556 
00557     /** \brief Compute a function \c y of \c nv variables stored in \c x
00558         with parameter \c pa.
00559     */
00560     virtual int operator()(size_t nv, const double x[nvar], double &y, 
00561                            param_t &pa) {
00562       y=fptr(nv,x,pa);
00563       return 0;
00564     }
00565 
00566     /** \brief Return the value of a function of \c nv variables
00567         stored in \c x with parameter \c pa.
00568 
00569         Note that this is reimplemented in all children because 
00570         if one member function operator() is reimplemented, all must be.
00571     */
00572     virtual double operator()(size_t nv, const double x[nvar], param_t &pa) {
00573       double y;
00574       operator()(nv,x,y,pa);
00575       return y;
00576     }
00577 
00578 #ifndef DOXYGEN_INTERNAL
00579 
00580     protected:
00581 
00582     friend class io_tlate<multi_vfunct_fptr_noerr>;
00583   
00584     multi_vfunct_fptr_noerr() {}
00585 
00586     /// Store the function pointer
00587     double (*fptr)(size_t nv, const double x[nvar], param_t &pa);
00588 
00589 #ifndef DOXYGENP
00590 #endif
00591 
00592     private:
00593 
00594     multi_vfunct_fptr_noerr(const multi_vfunct_fptr_noerr &);
00595     multi_vfunct_fptr_noerr& operator=(const multi_vfunct_fptr_noerr&);
00596 
00597 #endif
00598 
00599   };
00600 
00601   /** \brief Member function pointer to a multi-dimensional function
00602       with arrays
00603    */
00604   template<class tclass, class param_t, size_t nvar>
00605     class multi_vfunct_mfptr : public multi_vfunct<param_t,nvar> {
00606     public:
00607   
00608     /** \brief Specify the member function pointer
00609      */
00610     multi_vfunct_mfptr(tclass *tp, int (tclass::*fp)
00611                        (size_t nv, const double x[nvar], double &y, 
00612                         param_t &pa)) {
00613       tptr=tp;
00614       fptr=fp;
00615     }
00616     
00617     virtual ~multi_vfunct_mfptr() {}
00618     
00619     /** \brief Compute a function \c y of \c nv variables stored in \c x
00620         with parameter \c pa.
00621     */
00622     virtual int operator()(size_t nv, const double x[nvar], double &y, 
00623                            param_t &pa) {
00624       return (*tptr.*fptr)(nv,x,y,pa);
00625     }
00626 
00627     /** \brief Return the value of a function of \c nv variables
00628         stored in \c x with parameter \c pa.
00629 
00630         Note that this is reimplemented in all children because 
00631         if one member function operator() is reimplemented, all must be.
00632     */
00633     virtual double operator()(size_t nv, const double x[nvar], param_t &pa) {
00634       double y;
00635       operator()(nv,x,y,pa);
00636       return y;
00637     }
00638   
00639 #ifndef DOXYGEN_INTERNAL
00640   
00641     protected:
00642   
00643     /// Store the function pointer
00644     int (tclass::*fptr)(size_t nv, const double x[nvar], double &y, 
00645                         param_t &pa);
00646 
00647     /// Store a pointer to the class instance
00648     tclass *tptr;
00649   
00650 #ifndef DOXYGENP
00651 #endif
00652 
00653     private:
00654 
00655     multi_vfunct_mfptr(const multi_vfunct_mfptr &);
00656     multi_vfunct_mfptr& operator=(const multi_vfunct_mfptr&);
00657 
00658 #endif
00659 
00660   };
00661 
00662   /** \brief Member function pointer to a multi-dimensional function
00663       with arrays
00664    */
00665   template<class tclass, class param_t, size_t nvar>
00666     class multi_vfunct_mfptr_noerr : public multi_vfunct<param_t,nvar> {
00667     public:
00668   
00669     /** \brief Specify the member function pointer
00670      */
00671     multi_vfunct_mfptr_noerr(tclass *tp, double (tclass::*fp)
00672                             (size_t nv, const double x[nvar], param_t &pa)) {
00673       tptr=tp;
00674       fptr=fp;
00675     }
00676   
00677     virtual ~multi_vfunct_mfptr_noerr() {}
00678   
00679     /** \brief Compute a function \c y of \c nv variables stored in \c x
00680         with parameter \c pa.
00681     */
00682     virtual int operator()(size_t nv, const double x[nvar], double &y, 
00683                            param_t &pa) {
00684       y=(*tptr.*fptr)(nv,x,pa);
00685       return 0;
00686     }
00687 
00688     /** \brief Return the value of a function of \c nv variables
00689         stored in \c x with parameter \c pa.
00690 
00691         Note that this is reimplemented in all children because 
00692         if one member function operator() is reimplemented, all must be.
00693     */
00694     virtual double operator()(size_t nv, const double x[nvar], param_t &pa) {
00695       double y;
00696       operator()(nv,x,y,pa);
00697       return y;
00698     }
00699   
00700 #ifndef DOXYGEN_INTERNAL
00701   
00702     protected:
00703   
00704     /// Store the function pointer
00705     double (tclass::*fptr)(size_t nv, const double x[nvar], param_t &pa);
00706 
00707     /// Store a pointer to the class instance
00708     tclass *tptr;
00709   
00710 #ifndef DOXYGENP
00711 #endif
00712 
00713     private:
00714 
00715     multi_vfunct_mfptr_noerr(const multi_vfunct_mfptr_noerr &);
00716     multi_vfunct_mfptr_noerr& operator=(const multi_vfunct_mfptr_noerr&);
00717 
00718 #endif
00719 
00720   };
00721   
00722 #ifndef DOXYGENP
00723 }
00724 #endif
00725 
00726 #endif

Documentation generated with Doxygen and provided under the GNU Free Documentation License. See License Information for details.