C++ mpi module for stochmagnet_main Package
functions_numeric.h
1 #ifndef FUNCTIONS_NUMERIC_H
2 #define FUNCTIONS_NUMERIC_H
3 
4 //types of the code
5 #include "types.h"
6 #include "functions_type.h"
7 
8 //math header isnan
9 #include <math.h>
10 
11 namespace functions_numeric {
12 
13 
14 
15  //equal operators
16  //================
22  template<typename T>
23  inline tBoolean areEquals(const T& e1, const T& e2 )
24  { return (e1==e2) ; }
25 
33  template<>
34  inline tBoolean areEquals(const tReal& e1,const tReal& e2 ) {
35  return abs(e1-e2)<std::numeric_limits<tReal>::epsilon();
36  }
44  template<>
45  inline tBoolean areEquals(const tComplex& e1,const tComplex &e2 ) {
46  return abs(e1-e2)<std::numeric_limits<tReal>::epsilon();
47  }
48 
56  template<>
57  inline tBoolean areEquals(const tString& e1,const tString & e2 ) {
58  return (e1.compare(e2)==0);
59  }
60 
61 
62  //arithmetic type methods
63  //=======================
64 
69  template<typename T>
70  requires functions_type::isRealType<T>
71  inline tBoolean isNAN(const T& s) {
72  return std::isnan(s);
73  }
74 
79  inline tBoolean isInteger(const tString& s) {
80  char* p;
81  strtol(s.c_str(), &p, 10);
82  if (*p) {
83  // conversion failed because the input wasn't a number
84  return false;
85  }
86  else {
87  // use converted
88  return true;
89  }
90  }
95  inline tBoolean isNumeric(const tString& s) {
96  char* p;
97  strtod(s.c_str(), &p);
98  if (*p) {
99  // conversion failed because the input wasn't a number
100  return false;
101  }
102  else {
103  // use converted
104  return true;
105  }
106  }
111  inline tBoolean isString(const tString& s) {
112  return ( (!isInteger(s)) && (!isNumeric(s)));
113  }
114 
115 
116 
117 
118  //arithmetic type
119  //===============
120 
121  //arithmetic bounds
122  //=================
123 
124  /* \brief get min epsilon
125  * @return the minimum positive significant value
126  */
127  template<class T>
128  requires functions_type::isArithmeticType<T>
129  inline static T getEpsilon() {
130  return std::numeric_limits<T>::epsilon();
131  }
132  /* \brief get infinity value
133  * @return the infinity value
134  */
135  template<class T>
136  requires functions_type::isArithmeticType<T>
137  inline static T getInfinity() {
138  return std::numeric_limits<T>::infinity();
139  }
140  /* \brief get min epsilon
141  * @return the minimum positive significant value
142  */
143  template<class T>
144  requires functions_type::isArithmeticType<T>
145  inline static T getEpsilonValue() {
146  return std::numeric_limits<T>::epsilon();
147  }
148  /* \brief get infinity value
149  * @return the infinity value
150  */
151  template<class T>
152  requires functions_type::isArithmeticType<T>
153  inline static T getInfinityValue() {
154  return std::numeric_limits<T>::infinity();
155  }
156  /* \brief get max value
157  * @return the maximum positive value
158  */
159  template<class T>
160  requires functions_type::isIntegerType<T>
161  inline static T getMax() {
162  return std::numeric_limits<T>::max();
163  }
164  /* \brief get min value
165  * @return the minimum positive value
166  */
167  template<class T>
168  requires functions_type::isIntegerType<T>
169  inline static T getMin() {
170  return std::numeric_limits<T>::min();
171  }
172  /* \brief get max value
173  * @return the maximum positive value
174  */
175  template<class T>
176  requires functions_type::isIntegerType<T>
177  inline static T getMaxValue() {
178  return std::numeric_limits<T>::max();
179  }
180  /* \brief get min value
181  * @return the minimum positive value
182  */
183  template<class T>
184  requires functions_type::isIntegerType<T>
185  inline static T getMinValue() {
186  return std::numeric_limits<T>::min();
187  }
188 
189 
190  //arithmetic scalar methods
191  //=========================
192 
193 
199  template<typename T>
200  requires functions_type::isArithmeticType<T>
201  inline const T& min(const T& a,const T&b) {
202  return (a<b)?a:b;
203  }
209  template<typename T>
210  requires functions_type::isArithmeticType<T>
211  inline const T& max(const T& a,const T&b) {
212  return (a>b)?a:b;
213  }
214 
218  template<typename Q,tUCInt N,tUCInt i> requires (i==N)
219  inline Q levelPow(const Q& x) {
220  return x;
221  }
225  template<typename Q,tUCInt N,tUCInt i> requires (i<N)
226  inline Q levelPow(const Q& x) {
227  return x*levelPow<Q,N,i+1>(x);
228  }
229 
233  template<typename Q,tUCInt N>
234  inline Q pow(const Q& x) {
235  return levelPow<Q,N,1>(x);
236  }
237 
238 
239 
243  template<typename T,std::enable_if_t<std::is_integral_v<T>> * = nullptr>
244  inline tString toString(const T& v,const tUCInt& d) {
245  tString ret=std::to_string(v);
246  for (tUCInt k=ret.length();k<d;k++) {
247  ret="0"+ret;
248  }
249  return ret;
250  }
254  template<typename T,std::enable_if_t<std::is_arithmetic_v<T>> * = nullptr>
255  inline tString toString(const T& v) {
256  std::stringstream sv;
257  sv<<v;
258  return sv.str();
259  }
260 
261 
265  inline tString booleanToString(const tBoolean& v) {
266  return (v)?"true":"false";
267  }
268 
273  template<typename T>
274  inline void parse(const tString& s,T& v) {
275  std::stringstream ss;
276  ss<<s;
277  ss>>v;
278  }
283  template<>
284  inline void parse(const tString& s,tBoolean& v) {
285  v=false;
286  switch (s[0]) {
287  case '1':
288  case 't':
289  case 'T':
290  v=true;
291  }
292  }
293 
294 
295 
296  //quick search
297  //============
298 
299 
307  template<typename Q> requires functions_type::isArithmeticType<Q>
308  tIndex quickSearch(const Q& v,
309  const tIndex& n,
310  const Q* values,
311  tBoolean& isFound) {
312 
313  //return index
314  tIndex k;
315 
316  //range of search in array
317  tIndex k0=0;
318  tIndex k1=n;
319 
320  //current value
321  Q currentValue;
322 
323 
324  //range is empty
325  if (k0==k1) {
326 
327  isFound=false;
328  return k0;
329  }
330 
331  //last included index
332  k1--;
333 
334  //min value
335  k=k0;
336  currentValue=values[k];
337 
338  if (v<currentValue) {
339  //no values : return the index of the array greater than v
340  isFound=false;
341  return k;
342  }
343  if (v==currentValue) {
344  isFound=true;
345  return k;
346  }
347 
348  //max value
349  k=k1;
350  currentValue=values[k];
351 
352  if (v>currentValue) {
353  //no values : return the index of the array less than v
354  isFound=false;
355  return k;
356  }
357  if (v==currentValue) {
358  isFound=true;
359  return k;
360  }
361 
362 
363 
364  //quick sort search
365  do {
366  k=(k0+k1)/2;
367  currentValue=values[k];
368  if (v==currentValue) {
369  isFound=true;
370  return k;
371  }
372  if (v<currentValue) k1=k;
373  else k0=k;
374  } while (k1-k0>1);
375 
376  //k1-k0=1
377  //ib>=mRows[k0]
378  //ib<mRows[k1]
379  if (values[k0]==v) {
380  isFound=true;
381  return k0;
382  }
383 
384  if (values[k1]==v) {
385  isFound=true;
386  return k1;
387  }
388  //no values : return the index of the array greater than v
389  isFound=false;
390  return k1;
391  }//end method uickSearch
392 
393 }
394 
395 #endif