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 /** 00159 \brief Simple string comparison 00160 00161 This struct is used internally by \o2 for the STL routines which 00162 require a way to compare strings in the class \ref table and in 00163 the I/O classes. 00164 */ 00165 typedef struct { 00166 /// Return \c s1<s2 00167 bool operator()(const std::string s1, const std::string s2) const { 00168 return s1<s2; 00169 } 00170 } string_comp; 00171 00172 /** \brief Take a string of binary quads and compress them to 00173 hexadecimal digits 00174 00175 This function proceeds from left to right, ignoring parts of the 00176 string that do not consist of squences of four '1's or '0's. 00177 */ 00178 std::string binary_to_hex(std::string s); 00179 00180 /** 00181 \brief Generate number sequence for testing 00182 00183 A class which generates \c tot numbers from -1 to 1, making sure 00184 to include -1, 1, 0, and numbers near -1, 0 and 1 (so long as \c 00185 tot is sufficiently large). If gen() is called more than \c tot 00186 times, it just recycles through the list again. 00187 00188 This class is used to generate combinations of coefficients for 00189 testing the polynomial solvers. 00190 00191 For example, the first 15 numbers generated by 00192 an object of type gen_test_number<10> are: 00193 \verbatim 00194 0 -1.000000e+00 00195 1 -9.975274e-01 00196 2 -8.807971e-01 00197 3 -1.192029e-01 00198 4 -2.472623e-03 00199 5 +0.000000e+00 00200 6 +2.472623e-03 00201 7 +1.192029e-01 00202 8 +8.807971e-01 00203 9 +1.000000e+00 00204 10 -1.000000e+00 00205 11 -9.975274e-01 00206 12 -8.807971e-01 00207 13 -1.192029e-01 00208 14 -2.472623e-03 00209 \endverbatim 00210 00211 \future Document what happens if \c tot is small 00212 00213 */ 00214 template<size_t tot> class gen_test_number { 00215 00216 #ifndef DOXYGEN_INTERNAL 00217 00218 protected: 00219 00220 /// Count number of numbers generated 00221 int n; 00222 00223 /** \brief A constant factor for the argument to 00224 \c tanh() , equal to \c tot divided by 20. 00225 */ 00226 double fact; 00227 00228 #endif 00229 00230 public: 00231 00232 gen_test_number() { 00233 n=0; 00234 fact=((double)tot)/20.0; 00235 } 00236 00237 /// Return the next number in the sequence 00238 double gen() { 00239 double x, dtot=((double)tot), dn=((double)n); 00240 if (n==0) { 00241 x=-1.0; 00242 } else if (n==tot/2) { 00243 x=0.0; 00244 } else if (n==tot-1) { 00245 x=1.0; 00246 } else if (n==tot) { 00247 // Start the sequence over 00248 x=-1.0; 00249 n=0; 00250 } else if (n<((int)tot)/2) { 00251 // Since we're in the o2scl namespace, we explicitly 00252 // specify std::tanh() here 00253 x=(std::tanh((dn-dtot/4.0)/fact)-1.0)/2.0; 00254 } else { 00255 x=(std::tanh((dn-0.75*dtot)/fact)+1.0)/2.0; 00256 } 00257 n++; 00258 return x; 00259 } 00260 }; 00261 00262 /** 00263 \brief A convenient function to allocate several arrays of the 00264 same size 00265 00266 Allocate memory for <tt>nv</tt> vectors of size <tt>msize</tt> 00267 with names specified in <tt>names</tt> and function name 00268 <tt>func_name</tt> to produce pointers in <tt>ptrs</tt>. This 00269 function is unsed internally to allocate several GSL vectors in 00270 succession, taking care to call the error handler when 00271 necessary. 00272 00273 \future Fix so that __FILE__ and __LINE__ are implemented here. 00274 */ 00275 template<class type_t> 00276 int gsl_alloc_arrays(size_t nv, size_t msize, const char *names[], 00277 type_t *ptrs[], std::string func_name) { 00278 00279 for(size_t i=0;i<nv;i++) { 00280 ptrs[i]=(type_t *)malloc(msize*sizeof(type_t)); 00281 if (ptrs[i]==0) { 00282 for(size_t j=0;j<i;j++) { 00283 std::free(ptrs[j]); 00284 } 00285 std::string s="Failed to allocate space for "; 00286 s+=names[i]; 00287 s+=" in"+(func_name+'.'); 00288 O2SCL_ERR_RET(s.c_str(),gsl_enomem); 00289 } 00290 } 00291 00292 return gsl_success; 00293 } 00294 00295 #ifndef DOXYGENP 00296 } 00297 #endif 00298 00299 #endif 00300
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