00001 /* 00002 ------------------------------------------------------------------- 00003 00004 Copyright (C) 2006, 2007, 2008, 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 <iostream> 00030 #include <cmath> 00031 #include <string> 00032 #include <fstream> 00033 #include <sstream> 00034 #include <vector> 00035 #include <o2scl/err_hnd.h> 00036 #include <o2scl/lib_settings.h> 00037 #include <gsl/gsl_ieee_utils.h> 00038 00039 #ifndef DOXYGENP 00040 namespace o2scl { 00041 #endif 00042 00043 /** 00044 \brief Calculate a Fermi-Dirac distribution function safely 00045 00046 \f$ \left[1+\exp\left(E/T-\mu/T\right)\right]^{-1} \f$ 00047 00048 This calculates a Fermi-Dirac distribution function guaranteeing 00049 that numbers larger than \f$ \exp(\mathrm{limit}) \f$ and 00050 smaller than \f$ \exp(-\mathrm{limit}) \f$ will be avoided. The 00051 default value of \c limit ensures accuracy to within 1 part in 00052 \f$ 10^{17} \f$ compared to the maximum of the distribution 00053 (which is unity). 00054 00055 Note that this function may return Inf or NAN if \c limit is too 00056 large, depending on the machine precision. 00057 */ 00058 double fermi_function(double E, double mu, double T, double limit=40.0); 00059 00060 /** 00061 \brief Reformat the columns for output of width \c size 00062 00063 Given a string array \c in_cols of size \c nin, screenify() 00064 reformats the array into columns creating a new string array \c 00065 outc with size \c nout. 00066 00067 For example, for an array of 10 strings 00068 \verbatim 00069 test1 00070 test_of_string2 00071 test_of_string3 00072 test_of_string4 00073 test5 00074 test_of_string6 00075 test_of_string7 00076 test_of_string8 00077 test_of_string9 00078 test_of_string10 00079 \endverbatim 00080 screenify() will create an array of 3 new strings: 00081 \verbatim 00082 test1 test_of_string4 test_of_string7 test_of_string10 00083 test_of_string2 test5 test_of_string8 00084 test_of_string3 test_of_string6 test_of_string9 00085 \endverbatim 00086 00087 The string array given in outc must be deleted with 00088 delete[] after usage. 00089 00090 If the value of \c max_size is less than the 00091 length of the longest input string (plus one for 00092 a space character), then the output strings may 00093 have a larger length than \c max_size. 00094 00095 \todo Convert to the new version "screenify2" 00096 */ 00097 void screenify(const std::string *in_cols, int nin, 00098 std::string *&outc, int &nout, int max_size=80); 00099 00100 template<class string_arr_t> 00101 int screenify2(size_t nin, const string_arr_t &in_cols, 00102 std::vector<std::string> &out_cols, 00103 size_t max_size=80) { 00104 00105 size_t i,j,lmax,itemp; 00106 std::string *in_spaces=new std::string[nin]; 00107 00108 // Determine size of largest string 00109 lmax=0; 00110 for(i=0;i<nin;i++) { 00111 if (lmax<in_cols[i].size()) lmax=in_cols[i].size(); 00112 } 00113 00114 // Pad with spaces 00115 for(i=0;i<nin;i++) { 00116 itemp=in_cols[i].size(); 00117 in_spaces[i]=in_cols[i]; 00118 for(j=0;j<lmax+1-itemp;j++) { 00119 in_spaces[i]+=' '; 00120 } 00121 } 00122 00123 // Determine number of rows and columns 00124 size_t row, col; 00125 col=max_size/(lmax+1); 00126 if (col==0) col=1; 00127 if (nin/col*col==nin) row=nin/col; 00128 else row=nin/col+1; 00129 00130 // Create outc 00131 out_cols.reserve(row); 00132 for(i=0;i<row;i++) { 00133 out_cols.push_back(""); 00134 for(j=0;j<col;j++) { 00135 if (i+j*row<nin) { 00136 out_cols[i]+=in_spaces[i+j*row]; 00137 } 00138 } 00139 } 00140 00141 delete[] in_spaces; 00142 00143 return 0; 00144 00145 } 00146 00147 /** 00148 \brief Count the number of words in the string \c str 00149 00150 Words are defined as groups of characters separated by 00151 whitespace, where whitespace is any combination of adjacent 00152 spaces, tabs, carriage returns, etc. On most systems, whitespace 00153 is usually defined as any character corresponding to the 00154 integers 9 (horizontal tab), 10 (line feed), 11 (vertical tab), 00155 12 (form feed), 13 (carriage return), and 32 (space bar). The 00156 test program \c misc_ts enumerates the characters between 0 and 00157 255 (inclusive) that count as whitespace for this purpose. 00158 00159 Note that this function is used in text_in_file::string_in 00160 to perform string input. 00161 */ 00162 int count_words(std::string str); 00163 00164 /** 00165 \brief Naive string comparison 00166 00167 This is used internally for the STL routines which require a way 00168 to compare strings in the class \ref table and in the I/O 00169 classes. 00170 */ 00171 typedef struct { 00172 /// Return \c s1<s2 00173 bool operator()(const std::string s1, const std::string s2) const { 00174 return s1<s2; 00175 } 00176 } string_comp; 00177 00178 /** \brief Take a string of binary quads and compress them to 00179 hexadecimal digits 00180 00181 This function proceeds from left to right, ignoring parts of the 00182 string that do not consist of squences of four '1's or '0's. 00183 */ 00184 std::string binary_to_hex(std::string s); 00185 00186 /** 00187 \brief Generate number sequence for testing 00188 00189 A class which generates \c tot numbers from -1 to 1, making sure 00190 to include -1, 1, 0, and numbers near -1, 0 and 1 (so long as \c 00191 tot is sufficiently large). If gen() is called more than \c tot 00192 times, it just recycles through the list again. The template 00193 argument \c tot should probably be greater than or equal to 00194 three. 00195 00196 This class is used to generate combinations of coefficients for 00197 testing the polynomial solvers. 00198 00199 For example, the first 15 numbers generated by 00200 an object of type gen_test_number<10> are: 00201 \verbatim 00202 0 -1.000000e+00 00203 1 -9.975274e-01 00204 2 -8.807971e-01 00205 3 -1.192029e-01 00206 4 -2.472623e-03 00207 5 +0.000000e+00 00208 6 +2.472623e-03 00209 7 +1.192029e-01 00210 8 +8.807971e-01 00211 9 +1.000000e+00 00212 10 -1.000000e+00 00213 11 -9.975274e-01 00214 12 -8.807971e-01 00215 13 -1.192029e-01 00216 14 -2.472623e-03 00217 \endverbatim 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 /// A constant factor for the argument to \c tanh(). 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 x=-1.0; 00251 n=0; 00252 } else if (n<((int)tot)/2) { 00253 x=(tanh((dn-dtot/4.0)/fact)-1.0)/2.0; 00254 } else { 00255 x=(tanh((dn-0.75*dtot)/fact)+1.0)/2.0; 00256 } 00257 n++; 00258 return x; 00259 } 00260 }; 00261 00262 #ifndef DOXYGENP 00263 } 00264 #endif 00265 00266 #endif 00267
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