OpenMS
MathFunctions.h
Go to the documentation of this file.
1 // Copyright (c) 2002-present, The OpenMS Team -- EKU Tuebingen, ETH Zurich, and FU Berlin
2 // SPDX-License-Identifier: BSD-3-Clause
3 //
4 // --------------------------------------------------------------------------
5 // $Maintainer: Timo Sachsenberg$
6 // $Authors: Marc Sturm $
7 // --------------------------------------------------------------------------
8 
9 #pragma once
10 
12 #include <OpenMS/CONCEPT/Macros.h>
13 #include <OpenMS/CONCEPT/Types.h>
14 #include <boost/random/mersenne_twister.hpp> // for mt19937_64
15 #include <boost/random/uniform_int.hpp>
16 #include <cmath>
17 #include <utility> // for std::pair
18 
19 namespace OpenMS
20 {
28 namespace Math
29 {
30 
39  template<typename T>
40  bool extendRange(T& min, T& max, const T& value)
41  {
42  if (value < min)
43  {
44  min = value;
45  return true;
46  }
47  if (value > max)
48  {
49  max = value;
50  return true;
51  }
52  return false;
53  }
54 
60  template<typename T>
61  bool contains(T value, T min, T max)
62  {
63  return min <= value && value <= max;
64  }
65 
86  inline std::pair<double, double> zoomIn(const double left, const double right, const float factor, const float align)
87  {
88  OPENMS_PRECONDITION(factor >= 0, "Factor must be >=0")
89  OPENMS_PRECONDITION(align >= 0, "align must be >=0")
90  OPENMS_PRECONDITION(align <= 1, "align must be <=1")
91  std::pair<double, double> res;
92  auto old_width = right - left;
93  auto offset_left = (1.0f - factor) * old_width * align;
94  res.first = left + offset_left;
95  res.second = res.first + old_width * factor;
96  return res;
97  }
98 
110  inline double ceilDecimal(double x, int decPow)
111  {
112  return (ceil(x / pow(10.0, decPow))) * pow(10.0, decPow); // decimal shift right, ceiling, decimal shift left
113  }
114 
125  inline double roundDecimal(double x, int decPow)
126  {
127  if (x > 0) return (floor(0.5 + x / pow(10.0, decPow))) * pow(10.0, decPow);
128 
129  return -((floor(0.5 + fabs(x) / pow(10.0, decPow))) * pow(10.0, decPow));
130  }
131 
137  inline double intervalTransformation(double x, double left1, double right1, double left2, double right2)
138  {
139  return left2 + (x - left1) * (right2 - left2) / (right1 - left1);
140  }
141 
149  inline double linear2log(double x)
150  {
151  return log10(x + 1); //+1 to avoid negative logarithms
152  }
153 
161  inline double log2linear(double x)
162  {
163  return pow(10, x) - 1;
164  }
165 
171  inline bool isOdd(UInt x)
172  {
173  return (x & 1) != 0;
174  }
175 
181  template<typename T>
182  T round(T x)
183  {
184  if (x >= T(0)) { return T(floor(x + T(0.5))); }
185  else { return T(ceil(x - T(0.5))); }
186  }
187 
193  inline bool approximatelyEqual(double a, double b, double tol)
194  {
195  return std::fabs(a - b) <= tol;
196  }
197 
206  template<typename T>
207  T gcd(T a, T b)
208  {
209  T c;
210  while (b != 0)
211  {
212  c = a % b;
213  a = b;
214  b = c;
215  }
216  return a;
217  }
218 
231  template<typename T>
232  T gcd(T a, T b, T& u1, T& u2)
233  {
234  u1 = 1;
235  u2 = 0;
236  T u3 = a;
237 
238  T v1 = 0;
239  T v2 = 1;
240  T v3 = b;
241 
242  while (v3 != 0)
243  {
244  T q = u3 / v3;
245  T t1 = u1 - v1 * q;
246  T t2 = u2 - v2 * q;
247  T t3 = u3 - v3 * q;
248 
249  u1 = v1;
250  u2 = v2;
251  u3 = v3;
252 
253  v1 = t1;
254  v2 = t2;
255  v3 = t3;
256  }
257 
258  return u3;
259  }
260 
270  template<typename T>
271  T getPPM(T mz_obs, T mz_ref)
272  {
273  return (mz_obs - mz_ref) / mz_ref * 1e6;
274  }
275 
285  template<typename T>
286  T getPPMAbs(T mz_obs, T mz_ref)
287  {
288  return std::fabs(getPPM(mz_obs, mz_ref));
289  }
290 
300  template<typename T>
301  T ppmToMass(T ppm, T mz_ref)
302  {
303  return (ppm / T(1e6)) * mz_ref;
304  }
305 
306  /*
307  @brief Compute the absolute mass diff in [Th], given a ppm value and a reference point.
308 
309  The returned mass diff is always positive!
310 
311  @param ppm Parts-per-million error
312  @param mz_ref Reference m/z
313  @return The absolute mass diff in [Th]
314  */
315  template<typename T>
316  T ppmToMassAbs(T ppm, T mz_ref)
317  {
318  return std::fabs(ppmToMass(ppm, mz_ref));
319  }
320 
334  inline std::pair<double, double> getTolWindow(double val, double tol, bool ppm)
335  {
336  double left, right;
337 
338  if (ppm)
339  {
340  left = val - val * tol * 1e-6;
341  right = val / (1.0 - tol * 1e-6);
342  }
343  else
344  {
345  left = val - tol;
346  right = val + tol;
347  }
348 
349  return std::make_pair(left, right);
350  }
351 
355  template<typename T1>
356  typename T1::value_type quantile(const T1& x, double q)
357  {
358  if (x.empty()) throw Exception::InvalidParameter(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, "Quantile requested from empty container.");
359  if (q < 0.0) q = 0.;
360  if (q > 1.0) q = 1.;
361 
362  const auto n = x.size();
363  const auto id = std::max(0., n * q - 1); // -1 for c++ index starting at 0
364  const auto lo = floor(id);
365  const auto hi = ceil(id);
366  const auto qs = x[lo];
367  const auto h = (id - lo);
368 
369  return (1.0 - h) * qs + h * x[hi];
370  }
371 
372  // portable random shuffle
373  class OPENMS_DLLAPI RandomShuffler
374  {
375  public:
376  explicit RandomShuffler(int seed): rng_(boost::mt19937_64(seed))
377  {
378  }
379 
380  explicit RandomShuffler(const boost::mt19937_64& mt_rng): rng_(mt_rng)
381  {
382  }
383 
384  RandomShuffler() = default;
385  ~RandomShuffler() = default;
386 
387  boost::mt19937_64 rng_;
388  template<class RandomAccessIterator>
389  void portable_random_shuffle(RandomAccessIterator first, RandomAccessIterator last)
390  {
391  for (auto i = (last - first) - 1; i > 0; --i) // OMS_CODING_TEST_EXCLUDE
392  {
393  boost::uniform_int<decltype(i)> d(0, i);
394  std::swap(first[i], first[d(rng_)]);
395  }
396  }
397 
398  void seed(uint64_t val)
399  {
400  rng_.seed(val);
401  }
402  };
403 } // namespace Math
404 } // namespace OpenMS
Exception indicating that an invalid parameter was handed over to an algorithm.
Definition: Exception.h:299
Definition: MathFunctions.h:374
RandomShuffler(int seed)
Definition: MathFunctions.h:376
boost::mt19937_64 rng_
Definition: MathFunctions.h:387
void seed(uint64_t val)
Definition: MathFunctions.h:398
RandomShuffler(const boost::mt19937_64 &mt_rng)
Definition: MathFunctions.h:380
void portable_random_shuffle(RandomAccessIterator first, RandomAccessIterator last)
Definition: MathFunctions.h:389
unsigned int UInt
Unsigned integer type.
Definition: Types.h:64
#define OPENMS_PRECONDITION(condition, message)
Precondition macro.
Definition: openms/include/OpenMS/CONCEPT/Macros.h:94
T gcd(T a, T b)
Returns the greatest common divisor (gcd) of two numbers by applying the Euclidean algorithm.
Definition: MathFunctions.h:207
double intervalTransformation(double x, double left1, double right1, double left2, double right2)
transforms point x of interval [left1,right1] into interval [left2,right2]
Definition: MathFunctions.h:137
double linear2log(double x)
Transforms a number from linear to log10 scale. Avoids negative logarithms by adding 1.
Definition: MathFunctions.h:149
T round(T x)
Rounds the value.
Definition: MathFunctions.h:182
double log2linear(double x)
Transforms a number from log10 to to linear scale. Subtracts the 1 added by linear2log(double)
Definition: MathFunctions.h:161
double ceilDecimal(double x, int decPow)
rounds x up to the next decimal power 10 ^ decPow
Definition: MathFunctions.h:110
bool approximatelyEqual(double a, double b, double tol)
Returns if a is approximately equal b , allowing a tolerance of tol.
Definition: MathFunctions.h:193
double roundDecimal(double x, int decPow)
rounds x to the next decimal power 10 ^ decPow
Definition: MathFunctions.h:125
bool isOdd(UInt x)
Returns true if the given integer is odd.
Definition: MathFunctions.h:171
const double c
Definition: Constants.h:188
const double h
Definition: Constants.h:141
bool extendRange(T &min, T &max, const T &value)
Given an interval/range and a new value, extend the range to include the new value if needed.
Definition: MathFunctions.h:40
T getPPM(T mz_obs, T mz_ref)
Compute parts-per-million of two m/z values.
Definition: MathFunctions.h:271
T1::value_type quantile(const T1 &x, double q)
Returns the value of the q th quantile (0-1) in a sorted non-empty vector x.
Definition: MathFunctions.h:356
T ppmToMass(T ppm, T mz_ref)
Compute the mass diff in [Th], given a ppm value and a reference point.
Definition: MathFunctions.h:301
std::pair< double, double > zoomIn(const double left, const double right, const float factor, const float align)
Zoom into an interval [left, right], decreasing its width by factor (which must be in [0,...
Definition: MathFunctions.h:86
bool contains(T value, T min, T max)
Is a value contained in [min, max] ?
Definition: MathFunctions.h:61
T getPPMAbs(T mz_obs, T mz_ref)
Compute absolute parts-per-million of two m/z values.
Definition: MathFunctions.h:286
T ppmToMassAbs(T ppm, T mz_ref)
Definition: MathFunctions.h:316
std::pair< double, double > getTolWindow(double val, double tol, bool ppm)
Return tolerance window around val given tolerance tol.
Definition: MathFunctions.h:334
FLASHIda C++ to C# (or vice versa) bridge functions The functions here are called in C# to invoke fun...
Definition: openswathalgo/include/OpenMS/OPENSWATHALGO/DATAACCESS/ISpectrumAccess.h:19