Object-oriented Scientific Computing Library: Version 0.910
misc.h
Go to the documentation of this file.
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_MISC_H
00024 #define O2SCL_MISC_H
00025 /** \file misc.h
00026     \brief Miscellaneous functions
00027 */
00028 
00029 #include <cstdlib>
00030 #include <iostream>
00031 #include <cmath>
00032 #include <string>
00033 #include <fstream>
00034 #include <sstream>
00035 #include <vector>
00036 
00037 #include <gsl/gsl_vector.h>
00038 #include <gsl/gsl_ieee_utils.h>
00039 
00040 #include <o2scl/err_hnd.h>
00041 #include <o2scl/lib_settings.h>
00042 
00043 #ifndef DOXYGENP
00044 namespace o2scl {
00045 #endif
00046 
00047   /** \brief Calculate a Fermi-Dirac distribution function safely
00048       
00049       \f$ \left[1+\exp\left(E/T-\mu/T\right)\right]^{-1} \f$ 
00050       
00051       This calculates a Fermi-Dirac distribution function guaranteeing
00052       that numbers larger than \f$ \exp(\mathrm{limit}) \f$ and
00053       smaller than \f$ \exp(-\mathrm{limit}) \f$ will be avoided. The
00054       default value of <tt>limit=40</tt> ensures accuracy to within 1
00055       part in \f$ 10^{17} \f$ compared to the maximum of the
00056       distribution (which is unity).
00057       
00058       Note that this function may return Inf or NAN if \c limit is too 
00059       large, depending on the machine precision.
00060   */
00061   double fermi_function(double E, double mu, double T, double limit=40.0);
00062 
00063   /** \brief Reformat the columns for output of width \c size 
00064 
00065       Given a string array \c in_cols of size \c nin, screenify()
00066       reformats the array into columns creating a new string array \c
00067       out_cols.
00068       
00069       For example, for an array of 10 strings 
00070       \verbatim
00071       test1
00072       test_of_string2
00073       test_of_string3
00074       test_of_string4
00075       test5
00076       test_of_string6
00077       test_of_string7
00078       test_of_string8
00079       test_of_string9
00080       test_of_string10
00081       \endverbatim
00082       screenify() will create an array of 3 new strings:
00083       \verbatim
00084       test1            test_of_string4  test_of_string7  test_of_string10
00085       test_of_string2  test5            test_of_string8
00086       test_of_string3  test_of_string6  test_of_string9
00087       \endverbatim
00088       
00089       If the value of \c max_size is less than the length of the
00090       longest input string (plus one for a space character), then the
00091       output strings may have a larger length than \c max_size.
00092   */
00093   template<class string_arr_t>
00094     int screenify(size_t nin, const string_arr_t &in_cols, 
00095                   std::vector<std::string> &out_cols,
00096                   size_t max_size=80) {
00097     
00098     size_t i,j,lmax,itemp;
00099     std::string *in_spaces=new std::string[nin];
00100     
00101     // Determine size of largest string
00102     lmax=0;
00103     for(i=0;i<nin;i++) {
00104       if (lmax<in_cols[i].size()) lmax=in_cols[i].size();
00105     }
00106 
00107     // Pad with spaces
00108     for(i=0;i<nin;i++) {
00109       itemp=in_cols[i].size();
00110       in_spaces[i]=in_cols[i];
00111       for(j=0;j<lmax+1-itemp;j++) {
00112         in_spaces[i]+=' ';
00113       }
00114     }
00115 
00116     // Determine number of rows and columns
00117     size_t row, col;
00118     col=max_size/(lmax+1);
00119     if (col==0) col=1;
00120     if (nin/col*col==nin) row=nin/col;
00121     else row=nin/col+1;
00122 
00123     // Create outc
00124     out_cols.reserve(row);
00125     for(i=0;i<row;i++) {
00126       out_cols.push_back("");
00127       for(j=0;j<col;j++) {
00128         if (i+j*row<nin) {
00129           out_cols[i]+=in_spaces[i+j*row];
00130         }
00131       }
00132     }
00133 
00134     delete[] in_spaces;
00135 
00136     return 0;
00137   
00138   }
00139 
00140   /** \brief Count the number of words in the string \c str 
00141    
00142       Words are defined as groups of characters separated by
00143       whitespace, where whitespace is any combination of adjacent
00144       spaces, tabs, carriage returns, etc. On most systems, whitespace
00145       is usually defined as any character corresponding to the
00146       integers 9 (horizontal tab), 10 (line feed), 11 (vertical tab),
00147       12 (form feed), 13 (carriage return), and 32 (space bar).  The
00148       test program \c misc_ts enumerates the characters between 0 and
00149       255 (inclusive) that count as whitespace for this purpose.
00150 
00151       Note that this function is used in text_in_file::string_in 
00152       to perform string input.
00153   */
00154   int count_words(std::string str);
00155   
00156   /** \brief Remove all whitespace from the string \c s
00157 
00158       This function removes all characters in \c s which correspond
00159       to the integer values 9, 10, 11, 12, 13, or 32.
00160    */
00161   int remove_whitespace(std::string &s);
00162 
00163   /** \brief Simple string comparison 
00164       
00165       This struct is used internally by \o2 for the STL routines which
00166       require a way to compare strings in the class \ref table and in
00167       the I/O classes.
00168   */
00169   typedef struct {
00170     /// Return \c s1<s2
00171     bool operator()(const std::string s1, const std::string s2) const {
00172       return s1<s2;
00173     }
00174   } string_comp;
00175   
00176   /** \brief Take a string of binary quads and compress them to 
00177       hexadecimal digits
00178 
00179       This function proceeds from left to right, ignoring parts of the
00180       string that do not consist of squences of four '1's or '0's.
00181   */
00182   std::string binary_to_hex(std::string s);
00183 
00184   /** \brief Generate number sequence for testing
00185       
00186       A class which generates \c tot numbers from -1 to 1, making sure
00187       to include -1, 1, 0, and numbers near -1, 0 and 1 (so long as \c
00188       tot is sufficiently large). If gen() is called more than \c tot
00189       times, it just recycles through the list again.  
00190       
00191       This class is used to generate combinations of coefficients for
00192       testing the polynomial solvers.
00193 
00194       For example, the first 15 numbers generated by
00195       an object of type gen_test_number<10> are:
00196       \verbatim
00197       0  -1.000000e+00
00198       1  -9.975274e-01
00199       2  -8.807971e-01
00200       3  -1.192029e-01
00201       4  -2.472623e-03
00202       5  +0.000000e+00
00203       6  +2.472623e-03
00204       7  +1.192029e-01
00205       8  +8.807971e-01
00206       9  +1.000000e+00
00207       10 -1.000000e+00
00208       11 -9.975274e-01
00209       12 -8.807971e-01
00210       13 -1.192029e-01
00211       14 -2.472623e-03
00212       \endverbatim
00213 
00214       This function is used in <tt>src/other/poly_ts.cpp</tt> which
00215       tests the polynomial solvers.
00216 
00217       \future Document what happens if \c tot is pathologically small.
00218   */
00219   template<size_t tot> class gen_test_number {
00220 
00221 #ifndef DOXYGEN_INTERNAL
00222 
00223   protected:
00224 
00225     /// Count number of numbers generated
00226     int n;
00227 
00228     /** \brief A constant factor for the argument to 
00229         <tt>tanh()</tt>, equal to \c tot divided by 20.
00230     */
00231     double fact;
00232 
00233 #endif
00234 
00235   public:
00236 
00237     gen_test_number() {
00238       n=0;
00239       fact=((double)tot)/20.0;
00240     }
00241 
00242     /// Return the next number in the sequence
00243     double gen() {
00244       double x, dtot=((double)tot), dn=((double)n);
00245       if (n==0) {
00246         x=-1.0;
00247       } else if (n==tot/2) {
00248         x=0.0;
00249       } else if (n==tot-1) {
00250         x=1.0;
00251       } else if (n==tot) {
00252         // Start the sequence over
00253         x=-1.0;
00254         n=0;
00255       } else if (n<((int)tot)/2) {
00256         // Since we're in the o2scl namespace, we explicitly
00257         // specify std::tanh() here
00258         x=(std::tanh((dn-dtot/4.0)/fact)-1.0)/2.0;
00259       } else {
00260         x=(std::tanh((dn-0.75*dtot)/fact)+1.0)/2.0;
00261       }
00262       n++;
00263       return x;
00264     }
00265   };
00266 
00267   /** \brief A convenient function to allocate several arrays of the 
00268       same size
00269       
00270       Allocate memory for <tt>nv</tt> vectors of size <tt>msize</tt>
00271       with names specified in <tt>names</tt> and function name
00272       <tt>func_name</tt> to produce pointers in <tt>ptrs</tt>. This
00273       function is unsed internally to allocate several vectors in
00274       succession, taking care to free memory and call the error
00275       handler when an allocation fails.
00276 
00277       The caller must make sure that previously allocated memory 
00278       will be freed and an error is thrown if this function
00279       returns a non-zero value.
00280 
00281       This function is used, for example, in \ref gsl_miser.
00282 
00283       \comment
00284       \todo Remove or rework this because of exception safety
00285       5/21/11 - Actually, this function is ok, because it uses
00286       malloc instead of new and throws an error properly. 
00287       \endcomment
00288   */
00289   template<class type_t> 
00290     int gsl_alloc_arrays(size_t nv, size_t msize, const char *names[], 
00291                          type_t *ptrs[], std::string func_name) {
00292     
00293     for(size_t i=0;i<nv;i++) {
00294       ptrs[i]=(type_t *)malloc(msize*sizeof(type_t));
00295       if (ptrs[i]==0) {
00296         for(size_t j=0;j<i;j++) {
00297           std::free(ptrs[j]);
00298         }
00299         return gsl_enomem;
00300       }
00301     }
00302 
00303     return gsl_success;
00304   }
00305 
00306   /** \brief A convenient function to allocate and initialize 
00307       several arrays of the same size
00308 
00309       The caller must make sure that previously allocated memory 
00310       will be freed and an error is thrown if this function
00311       returns a non-zero value.
00312 
00313       \comment
00314       \todo Remove or rework this because of exception safety
00315       5/21/01 - Actually, this function is ok, because it uses
00316       malloc instead of new and throws an error properly. 
00317       \endcomment
00318   */
00319   template<class type_t> 
00320     int gsl_calloc_arrays(size_t nv, size_t msize, const char *names[], 
00321                           type_t *ptrs[], std::string func_name,
00322                           type_t val) {
00323 
00324     int ret=gsl_alloc_arrays<type_t>(nv,msize,names,ptrs,func_name);
00325     if (ret==gsl_success) {
00326       for(size_t i=0;i<nv;i++) {
00327         for(size_t j=0;j<msize;j++) {
00328           ptrs[i][j]=val;
00329         }
00330       }
00331     }
00332     return ret;
00333   }
00334 
00335   /** \brief A convenient function to allocate and initialize 
00336       several arrays of the same size
00337 
00338       The caller must make sure that previously allocated memory 
00339       will be freed and an error is thrown if this function
00340       returns a non-zero value.
00341 
00342       \comment
00343       \todo Remove or rework this because of exception safety
00344       5/21/01 - Actually, this function is ok, because it uses
00345       malloc instead of new and throws an error properly. 
00346       \endcomment
00347   */
00348   int gsl_calloc_gvecs(size_t nv, size_t msize, const char *names[], 
00349                        gsl_vector ***ptrs, std::string func_name);
00350   
00351   /** \brief Return the x value of the extremum of a quadratic defined by 
00352       three \f$ (x,y) \f$ pairs
00353 
00354       \future Make a function quadratic_points(double x1, 
00355       double x2, double x3, double y1, double y2, double y3,
00356       double &a, double &b, double &c)?
00357       \future Make a quadratic_extremum_xy()?
00358       
00359   */
00360   double quadratic_extremum_x(double x1, double x2, double x3,
00361                               double y1, double y2, double y3);
00362 
00363   /** \brief Return the y value of the extremum of a quadratic defined by 
00364       three \f$ (x,y) \f$ pairs
00365   */
00366   double quadratic_extremum_y(double x1, double x2, double x3,
00367                               double y1, double y2, double y3);
00368   
00369 #ifndef DOXYGENP
00370 }
00371 #endif
00372 
00373 #endif
00374 
 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.