File: Utility.h

package info (click to toggle)
lammps 20220106.git7586adbb6a%2Bds1-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 348,064 kB
  • sloc: cpp: 831,421; python: 24,896; xml: 14,949; f90: 10,845; ansic: 7,967; sh: 4,226; perl: 4,064; fortran: 2,424; makefile: 1,501; objc: 238; lisp: 163; csh: 16; awk: 14; tcl: 6
file content (336 lines) | stat: -rw-r--r-- 10,276 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
#ifndef UTILITY_H
#define UTILITY_H

#include <iostream>
#include <ctime>
#include <limits>
#undef near

#include <vector>
#include <fstream>
#include <cstring>
#include <string>
#include <sstream>
#include <iomanip>
#include <algorithm>
#include <cmath>

#include "ATC_Error.h"

namespace ATC_Utility
{
  /** constants */
  static const double Pi_ = 4.0*atan(1.0);
  static const double Big_ = 1.e20;
  const static double parsetol_ = 1.0e-8;
  //const static double parsetol_ = 1.0e-10;
  const static double parsebig_ = 1.0e10;

  /** scalar triple product */
  inline double det3(double * v1, double * v2, double * v3) {
    return
     -v1[2]*v2[1]*v3[0] + v1[1]*v2[2]*v3[0] + v1[2]*v2[0]*v3[1]
     -v1[0]*v2[2]*v3[1] - v1[1]*v2[0]*v3[2] + v1[0]*v2[1]*v3[2];
  }
  inline void plane_coords(int i, int & i1, int & i2) {
    if      (i==0) { i1 = 1; i2 = 2; }
    else if (i==1) { i1 = 2; i2 = 0; }
    else if (i==2) { i1 = 0; i2 = 1; }
  }
  /** 2d cross product */
  inline double cross2(double * v1, double * v2) {
    return v1[0]*v2[1] - v1[1]*v2[0];
  }
  /** 3d cross product */
  inline void cross3(double * v1, double * v2, double * v) {
    v[0] = v1[1]*v2[2] - v1[2]*v2[1];
    v[1] = v1[2]*v2[0] - v1[0]*v2[3];
    v[2] = v1[0]*v2[1] - v1[1]*v2[0];
  }
  inline double norm3(double * v) {return sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]); }

  inline int sgn(double x) { return (int) ((x>0) - (x<0)); }
//  template <typename T> int sgn(T val) { return (T(0) < val) - (val < T(0)); }
  inline int rnd(double x) { return (int) (x+sgn(x)*0.5); }

  /** Compares doubles acceptably */
  inline bool dbl_geq(double dblL, double dblR, int tolMult=2)
  {
    return ( (dblL >   dblR) ||
            ((dblL <= (dblR + \
                       std::numeric_limits<double>::epsilon() * \
                       tolMult * std::max(fabs(dblL), fabs(dblR)))) &&
             (dblR <= (dblL + \
                       std::numeric_limits<double>::epsilon() * \
                       tolMult * std::max(fabs(dblL), fabs(dblR))))));
  }

  inline double tolerance(double x, double tol = parsetol_) {
    return std::max(tol,tol*fabs(x));
  }
  inline double nudge_up(double x)   { return x+tolerance(x); }
  inline double nudge_down(double x) { return x-tolerance(x); }
  inline double parse_min(const char * arg) {
    if      (std::strcmp(arg,"INF") == 0)  return -parsebig_;
    else if (std::strcmp(arg,"-INF") == 0) return -parsebig_;
    else                                   return (atof(arg));
  }
  inline double parse_max(const char * arg) {
     if (std::strcmp(arg,"INF") == 0)  return parsebig_;
     else                              return (atof(arg));
  }
  inline double parse_minmax(const char * arg) {
    if      (std::strcmp(arg,"-INF") == 0)  return -parsebig_;
    else if (std::strcmp(arg,"INF") == 0)   return  parsebig_;
    else                         return atof(arg);
  }
  inline void split_values(double & min, double & max) {
    min = nudge_down(min);
    max = nudge_up(max);
  }


  /** Returns true if the value v is between min &  max */
  template<typename T>
  inline bool in_range(const T &v, const T &min, const T &max)
  {
    return v >= min && v <= max;
  }
  /** Returns true if the value v is between min & max within tolerance TOL */
  template<typename T>
  inline bool in_range(const T &v, const T &min, const T &max, const T &tol)
  {
    return in_range(v, min-tol, max+tol);
  }
  /** Returns the value with the larger absolute value */
  template<typename T>
  inline T max_abs(const T &a, const T &b)
  {
    return (a*a > b*b) ? a : b;
  }
  /** Returns the value with the smaller absolute value */
  template<typename T>
  inline T min_abs(const T &a, const T &b)
  {
    return (a*a < b*b) ? a : b;
  }
  /** A simple Matlab like timing function */
  inline double tictoc()
  {
    double t_new = clock() / (double) CLOCKS_PER_SEC;
    static double t = t_new;
    double dt = t_new - t;
    t = t_new;
    return dt;
  }
  /** A simple timer */
  inline double timer()
  {
    double t_new = clock() / (double) CLOCKS_PER_SEC;
    static double t = t_new; // done once at first time the function is evoked
    double dt = t_new - t;
    return dt;
  }
  /** Binary search between low & high for value (assumes array is sorted) */

  template<typename T>
  inline int search_sorted(const T* A, T value, int low, int high)
  {
    int mid;
    while (low < high)
    {
     mid = (low + high) >> 1;                 // set mid to mean of high and low, ">>" is a bit shift which divides by 2, rounding down
     if (A[mid] > value)       high = mid;  // mid was too high, reduce high
     else if (A[mid] < value)  low = mid+1;   // mid was too low, increase low
     else return mid;
    }
    return -1; // value not found in array, return -1
  }
  /** Flat search between low & high for value (assumes array is NOT sorted) */
  template<typename T>
  inline int search_unsorted(const T* A, T value, int low, int high)
  {
    for (int i=low; i<high; i++) if (A[i] == value) return i;
    return -1;
  }
  /** Regular swap */
  template<typename T>
  inline void swap(T &a, T &b)
  {
    T temp = a;
    a = b;
    b = temp;
  }


  //===================================================================
  /** A collection of string convesion/manipulation routines  */
  //===================================================================


  /** converts anything that has iostream::<< defined to a string  */
  template<typename T>
  inline std::string to_string(const T &v, int precision=0)
  {
    std::ostringstream out;
    if (precision) {
      out << std::setprecision(precision);
      out << std::setw(precision+3);
      out << std::showpoint;
    }
    out << v;
    out << std::noshowpoint;
    return out.str();
  }

  /** formatted double to a string  */
  inline std::string to_string(int precision, const double v)
  {
    char b[50];
    sprintf(b, "%*.*f",4+precision,precision, v);
    std::string s(b);
    return s;
  }

  /** conversion to string */
  inline std::string true_false(const double &v)
  {
    if (v) return "TRUE";
    else   return "FALSE";
  }

  /** test conversion to double */
  inline bool is_numeric(const std::string &s)
  {
    double v;
    std::istringstream in(s);
    in >> v;
    // in.good() == true indicates, that not the whole string was converted.
    return !(in.fail() || in.good());
  }

  /** convert a string to anything that has iostream::>> defined, second arg is to disambibuate type */
  template<typename T>
  inline T str2T(const std::string &s, T v)
  {
    std::istringstream in(s);
    if (!(in >> v)) throw ATC::ATC_Error("str2T invalid string conversion");
    return v;
  }

  /** convert a string to a double */
  inline double str2dbl(const std::string &s) { return str2T(s, double(0.0)); }

  /** tests if conversion to double is possible */
  inline bool is_dbl(const std::string &s)
  {
    char *endptr;
    strtod(s.c_str(), &endptr);
    if(endptr != nullptr && *endptr == '\0') return true;
    return false;
  }

  inline bool is_number(const std::string& s)
  {
    std::string::const_iterator it = s.begin();
    while (it != s.end() && std::isdigit(*it)) ++it;
    return !s.empty() && it == s.end();
  }

  /** convert a string to an int */
  inline int str2int(const std::string &s)    { return str2T(s, int(4)); }

  //* replaces all characters in a set of characters with a character
  //* @param str input string
  //* @param *s pointer to array of characters that will be replaced
  //* @param r character to replace characters in s[] with
  static void replace_all_of(std::string &str, const char *s, const char r)
  {
     size_t found;
     found = str.find_first_of(s);
     while (found != std::string::npos)
     {
        str[found] = r;
        found = str.find_first_of(s, found+1);
     }
  }

  /** converts the string to lowercase */
  inline std::string& to_lower(std::string &s)
  {
    std::transform(s.begin(),s.end(),s.begin(),static_cast<int(*)(int)>(tolower));
    return s;
  }

  /** converts the string to uppercase */
  inline std::string& to_upper(std::string &s)
  {
    std::transform(s.begin(),s.end(),s.begin(),static_cast<int(*)(int)>(toupper));
    return s;
  }

  /** removes any whitespace from the beginning or end of string */
  static std::string& trim(std::string &s)
  {
    if (s.empty()) return s;
    size_t found = s.find_last_not_of(" \t\n");
    if (found < s.size()-1) s.erase(found+1);
    found = s.find_first_not_of(" \t\n");
    if (found != std::string::npos) s = s.substr(found);
    return s;
  }

  /** splits delimited string into a vector of strings */
  static void split(const std::string &s, std::vector<std::string> &ss, char del=' ')
  {
    ss.clear();
    size_t begin=0, end=0;
    while (end != std::string::npos)
    {
      begin = s.find_first_not_of(del, end);     // find beginning of fragment
      end = s.find_first_of(del,begin);
      if (begin != std::string::npos)                 // safe if end is npos-1
        ss.push_back(s.substr(begin,end-begin));
    }
  }

  static std::string cap(std::string & s) {
    s[0] = toupper(s[0]);
    return s;
  }

  /* turns Aa_Bb_Cc into aa_bb_cc */
  static std::string to_cap(const std::string &s) {
    std::vector<std::string> words;
    std::string delimiter = "_";
    split(s,words,(delimiter.c_str())[0]);
    std::string name = "";
    for (unsigned int i = 0; i < words.size(); i++) {
      name = name + cap(words[i]);
    }
    return name;
  }

  //* scans a string for a list of commands delimited by ', \t' with # comments
  //* @param line The input line to be parsed
  //* @cs A vector of strings parsed from the input line
  static void command_strings(std::string line, std::vector<std::string> &cs)
  {
    if (line.find('#') != std::string::npos)  line.erase(line.find("#"));
    replace_all_of(line, "\t,", ' ');
    to_lower(trim(line));
    split(line, cs);
  }

  //* reads a single line from a file and splits it into a vector of strings
  //* returns the number of strings in the vector
  inline int command_line(std::fstream &fid, std::vector<std::string> &cs)
  {
     std::string line;
     getline(fid, line);
     command_strings(line, cs);
     return cs.size();
  }
}

#endif