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_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_ieee_utils.h> 00038 00039 #include <o2scl/err_hnd.h> 00040 #include <o2scl/lib_settings.h> 00041 00042 #ifndef DOXYGENP 00043 namespace o2scl { 00044 #endif 00045 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 /** 00064 \brief Reformat the columns for output of width \c size 00065 00066 Given a string array \c in_cols of size \c nin, screenify() 00067 reformats the array into columns creating a new string array \c 00068 out_cols. 00069 00070 For example, for an array of 10 strings 00071 \verbatim 00072 test1 00073 test_of_string2 00074 test_of_string3 00075 test_of_string4 00076 test5 00077 test_of_string6 00078 test_of_string7 00079 test_of_string8 00080 test_of_string9 00081 test_of_string10 00082 \endverbatim 00083 screenify() will create an array of 3 new strings: 00084 \verbatim 00085 test1 test_of_string4 test_of_string7 test_of_string10 00086 test_of_string2 test5 test_of_string8 00087 test_of_string3 test_of_string6 test_of_string9 00088 \endverbatim 00089 00090 If the value of \c max_size is less than the length of the 00091 longest input string (plus one for a space character), then the 00092 output strings may have a larger length than \c max_size. 00093 */ 00094 template<class string_arr_t> 00095 int screenify(size_t nin, const string_arr_t &in_cols, 00096 std::vector<std::string> &out_cols, 00097 size_t max_size=80) { 00098 00099 size_t i,j,lmax,itemp; 00100 std::string *in_spaces=new std::string[nin]; 00101 00102 // Determine size of largest string 00103 lmax=0; 00104 for(i=0;i<nin;i++) { 00105 if (lmax<in_cols[i].size()) lmax=in_cols[i].size(); 00106 } 00107 00108 // Pad with spaces 00109 for(i=0;i<nin;i++) { 00110 itemp=in_cols[i].size(); 00111 in_spaces[i]=in_cols[i]; 00112 for(j=0;j<lmax+1-itemp;j++) { 00113 in_spaces[i]+=' '; 00114 } 00115 } 00116 00117 // Determine number of rows and columns 00118 size_t row, col; 00119 col=max_size/(lmax+1); 00120 if (col==0) col=1; 00121 if (nin/col*col==nin) row=nin/col; 00122 else row=nin/col+1; 00123 00124 // Create outc 00125 out_cols.reserve(row); 00126 for(i=0;i<row;i++) { 00127 out_cols.push_back(""); 00128 for(j=0;j<col;j++) { 00129 if (i+j*row<nin) { 00130 out_cols[i]+=in_spaces[i+j*row]; 00131 } 00132 } 00133 } 00134 00135 delete[] in_spaces; 00136 00137 return 0; 00138 00139 } 00140 00141 /** 00142 \brief Count the number of words in the string \c str 00143 00144 Words are defined as groups of characters separated by 00145 whitespace, where whitespace is any combination of adjacent 00146 spaces, tabs, carriage returns, etc. On most systems, whitespace 00147 is usually defined as any character corresponding to the 00148 integers 9 (horizontal tab), 10 (line feed), 11 (vertical tab), 00149 12 (form feed), 13 (carriage return), and 32 (space bar). The 00150 test program \c misc_ts enumerates the characters between 0 and 00151 255 (inclusive) that count as whitespace for this purpose. 00152 00153 Note that this function is used in text_in_file::string_in 00154 to perform string input. 00155 */ 00156 int count_words(std::string str); 00157 00158 /// Desc 00159 int remove_whitespace(std::string &s); 00160 00161 /** 00162 \brief Simple string comparison 00163 00164 This struct is used internally by \o2 for the STL routines which 00165 require a way to compare strings in the class \ref table and in 00166 the I/O classes. 00167 */ 00168 typedef struct { 00169 /// Return \c s1<s2 00170 bool operator()(const std::string s1, const std::string s2) const { 00171 return s1<s2; 00172 } 00173 } string_comp; 00174 00175 /** \brief Take a string of binary quads and compress them to 00176 hexadecimal digits 00177 00178 This function proceeds from left to right, ignoring parts of the 00179 string that do not consist of squences of four '1's or '0's. 00180 */ 00181 std::string binary_to_hex(std::string s); 00182 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 \future Document what happens if \c tot is small 00215 00216 */ 00217 template<size_t tot> class gen_test_number { 00218 00219 #ifndef DOXYGEN_INTERNAL 00220 00221 protected: 00222 00223 /// Count number of numbers generated 00224 int n; 00225 00226 /** \brief A constant factor for the argument to 00227 \c tanh() , equal to \c tot divided by 20. 00228 */ 00229 double fact; 00230 00231 #endif 00232 00233 public: 00234 00235 gen_test_number() { 00236 n=0; 00237 fact=((double)tot)/20.0; 00238 } 00239 00240 /// Return the next number in the sequence 00241 double gen() { 00242 double x, dtot=((double)tot), dn=((double)n); 00243 if (n==0) { 00244 x=-1.0; 00245 } else if (n==tot/2) { 00246 x=0.0; 00247 } else if (n==tot-1) { 00248 x=1.0; 00249 } else if (n==tot) { 00250 // Start the sequence over 00251 x=-1.0; 00252 n=0; 00253 } else if (n<((int)tot)/2) { 00254 // Since we're in the o2scl namespace, we explicitly 00255 // specify std::tanh() here 00256 x=(std::tanh((dn-dtot/4.0)/fact)-1.0)/2.0; 00257 } else { 00258 x=(std::tanh((dn-0.75*dtot)/fact)+1.0)/2.0; 00259 } 00260 n++; 00261 return x; 00262 } 00263 }; 00264 00265 /** 00266 \brief A convenient function to allocate several arrays of the 00267 same size 00268 00269 Allocate memory for <tt>nv</tt> vectors of size <tt>msize</tt> 00270 with names specified in <tt>names</tt> and function name 00271 <tt>func_name</tt> to produce pointers in <tt>ptrs</tt>. This 00272 function is unsed internally to allocate several GSL vectors in 00273 succession, taking care to call the error handler when 00274 necessary. 00275 00276 \future Fix so that __FILE__ and __LINE__ are implemented here. 00277 */ 00278 template<class type_t> 00279 int gsl_alloc_arrays(size_t nv, size_t msize, const char *names[], 00280 type_t *ptrs[], std::string func_name) { 00281 00282 for(size_t i=0;i<nv;i++) { 00283 ptrs[i]=(type_t *)malloc(msize*sizeof(type_t)); 00284 if (ptrs[i]==0) { 00285 for(size_t j=0;j<i;j++) { 00286 std::free(ptrs[j]); 00287 } 00288 std::string s="Failed to allocate space for "; 00289 s+=names[i]; 00290 s+=" in"+(func_name+'.'); 00291 O2SCL_ERR_RET(s.c_str(),gsl_enomem); 00292 } 00293 } 00294 00295 return gsl_success; 00296 } 00297 00298 #ifndef DOXYGENP 00299 } 00300 #endif 00301 00302 #endif 00303
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