00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef TOOLS_H
00027 #define TOOLS_H
00028
00029 #include <iostream>
00030 #include <string>
00031 #include <list>
00032 #include <vector>
00033 #include <sstream>
00034 #include <ctype.h>
00035 #include <cmath>
00036 #include <cfloat>
00037 #include <typeinfo>
00038 #include <algorithm>
00039 #include <cassert>
00040 #include <limits>
00041
00042 #include "tools_exceptions.h"
00043 #include "geometry_common.h"
00044
00045
00046
00047 namespace MyTools {
00054 vector <unsigned short> get_digits (unsigned long long n);
00055
00065 template <typename NumericType>
00066 const bool get_intersection(const std::vector < std::vector <NumericType> > &l1, const std::vector < std::vector <NumericType> > &l2, std::vector< NumericType > &intersection) {
00067
00068 double x1=l1[0][0];double y1=l1[0][1];
00069 double x2=l1[1][0];double y2=l1[1][1];
00070 double x3=l2[0][0];double y3=l2[0][1];
00071 double x4=l2[1][0];double y4=l2[1][1];
00072
00073 double denom=((y4-y3)*(x2-x1)-(x4-x3)*(y2-y1));
00074
00075 double x=DBL_MAX;
00076 double y=DBL_MAX;
00077
00078 if (denom==0.)
00079
00080 return false;
00081 double div_denom=1./denom;
00082
00083 double ua=((x4-x3)*(y1-y3)-(y4-y3)*(x1-x3))*div_denom;
00084
00085
00086 x=x1+ua*(x2-x1);
00087 y=y1+ua*(y2-y1);
00088
00089
00090 intersection.clear();
00091 intersection.push_back(static_cast<NumericType>(x));
00092 intersection.push_back(static_cast<NumericType>(y));
00093
00094 return true;
00095 }
00096
00104
00105
00106
00107
00108
00112 inline static bool is_big_endian(){
00113 short int word = 0x0001;
00114 char *byte = (char *) &word;
00115 return(byte[0] ? true : false);
00116 };
00121 inline static int get_endianness() {
00122 int i = 1;
00123 char *p = (char *)&i;
00124 return (p[0] == 1 ? 0 : 1);
00125 }
00131 inline void byte_swapper(unsigned char* b, int n) {
00132 register int i = 0;
00133 register int j = n-1;
00134 while (i<j) {
00135 std::swap(b[i], b[j]);
00136 i++, j--;
00137 }
00138 };
00139
00145 template<class T>
00146 inline static void byte_swap (T &nb) {
00147 byte_swapper((unsigned char*)(&nb),sizeof(nb));
00148 };
00149
00153 int string2int(const std::string &s) ;
00154 float string2float(const std::string &s) ;
00155 double string2double(const std::string &s) ;
00156 int char2int(const char &c);
00157 std::string char2string(const char &c);
00167 std::string int2string(const int &i, const int &nb_digit = -1) ;
00173 template<typename NumericType>
00174 std::string to_string( const NumericType & nb ) {
00175 std::ostringstream oss;
00176 oss << nb;
00177 return oss.str();
00178 }
00185 template<typename NumericType>
00186 NumericType to_num( const string &s_nb ) {
00187
00188 std::istringstream iss(s_nb);
00189 NumericType nb ;
00190 iss >> nb;
00191 return nb;
00192 }
00199 std::string to_bit( void* bit_field, const int size=1 );
00200
00206 template<typename T_out>
00207 T_out round(const double &x) {
00208 return static_cast<T_out>(x + 0.5);
00209 }
00216 double angle_2D(double* p1, double* p2);
00217
00218 const bool is_int(const std::string &s);
00219 const bool is_float( const std::string & s );
00220 const bool is_int(const char * start, const int sz);
00227 template<typename T>
00228 bool has_type( const std::string & str ) {
00229 std::istringstream iss( str );
00230 T val;
00231
00232 return ( iss >> val ) && ( iss.eof() );
00233 }
00234
00235 const int count( const std::string & elt, const std::string & s );
00236 const int count( const char elt, const std::string & s );
00237
00238 void remove_space(std::string &);
00245 string strip (const std::string &str, const char c = ' ');
00246
00254 template <class T>
00255 const long double avg_array(const T* array, const int& nb_val, const T& fill_value);
00256
00257 template <class T>
00258 T abs(const T& val=T(0)) {
00259 if (val<T(0)) return -val;
00260 else return val;
00261 }
00262
00263 template <class T>
00264 const long double avg_array(const T* array, const int& nb_val, const T& fill_value) {
00265 bool good_val_found=false;
00266 long double acc=0.;
00267 int nb_good_val=0;
00268 for (int i = 0 ; i<nb_val ; ++i)
00269 if (array[i]!=fill_value) {
00270 if (!good_val_found)
00271 good_val_found=true;
00272 acc+=static_cast<long double>(array[i]);
00273 ++nb_good_val;
00274 }
00275 if (good_val_found)
00276 return acc/static_cast<long double>(nb_good_val);
00277 else
00278 return -LDBL_MAX;
00279 }
00280
00287 template<typename T>
00288 bool gt_comparator ( T i, T j) { return ( i > j ); };
00295 template<typename T>
00296 T sum (const T &i, const T &j) { return i+j; }
00303 template<typename T>
00304 T prod (const T &i, const T &j) { return i * j; }
00310 template<typename T>
00311 T log_op (const T &i) { return log((double)(i)); }
00312
00316 class KeyComparator {
00317 public:
00319 string key;
00324 KeyComparator (const string & key) : key(key){};
00330 bool operator ()(pair <string, string> const& key_val) const {
00331 return key_val.first == key;
00332 }
00333 };
00337 template <class T>
00338 class NotEqualComparator {
00339 public:
00341 T val;
00346 NotEqualComparator (const T &val) : val(val){};
00352 bool operator ()(const T ignored_val) const {
00353 return val != ignored_val;
00354 }
00355 };
00363 template<typename T>
00364 double get_abscissa ( const T val, const vector < T > & vec ) {
00365 return get_abscissa ( val, vec.begin(), vec.size() );
00366 };
00367
00376 template<typename T>
00377 double get_abscissa ( const T val, const T * v_abs, const int n_abs ) {
00378 double invalid = numeric_limits<double>::signaling_NaN();
00379 if ( n_abs <= 1 )
00380 return invalid;
00381
00382
00383 T * v_abs_begin = const_cast < T * > ( v_abs );
00384 T * v_abs_end = v_abs_begin + n_abs;
00385
00386 bool is_ascending_order = ( v_abs [1] > v_abs [0] );
00387 T * it = v_abs_begin;
00388
00389 if ( is_ascending_order ) {
00390 it = lower_bound ( v_abs_begin, v_abs_end, val );
00391 } else {
00392 it = lower_bound ( v_abs_begin, v_abs_end, val, gt_comparator < T > );
00393 }
00394
00395 if ( it == v_abs_begin || it == v_abs_end )
00396 return invalid;
00397
00398 size_t ilow = ( it - 1 ) - v_abs;
00399 T lower_bound = * ( it - 1 );
00400 T upper_bound = * ( it );
00401
00402 return ilow + ( val - lower_bound ) / ( upper_bound - lower_bound );
00403 };
00413 template <typename Txout, typename Tyout, typename Txin>
00414 void get_abscissa_sequential (Tyout * y_out, const Txout * x_out, const int sz_out, const Txin * x_in, const int sz_in) {
00415
00416 bool is_asc = ( x_in [1] > x_in [0] );
00417
00418
00419 Tyout nan = numeric_limits<Tyout>::signaling_NaN();
00420 int j;
00421 for (int i = 0 ; i < sz_out ; ++i) {
00422 j = 0;
00423 while ((j < (sz_in - 1)) &&
00424 (( is_asc && (x_out[i] > x_in [j+1])) ||
00425 (! is_asc && (x_out[i] < x_in [j+1]))
00426 ))
00427 ++j;
00428 if (j >= (sz_in - 1) || isnan (x_out[i]))
00429 y_out [i] = nan;
00430 else {
00431 y_out [i] = j + (x_out[i] - x_in [j]) / (x_in [j+1] - x_in [j]);
00432 }
00433 }
00434 }
00435
00445 template <typename Txout, typename Tyout, typename Txin>
00446 void get_log_abscissa_sequential (Tyout * y_out, const Txout * x_out, const int sz_out, const Txin * x_in, const int sz_in) {
00447
00448 double x_out_log[sz_out];
00449 for (int i = 0 ; i < sz_out ; ++i )
00450 x_out_log [i] = log(double(x_out[i]));
00451
00452
00453 double x_in_log [sz_in];
00454 for (int i = 0 ; i < sz_in ; ++i )
00455 x_in_log [i] = log((double)(x_in[i]));
00456
00457 get_abscissa_sequential (y_out, x_out_log, sz_out, x_in_log, sz_in);
00458 }
00459
00467 template<typename T>
00468 vector <T> arange (const T &val_min, const T &val_max, const T &inc = (T)(1));
00476 template<typename T>
00477 void arange (vector <T> & v, const T &val_min, const T &val_max, const T &inc = (T)(1));
00483 template<typename T>
00484 void push_back (const vector <T> & v_in, vector <T> & v_out);
00485
00491 template <typename T>
00492 std::string vec2str (const T * vec, const size_t sz) {
00493 std::ostringstream oss;
00494 oss << "[";
00495 for (size_t i = 0 ; i < sz ; ++i) {
00496 oss << vec[i];
00497 if (i < (sz - 1))
00498 oss << ", ";
00499 }
00500 oss << "]";
00501 return oss.str();
00502 };
00508 template <typename T>
00509 std::string vec2str ( const vector <T> & vec ) {
00510 return vec2str ((T*)(&vec[0]), vec.size());
00511 };
00517 template <typename T>
00518 void print_vec ( const T * vec, const size_t sz ) {
00519 cout << vec2str(vec, sz) << endl;
00520 };
00525 template <typename T>
00526 void print_vec ( const vector <T> & vec ) {
00527 print_vec ((T*)(&vec[0]), vec.size());
00528 };
00529 };
00530
00531 template<typename T>
00532 void MyTools::push_back(const std::vector<T> & v_in, std::vector<T> & v_out) {
00533 if (! v_in.empty()) {
00534 v_out.reserve (v_out.size() + v_in.size());
00535 for (typename std::vector<T>::const_iterator it = v_in.begin() ; it != v_in.end() ; ++it)
00536 v_out.push_back(*it);
00537 }
00538 };
00539
00540 template<typename T>
00541 vector< T > MyTools::arange(const T & val_min, const T & val_max, const T & inc) {
00542 vector <T> v(0);
00543 arange (v, val_min, val_max, inc);
00544 return v;
00545 }
00546
00547 template<typename T>
00548 void MyTools::arange(vector< T > & v, const T & val_min, const T & val_max, const T & inc) {
00549 v.clear();
00550 size_t sz = (size_t)((val_max - val_min) / inc);
00551 v.reserve (sz);
00552 for (T val = val_min ; val < val_max ; val = (T)(val + inc))
00553 v.push_back (val);
00554 }
00555
00556 #endif