MechSys  1.0
Computing library for simulations in continuum and discrete mechanics
/home/dorival/mechsys/lib/util/util.h
Go to the documentation of this file.
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 ? "" : "") << str << "";
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines