![]() |
Object-oriented Scientific Computing Library: Version 0.910
|
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
Documentation generated with Doxygen. Provided under the GNU Free Documentation License (see License Information).