Object-oriented Scientific Computing Library: Version 0.910
ode_iv_solve.h
00001 /*
00002   -------------------------------------------------------------------
00003   
00004   Copyright (C) 2006-2012, 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_ODE_IV_SOLVE_H
00024 #define O2SCL_ODE_IV_SOLVE_H
00025 
00026 #include <string>
00027 #include <o2scl/adapt_step.h>
00028 #include <o2scl/gsl_astep.h>
00029 
00030 #ifndef DOXYGENP
00031 namespace o2scl {
00032 #endif
00033 
00034   /** \brief Solve an initial-value ODE problems given an adaptive ODE
00035       stepper
00036 
00037       This class is experimental.
00038 
00039       This class gives several functions which solve an initial
00040       value ODE problem. The functions \ref solve_final_value()
00041       give only the final value of the functions at the end
00042       of the ODE integration and are relatively fast. 
00043 
00044       The function solve_store() stores the solution of the ODE over
00045       the full range into a set of vectors and matrices which are
00046       allocated and specified by the user. This function is designed
00047       to give exactly the same results (though this cannot be
00048       guaranteed) as solve_final_value() and additionally records some
00049       or all of the results from the adaptive steps which were taken.
00050 
00051       The functions solve_grid() works as in solve_store() except
00052       that the solution is stored on a grid of points in the 
00053       independent variable specified by the user, at the cost of 
00054       taking extra steps to ensure that function values,
00055       derivatives, and errors are computed at each grid point. 
00056 
00057       All of these functions automatically evaluate the derivatives
00058       from the specified function at the initial point and
00059       user-specified initial derivatives are ignored. The total
00060       number of steps taken is limited by \ref ntrial and \ref
00061       nsteps stores the number of steps taken by the most recent
00062       solution. The variable \ref nsteps_out is the maximum number
00063       of points in the interval for which verbose output will be
00064       given when \ref verbose is greater than zero.
00065 
00066       There is an example for the usage of this class in
00067       <tt>examples/ex_ode.cpp</tt> documented in the \ref ex_ode_sect
00068       section.
00069 
00070       Default template arguments
00071       - \c func_t - \ref ode_funct 
00072       - \c vec_t - \ref ovector_base 
00073       - \c alloc_vec_t - \ref ovector 
00074       - \c alloc_t  - \ref ovector_alloc 
00075       
00076       The default adaptive stepper is an object of type \ref gsl_astep.
00077 
00078       \future The form of solve_final_value() is very similar to that
00079       of adapt_step::astep_full(), but not quite the same. Maybe
00080       should probably be made to be consistent with each other?
00081   */
00082   template<class func_t=ode_funct<>, 
00083     class vec_t=ovector_base, class alloc_vec_t=ovector, 
00084     class alloc_t=ovector_alloc> class ode_iv_solve {
00085    
00086 #ifndef DOXYGEN_INTERNAL
00087     
00088   protected:
00089     
00090   /// Memory allocator
00091   alloc_t ao;
00092 
00093   /// \name Desc
00094   //@{
00095   alloc_vec_t vtemp, vtemp2, vtemp3, vtemp4;
00096   //@}
00097 
00098   /// Desc
00099   size_t mem_size;
00100 
00101   /// The adaptive stepper
00102   adapt_step<func_t,vec_t,alloc_vec_t,alloc_t> *astp;
00103     
00104   /// Print out iteration information
00105   virtual int print_iter(double x, size_t nv, vec_t &y) {
00106     std::cout << type() << " x: " << x << " y: ";
00107     for(size_t i=0;i<nv;i++) std::cout << y[i] << " ";
00108     std::cout << std::endl;
00109     if (verbose>1) {
00110       char ch;
00111       std::cin >> ch;
00112     }
00113     return 0;
00114   }
00115 
00116   /// Free allocated memory
00117   void free() {
00118     if (mem_size>0) {
00119       ao.free(vtemp);
00120       ao.free(vtemp2);
00121       ao.free(vtemp3);
00122       ao.free(vtemp4);
00123     }
00124   }
00125 
00126   /// Allocate space for temporary vectors
00127   void allocate(size_t n) {
00128     if (n!=mem_size) {
00129       free();
00130       ao.allocate(vtemp,n);
00131       ao.allocate(vtemp2,n);
00132       ao.allocate(vtemp3,n);
00133       ao.allocate(vtemp4,n);
00134       mem_size=n;
00135     }
00136   }
00137   
00138 #endif
00139 
00140   public:
00141       
00142   ode_iv_solve() {
00143     verbose=0;
00144     ntrial=1000;
00145     nsteps_out=10;
00146     astp=&gsl_astp;
00147     exit_on_fail=true;
00148     mem_size=0;
00149   }
00150       
00151   virtual ~ode_iv_solve() {
00152     free();
00153   }
00154 
00155   /// \name Main solver functions
00156   //@{
00157   /** \brief Solve the initial-value problem to get the final value
00158 
00159       Given the \c n initial values of the functions in \c ystart,
00160       this function integrates the ODEs specified in \c derivs over
00161       the interval from \c x0 to \c x1 with an initial stepsize of \c
00162       h. The final values of the function are given in \c yend and the
00163       initial values of \c yend are ignored.
00164 
00165       If \ref verbose is greater than zero, The solution at less than
00166       or approximately equal to \ref nsteps_out points will be written
00167       to \c std::cout. If \ref verbose is greater than one, a
00168       character will be required after each selected point.
00169 
00170       \todo Document if yend can be the same as ystart.
00171   */
00172   int solve_final_value(double x0, double x1, double h, size_t n,
00173                         vec_t &ystart, vec_t &yend, func_t &derivs) {
00174 
00175     allocate(n);
00176     return solve_final_value(x0,x1,h,n,ystart,yend,vtemp2,
00177                              vtemp3,derivs);
00178   }
00179       
00180   /** \brief Solve the initial-value problem to get the final value
00181       with errors
00182 
00183       Given the \c n initial values of the functions in \c ystart,
00184       this function integrates the ODEs specified in \c derivs over
00185       the interval from \c x0 to \c x1 with an initial stepsize of \c
00186       h. The final values of the function are given in \c yend and the
00187       associated errors are given in \c yerr. The initial values of \c
00188       yend and \c yerr are ignored.
00189 
00190       If \ref verbose is greater than zero, The solution at less
00191       than or approximately equal to \ref nsteps_out points will be
00192       written to \c std::cout. If \ref verbose is greater than one,
00193       a character will be required after each selected point.
00194   */
00195   int solve_final_value(double x0, double x1, double h, size_t n,
00196                         vec_t &ystart, vec_t &yend, vec_t &yerr,
00197                         func_t &derivs) {
00198 
00199     allocate(n);
00200     return solve_final_value(x0,x1,h,n,ystart,yend,yerr,
00201                              vtemp2,derivs);
00202   }
00203       
00204   /** \brief Solve the initial-value problem to get the final value,
00205       derivatives, and errors
00206 
00207       Given the \c n initial values of the functions in \c ystart,
00208       this function integrates the ODEs specified in \c derivs over
00209       the interval from \c x0 to \c x1 with an initial stepsize of \c
00210       h. The final values of the function are given in \c yend, the
00211       derivatives in \c dydx_end, and the associated errors are given
00212       in \c yerr. The initial values of \c yend and \c yerr are
00213       ignored.
00214 
00215       This function is designed to be relatively fast,
00216       avoiding extra copying of vectors back and forth. 
00217 
00218       If \ref verbose is greater than zero, The solution at less
00219       than or approximately equal to \ref nsteps_out points will be
00220       written to \c std::cout. If \ref verbose is greater than one,
00221       a character will be required after each selected point.
00222 
00223       This function computes \c dydx_start automatically and the
00224       values given by the user are ignored. 
00225 
00226       The solution fails if more than \ref ntrial steps are required.
00227       This function will also fail if <tt>x1>x0</tt> and <tt>h<0</tt>
00228       or if <tt>x1<x0</tt> but <tt>h>0</tt>.
00229   */
00230   int solve_final_value(double x0, double x1, double h, size_t n,
00231                         vec_t &ystart, vec_t &yend, vec_t &yerr, 
00232                         vec_t &dydx_end, func_t &derivs) {
00233     
00234     if ((x1>x0 && h<=0.0) || (x0>x1 && h>=0.0)) {
00235       std::string str="Interval direction (x1-x0="+dtos(x1-x0)+
00236       ") does not match step direction (h="+dtos(h)+
00237       " in ode_iv_solve::solve_final_value().";
00238       O2SCL_ERR_RET(str.c_str(),gsl_einval);
00239     }
00240 
00241     // Allocate for temporary vectors
00242     allocate(n);
00243     
00244     // The variable 'x' is the current independent variable, xnext is 
00245     // the next value of x, xverb is the next value of x for which 
00246     // verbose output should be provided, and dxverb is the stepsize 
00247     // for xverb.
00248     double x=x0, xverb=0.0, dxverb=0.0, xnext;
00249     int ret=0, first_ret=0;
00250 
00251     nsteps=0;
00252 
00253     // Create a reference to make the code easier to read
00254     alloc_vec_t &dydx_start=vtemp;
00255 
00256     // Compute stepsize for verbose output
00257     if (verbose>0) {
00258       print_iter(x0,n,ystart);
00259       if (verbose>1) {
00260         char ch;
00261         std::cin >> ch;
00262       }
00263       // Ensure that 'dxverb' is positive
00264       if (x1>x0) {
00265         dxverb=(x1-x0)/((double)nsteps_out);
00266         xverb=x0+dxverb;
00267       } else {
00268         dxverb=(x0-x1)/((double)nsteps_out);
00269         xverb=x0-dxverb;
00270       }
00271     }
00272 
00273     // Use yend as workspace
00274     for(size_t i=0;i<n;i++) yend[i]=ystart[i];
00275 
00276     // Compute initial derivative
00277     derivs(x,n,yend,dydx_start);
00278       
00279     bool done=false;
00280     while (done==false) {
00281         
00282       // Take a step of the first type
00283       ret=astp->astep_full(x,x1,xnext,h,n,ystart,dydx_start,
00284                            yend,yerr,dydx_end,derivs);
00285       
00286       if (ret!=0) {
00287         if (exit_on_fail) {
00288           O2SCL_ERR2_RET("Adaptive stepper failed in ",
00289                          "ode_iv_solve::solve_final_value()",ret);
00290         } else if (first_ret!=0) {
00291           first_ret=ret;
00292         }
00293       }
00294 
00295       // Print out verbose info 
00296       if (verbose>0 && xnext>xverb) {
00297         print_iter(xnext,n,yend);
00298         if (verbose>1) {
00299           char ch;
00300           std::cin >> ch;
00301         }
00302         xverb+=dxverb;
00303       }
00304 
00305       // Check number of iterations
00306       nsteps++;
00307       if (nsteps>ntrial) {
00308         std::string str="Too many steps required (ntrial="+itos(ntrial)+
00309           ", x="+dtos(x)+") in ode_iv_solve::solve_final_value().";
00310         O2SCL_ERR_RET(str.c_str(),gsl_emaxiter);
00311       }
00312 
00313       if (ret!=0) {
00314         done=true;
00315       } else {
00316         if (x1>x0) {
00317           if (xnext>=x1) done=true;
00318         } else {
00319           if (xnext<=x1) done=true;
00320         }
00321       }
00322 
00323       if (done==false) {
00324 
00325         // Take a step of the second type
00326         ret=astp->astep_full(xnext,x1,x,h,n,yend,dydx_end,ystart,yerr,
00327                              dydx_start,derivs);
00328         
00329         if (ret!=0) {
00330           if (exit_on_fail) {
00331             O2SCL_ERR2_RET("Adaptive stepper failed in ",
00332                            "ode_iv_solve::solve_final_value()",ret);
00333           } else if (first_ret!=0) {
00334             first_ret=ret;
00335           }
00336         }
00337 
00338         // Print out verbose info 
00339         if (verbose>0 && x>xverb) {
00340           print_iter(x,n,ystart);
00341           if (verbose>1) {
00342             char ch;
00343             std::cin >> ch;
00344           }
00345           xverb+=dxverb;
00346         }
00347 
00348         // Check number of iterations
00349         nsteps++;
00350         if (nsteps>ntrial) {
00351           std::string str="Too many steps required (ntrial="+itos(ntrial)+
00352             ", x="+dtos(x)+") in ode_iv_solve::solve_final_value().";
00353           O2SCL_ERR_RET(str.c_str(),gsl_emaxiter);
00354         }
00355 
00356         if (ret!=0) {
00357           done=true;
00358         } else {
00359           if (x1>x0) {
00360             if (x>=x1) {
00361               done=true;
00362               for(size_t j=0;j<n;j++) {
00363                 yend[j]=ystart[j];
00364                 dydx_end[j]=dydx_start[j];
00365               }
00366             }
00367           } else {
00368             if (x<=x1) {
00369               done=true;
00370               for(size_t j=0;j<n;j++) {
00371                 yend[j]=ystart[j];
00372                 dydx_end[j]=dydx_start[j];
00373               }
00374             }
00375           }
00376         }
00377 
00378       }
00379 
00380       // End of while loop
00381     }
00382         
00383     // Print out final verbose info
00384     if (verbose>0) {
00385       print_iter(x1,n,yend);
00386       if (verbose>1) {
00387         char ch;
00388         std::cin >> ch;
00389       }
00390     }
00391         
00392     return first_ret;
00393   }
00394       
00395   /** \brief Solve the initial-value problem and store the 
00396       associated output
00397 
00398       Initially, \c x_sol should be a vector of size \c n_sol, and \c
00399       y_sol, \c dydx_sol, and \c yerr_sol should be matrices with size
00400       \c [n_sol][n].  On exit, \c n_sol will will be number of points
00401       store, less than or equal to the original value of \c
00402       n_sol. This function avoids performing extra calls to the
00403       adaptive stepper, and the table will be approximately evenly
00404       spaced.
00405 
00406       This function is also designed to give the exactly the same
00407       results as solve_final_value(). This cannot be strictly
00408       guaranteed, but will likely hold in most applications.
00409 
00410       This template function works with any matrix class \c mat_t
00411       which can be accessed using successive applications of
00412       operator[] and which has an associated class \c mat_row_t
00413       which returns a row of a matrix of type \c mat_t as
00414       an object with type \c vec_t. 
00415 
00416       If \ref verbose is greater than zero, The solution at each
00417       internal point will be written to \c std::cout.  If \ref verbose
00418       is greater than one, a character will be required after each
00419       point.
00420 
00421       \future It might be possible to remove some extra copying 
00422       by removing the yerrl and dydx vectors
00423   */
00424   template<class mat_t, class mat_row_t>
00425   int solve_store(double x0, double x1, double h, size_t n, size_t &n_sol, 
00426                   vec_t &x_sol, mat_t &y_sol, mat_t &yerr_sol, 
00427                   mat_t &dydx_sol, func_t &derivs, size_t istart=0) {
00428     
00429     int ret=0;
00430     int first_ret=0;
00431     size_t nmax=n_sol-1;
00432     nsteps=0;
00433 
00434     // Stepsize for next verbose output. Use nsteps_out-1 instead of
00435     // nsteps_out since the first point is always output below.
00436     double dx_verb=(x1-x0)/((double)(nsteps_out-1));
00437     // Stepsize for next table entry
00438     double dx_tab=(x1-x0)/((double)(n_sol-istart-1));
00439 
00440     double x_verb=x0+dx_verb;
00441     double x_tab=x0+dx_tab;
00442     
00443     // Allocate space for errors and derivatives and storage
00444     allocate(n);
00445 
00446     // Create some references just to make the code easier
00447     // to read
00448     alloc_vec_t &ystart=vtemp4;
00449     alloc_vec_t &dydx_start=vtemp2;
00450 
00451     // Copy first point to ystart
00452     for(size_t j=0;j<n;j++) ystart[j]=y_sol[istart][j];
00453 
00454     // Output first point 
00455     if (verbose>0) {
00456       print_iter(x0,n,ystart);
00457       if (verbose>1) {
00458         char ch;
00459         std::cin >> ch;
00460       }
00461     }
00462 
00463     // Initial derivative evaulation
00464     derivs(x0,n,ystart,dydx_start);
00465 
00466     // Add first derivatives to table
00467     x_sol[istart]=x0;
00468     for(size_t j=0;j<n;j++) {
00469       dydx_sol[istart][j]=dydx_start[j];
00470       yerr_sol[istart][j]=0.0;
00471     }
00472 
00473     // Copy first point to table again for first step
00474     size_t icurr=istart+1;
00475     x_sol[icurr]=x0;
00476     for(size_t j=0;j<n;j++) y_sol[icurr][j]=ystart[j];
00477 
00478     double xnext;
00479     
00480     bool done=false;
00481     while (done==false) {
00482 
00483       // Create some references just to make the code easier
00484       // to read
00485       alloc_vec_t &yerr=vtemp;
00486       alloc_vec_t &dydx_out=vtemp3;
00487 
00488       // Use ystart as temporary storage for the end of the current
00489       // adaptive step
00490       mat_row_t yrow(y_sol,icurr);
00491       ret=astp->astep_full(x0,x1,xnext,h,n,yrow,dydx_start,ystart,yerr,
00492                            dydx_out,derivs);
00493       
00494       if (ret!=0) {
00495         if (exit_on_fail) {
00496           n_sol=icurr+1;
00497           // call error handler
00498           O2SCL_ERR2_RET("Adaptive stepper returned non-zero in ",
00499                          "ode_iv_solve::solve_store().",gsl_efailed);
00500         } else if (first_ret==0) {
00501           first_ret=ret;
00502         }
00503       }
00504       
00505       // Update step counter and abort if necessary
00506       nsteps++;
00507       if (nsteps>ntrial) {
00508         std::string str="Too many steps required (ntrial="+itos(ntrial)+
00509           ", x="+dtos(x0)+") in ode_iv_solve::solve_store().";
00510         O2SCL_ERR_RET(str.c_str(),gsl_emaxiter);
00511       }
00512       
00513       // If we've made enough progress, do verbose output
00514       if (xnext>=x_verb && verbose>0) {
00515         print_iter(xnext,n,ystart);
00516         if (verbose>1) {
00517           char ch;
00518           std::cin >> ch;
00519         }
00520         x_verb+=dx_verb;
00521       }
00522 
00523       // If we're at the end
00524       if (xnext>=x1) {
00525 
00526         // Exit the loop
00527         done=true;
00528 
00529         // Store the final entry in the table
00530         x_sol[icurr]=xnext;
00531         for(size_t j=0;j<n;j++) {
00532           y_sol[icurr][j]=ystart[j];
00533           dydx_sol[icurr][j]=dydx_out[j];
00534           yerr_sol[icurr][j]=yerr[j];
00535         }
00536 
00537         // Update the table size
00538         n_sol=icurr+1;
00539 
00540       } else {
00541 
00542         if (xnext>=x_tab && icurr<nmax) {
00543           
00544           // If we've made enough progress, store an entry in the table
00545           x_sol[icurr]=xnext;
00546           for(size_t j=0;j<n;j++) {
00547             y_sol[icurr][j]=ystart[j];
00548             dydx_sol[icurr][j]=dydx_out[j];
00549             yerr_sol[icurr][j]=yerr[j];
00550             
00551             // Also prepare for the next step
00552             y_sol[icurr+1][j]=ystart[j];
00553             dydx_start[j]=dydx_out[j];
00554           }
00555           x_tab+=dx_tab;
00556           
00557           // Update x0 and the current and next indicies
00558           x0=xnext;
00559           icurr++;
00560           
00561         } else {
00562 
00563           // Otherwise, just prepare for the next step
00564           // without updating icurr
00565           x0=xnext;
00566           for(size_t j=0;j<n;j++) {
00567             dydx_start[j]=dydx_out[j];
00568             y_sol[icurr][j]=ystart[j];
00569           }
00570           
00571         }
00572         
00573       }
00574      
00575       // End of loop 'while (done==false)'
00576     }
00577 
00578     return first_ret;
00579   }
00580 
00581   /** \brief Solve the initial-value problem from \c x0 to \c x1 over
00582       a grid storing derivatives and errors
00583 
00584       Initially, \c xsol should be an array of size \c nsol, and \c
00585       ysol should be a \c omatrix of size \c [nsol][n]. This function
00586       never takes a step larger than the grid size.
00587 
00588       If \ref verbose is greater than zero, The solution at each grid
00589       point will be written to \c std::cout. If \ref verbose is
00590       greater than one, a character will be required after each point.
00591 
00592       \future Consider making a version of grid which gives the 
00593       same answers as solve_final_value(). After each proposed step,
00594       it would go back and fill in the grid points if the proposed
00595       step was past the next grid point.
00596   */
00597   template<class mat_t, class mat_row_t>
00598   int solve_grid(double h, size_t n, size_t nsol, vec_t &xsol, 
00599                  mat_t &ysol, mat_t &err_sol, mat_t &dydx_sol, 
00600                  func_t &derivs) {
00601     
00602     double x0=xsol[0];
00603     double x1=xsol[nsol-1];
00604 
00605     double x=x0, xnext;
00606     int ret=0, first_ret=0;
00607     nsteps=0;
00608 
00609     // Copy the initial point to the first row
00610     xsol[0]=x0;
00611 
00612     // Create space for the initial point of each step
00613     allocate(n);
00614 
00615     // Create some references just to make the code easier
00616     // to read
00617     alloc_vec_t &ystart=vtemp;
00618     alloc_vec_t &dydx_start=vtemp2;
00619 
00620     // Copy ysol[0] to ystart
00621     for(size_t j=0;j<n;j++) {
00622       ystart[j]=ysol[0][j];
00623     }
00624 
00625     // Verbose output for the first row
00626     if (verbose>0) print_iter(xsol[0],n,ystart);
00627     
00628     // Evalulate the first derivative
00629     derivs(x0,n,ystart,dydx_start);
00630     
00631     // Set the derivatives and the uncertainties for the first row
00632     for(size_t j=0;j<n;j++) {
00633       dydx_sol[0][j]=dydx_start[j];
00634       err_sol[0][j]=0.0;
00635     }
00636 
00637     for(size_t i=1;i<nsol && ret==0;i++) {
00638           
00639       xnext=x0+(x1-x0)*((double)i)/((double)(nsol-1));
00640             
00641       mat_row_t y_row(ysol,i);
00642       mat_row_t dydx_row(dydx_sol,i);
00643       mat_row_t yerr_row(err_sol,i);
00644 
00645       // Step until we reach the next grid point
00646       bool done=false;
00647       while(done==false && ret==0) {
00648         
00649         ret=astp->astep_full(x,xnext,xsol[i],h,n,ystart,dydx_start,
00650                              y_row,yerr_row,dydx_row,derivs);
00651         nsteps++;
00652         if (ret!=0) {
00653           if (exit_on_fail) {
00654             O2SCL_ERR2_RET("Adaptive stepper failed in ",
00655                            "ode_iv_solve::solve_grid()",ret);
00656           } else if (first_ret!=0) {
00657             first_ret=ret;
00658           }
00659         }
00660         
00661         if (nsteps>ntrial) {
00662           std::string str="Too many steps required (ntrial="+itos(ntrial)+
00663             ", x="+dtos(x)+") in ode_iv_solve::solve_grid().";
00664           O2SCL_ERR_RET(str.c_str(),gsl_emaxiter);
00665         }
00666 
00667         // Copy the results of the last step to the starting
00668         // point for the next step
00669         x=xsol[i];
00670         for(size_t j=0;j<n;j++) {
00671           ystart[j]=y_row[j];
00672           dydx_start[j]=dydx_row[j];
00673         }
00674         
00675         // Decide if we have reached the grid point
00676         if (x1>x0) {
00677           if (x>=xnext) done=true;
00678         } else {
00679           if (x<=xnext) done=true;
00680         }
00681             
00682       }
00683       
00684       if (verbose>0) print_iter(xsol[i],n,dydx_row);
00685 
00686     }
00687     
00688     return first_ret;
00689   }
00690   //@}
00691 
00692   /// Set output level
00693   int verbose;
00694       
00695   /** \brief Number of output points if \ref verbose is greater 
00696       than zero (default 10)
00697 
00698       This is used in functions solve_table() and solve_final_value()
00699       to control how often steps are output when verbose is greater
00700       than zero.
00701   */
00702   size_t nsteps_out;
00703 
00704   /// Maximum number of applications of the adaptive stepper (default 1000)
00705   size_t ntrial;
00706 
00707   /// Number of adaptive steps employed
00708   size_t nsteps;
00709 
00710   /// \name The adaptive stepper
00711   //@{
00712   /// Set the adaptive stepper to use
00713   int set_adapt_step(adapt_step<func_t,vec_t,alloc_vec_t,alloc_t> &as) {
00714     astp=&as;
00715     return 0;
00716   }
00717 
00718   /** \brief If true, stop the solution if the adaptive stepper fails
00719       (default true)
00720       
00721       If this is false, then failures in the adaptive stepper are
00722       ignored.
00723   */
00724   bool exit_on_fail;
00725 
00726   /// The default adaptive stepper
00727   gsl_astep<func_t,vec_t,alloc_vec_t,alloc_t> gsl_astp;
00728   //@}
00729 
00730   /// Return the type, \c "ode_iv_solve".
00731   virtual const char *type() { return "ode_iv_solve"; }
00732   
00733   };
00734 
00735 #ifndef DOXYGENP
00736 }
00737 #endif
00738 
00739 #endif
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Documentation generated with Doxygen. Provided under the GNU Free Documentation License (see License Information).

Get Object-oriented Scientific Computing
Lib at SourceForge.net. Fast, secure and Free Open Source software
downloads.