![]() |
MechSys
1.0
Computing library for simulations in continuum and discrete mechanics
|
00001 /************************************************************************ 00002 * MechSys - Open Library for Mechanical Systems * 00003 * Copyright (C) 2005 Dorival M. Pedroso, Raul Durand * 00004 * Copyright (C) 2009 Sergio Galindo * 00005 * * 00006 * This program is free software: you can redistribute it and/or modify * 00007 * it under the terms of the GNU General Public License as published by * 00008 * the Free Software Foundation, either version 3 of the License, or * 00009 * any later version. * 00010 * * 00011 * This program is distributed in the hope that it will be useful, * 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00014 * GNU General Public License for more details. * 00015 * * 00016 * You should have received a copy of the GNU General Public License * 00017 * along with this program. If not, see <http://www.gnu.org/licenses/> * 00018 ************************************************************************/ 00019 00020 #ifndef MECHSYS_SORT_H 00021 #define MECHSYS_SORT_H 00022 00023 // STL 00024 #include <cmath> 00025 #include <cfloat> // for DBL_EPSILON 00026 #include <fstream> 00027 #include <sstream> // for istringstream 00028 00029 // MechSys 00030 #include <mechsys/util/string.h> 00031 #include <mechsys/util/array.h> 00032 00033 namespace Util 00034 { 00035 00036 // Constants 00037 const double ZERO = sqrt(DBL_EPSILON); 00038 const double SQ2 = sqrt(2.0); 00039 const double SQ3 = sqrt(3.0); 00040 const double SQ6 = sqrt(6.0); 00041 const double SQ2BY3 = sqrt(2.0/3.0); 00042 const double PI = 4.0*atan(1.0); 00043 00044 inline bool IsNan(double Val) 00045 { 00046 return (std::isnan(Val) || ((Val==Val)==false)); // NaN is the only value, for which the expression Val==Val is always false 00047 } 00048 00050 inline double Signum (double x, double Tol=DBL_EPSILON) { return (fabs(x)>Tol ? (x>=0.0 ? +1.0 : -1.0) : 0.0); } 00051 00052 /* 00053 inline double Sgn (double Val) { return (Val>=0.0 ? +1.0 : -1.0); } ///< Sgn function where Sgn(0)=+1 00054 inline double Sign (double a, double b) { return (b>=0.0 ? fabs(a) : -fabs(a)); } ///< Composite Sgn function. Returns |a| or -|a| according to the sign of b 00055 inline double Acos (double Val) { return (Val>=1.0 ? 0.0 : (Val<=-1.0 ? Pi() : acos(Val)) ); } ///< Safe acos function 00056 inline bool Str2Bool (String const & Str) { if (Str==String("true") || Str==String("TRUE") || Str==String("True")) return true; else return false; } ///< Converts "TRUE", "True", or "true" to bool 00057 inline bool IsNanOrInf (double Val) { int r=std::fpclassify(Val); if (r==FP_NAN) return true; if (r==FP_INFINITE) return true; return false; } ///< Check whether a number is NaN of Inf 00058 */ 00059 00060 template <typename Val_T> inline Val_T Min (Val_T const & a, Val_T const & b) { return (a<b ? a : b); } 00061 template <typename Val_T> inline Val_T Max (Val_T const & a, Val_T const & b) { return (a>b ? a : b); } 00062 template <typename Val_T> inline Val_T Max (Val_T const & a, Val_T const & b, Val_T const & c) 00063 { 00064 if (a>=b && a>=c) return a; 00065 if (b>=a && b>=c) return b; 00066 return c; 00067 } 00068 00070 template <typename Val_T> 00071 inline void Swap (Val_T & a, Val_T & b) 00072 { 00073 Val_T tmp = a; 00074 a = b; 00075 b = tmp; 00076 } 00077 00079 template <typename Val_T> 00080 inline void Sort (Val_T & a, Val_T & b) 00081 { 00082 if (b<a) Util::Swap (a,b); 00083 } 00084 00086 template <typename Val_T> 00087 inline void Sort (Val_T & a, Val_T & b, Val_T & c) 00088 { 00089 if (b<a) Util::Swap (a,b); 00090 if (c<b) Util::Swap (b,c); 00091 if (b<a) Util::Swap (a,b); 00092 } 00093 00095 template <typename Val_T> 00096 inline void Sort (Val_T & a, Val_T & b, Val_T & c, Val_T & d) 00097 { 00098 if (b<a) Util::Swap (b,a); 00099 if (c<b) Util::Swap (c,b); 00100 if (d<c) Util::Swap (d,c); 00101 if (b<a) Util::Swap (b,a); 00102 if (c<b) Util::Swap (c,b); 00103 if (b<a) Util::Swap (b,a); 00104 } 00105 00107 inline void FindBestSquare (int Size, int & nRow, int & nCol) 00108 { 00109 nRow = -1; // not found 00110 nCol = -1; // not found 00111 for (int x=1; x<=Size; ++x) 00112 { 00113 if ((x*x)>=Size) 00114 { 00115 if ((x*x)==Size) 00116 { 00117 nRow = x; 00118 nCol = x; 00119 return; 00120 } 00121 else 00122 { 00123 for (int y=x; y>=1; --y) 00124 { 00125 if ((x*y)==Size) 00126 { 00127 nRow = x; 00128 nCol = y; 00129 return; 00130 } 00131 } 00132 } 00133 } 00134 } 00135 } 00136 00137 struct FmtErr 00138 { 00139 FmtErr (double TheError, double TheTol, char const * TheFmt="%g") : Error(TheError), Tol(TheTol), Fmt(TheFmt) {} 00140 double Error; 00141 double Tol; 00142 String Fmt; 00143 }; 00144 00145 std::ostream & operator<< (std::ostream & os, FmtErr const & P) 00146 { 00147 String str; 00148 str.Printf (P.Fmt.CStr(), P.Error); 00149 os << (P.Error>P.Tol ? "[1;31m" : "[1;32m") << str << "[0m"; 00150 return os; 00151 } 00152 00153 inline bool FileExists (String const & Filename) 00154 { 00155 std::ifstream file(Filename.CStr(), std::ios::in); 00156 if (file.fail()) return false; 00157 else 00158 { 00159 file.close(); 00160 return true; 00161 } 00162 } 00163 00164 inline bool HasKey (String const & KeysSepBySpace, String const & Key) 00165 { 00166 std::istringstream iss(KeysSepBySpace); 00167 String key; 00168 bool has_key = false; 00169 while (iss>>key && !has_key) has_key = (key==Key); 00170 return has_key; 00171 } 00172 00173 inline void Keys2Array (String const & KeysSepBySpace, Array<String> & Keys) 00174 { 00175 std::istringstream iss(KeysSepBySpace); 00176 String key; 00177 while (iss>>key) Keys.Push (key); 00178 } 00179 00180 00181 #ifdef USE_BOOST_PYTHON 00182 00183 inline BPy::tuple PyFindBestSquare (int Size) 00184 { 00185 int row, col; 00186 FindBestSquare (Size, row, col); 00187 return BPy::make_tuple (row, col); 00188 } 00189 00190 inline void GetPyMethod (char const * ClassName, char const * MethodName, BPy::object & Method, char const * Filename="__main__") 00191 { 00192 try 00193 { 00194 BPy::object main_module((BPy::handle<>(BPy::borrowed(PyImport_AddModule("__main__"))))); 00195 BPy::object main_namespace = main_module.attr("__dict__"); 00196 if (strcmp(Filename,"__main__")!=0) 00197 { 00198 if (!FileExists(Filename)) throw new Fatal("Util::GetPyMethod: Could not file named %s",Filename); 00199 BPy::exec_file (Filename, main_namespace, main_namespace); 00200 } 00201 BPy::object py_class = BPy::extract<BPy::object>(main_namespace[ClassName])(); 00202 BPy::object class_namespace = py_class.attr("__dict__"); 00203 Method = BPy::extract<BPy::object>(class_namespace[MethodName])(); 00204 } 00205 catch (BPy::error_already_set const & Err) 00206 { 00207 printf("\n%sUtil::GetPyMethod: Could not get method=='%s' of class=='%s' in '__main__'\nPython error message: ",TERM_CLR_RED_H,MethodName,ClassName); 00208 PyErr_Print(); 00209 printf("%s\n",TERM_RST); 00210 throw new Fatal("PyODESolver::Init: failed (see message above)."); 00211 } 00212 } 00213 00214 inline void GetPyMethod (char const * InstanceName, char const * ClassName, char const * MethodName, BPy::object & Instance, BPy::object & Method, char const * Filename="__main__") 00215 { 00216 try 00217 { 00218 BPy::object main_module((BPy::handle<>(BPy::borrowed(PyImport_AddModule("__main__"))))); 00219 BPy::object main_namespace = main_module.attr("__dict__"); 00220 if (strcmp(Filename,"__main__")!=0) 00221 { 00222 if (!FileExists(Filename)) throw new Fatal("Util::GetPyMethod: Could not file named %s",Filename); 00223 BPy::exec_file (Filename, main_namespace, main_namespace); 00224 } 00225 Instance = BPy::extract<BPy::object>(main_namespace[InstanceName])(); 00226 BPy::object py_class = BPy::extract<BPy::object>(main_namespace[ClassName])(); 00227 BPy::object class_namespace = py_class.attr("__dict__"); 00228 Method = BPy::extract<BPy::object>(class_namespace[MethodName])(); 00229 } 00230 catch (BPy::error_already_set const & Err) 00231 { 00232 printf("\n%sUtil::GetPyMethod: Could not get method=='%s' of object=='%s' (class=='%s') in '__main__'\nPython error message: ",TERM_CLR_RED_H,MethodName,InstanceName,ClassName); 00233 PyErr_Print(); 00234 printf("%s\n",TERM_RST); 00235 throw new Fatal("PyODESolver::Init: failed (see message above)."); 00236 } 00237 } 00238 00239 #endif 00240 00241 00242 }; // namespace Util 00243 00244 #endif // MECHSYS_SORT_H