OpenMS
MathFunctions.h
Go to the documentation of this file.
1 // Copyright (c) 2002-2023, 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 
11 #include <OpenMS/CONCEPT/Types.h>
13 #include <OpenMS/CONCEPT/Macros.h>
14 
15 #include <boost/random/mersenne_twister.hpp> // for mt19937_64
16 #include <boost/random/uniform_int.hpp>
17 #include <cmath>
18 #include <utility> // for std::pair
19 
20 namespace OpenMS
21 {
29  namespace Math
30  {
31 
40  template<typename T>
41  bool extendRange(T& min, T& max, const T& value)
42  {
43  if (value < min)
44  {
45  min = value;
46  return true;
47  }
48  if (value > max)
49  {
50  max = value;
51  return true;
52  }
53  return false;
54  }
55 
61  template<typename T>
62  bool contains(T value, T min, T max)
63  {
64  return min <= value && value <= max;
65  }
66 
87  inline std::pair<double,double> zoomIn(const double left, const double right, const float factor, const float align)
88  {
89  OPENMS_PRECONDITION(factor >= 0, "Factor must be >=0")
90  OPENMS_PRECONDITION(align >= 0, "align must be >=0")
91  OPENMS_PRECONDITION(align <= 1, "align must be <=1")
92  std::pair<double, double> res;
93  auto old_width = right - left;
94  auto offset_left = (1.0f - factor) * old_width * align;
95  res.first = left + offset_left;
96  res.second = res.first + old_width * factor;
97  return res;
98  }
99 
111  inline double ceilDecimal(double x, int decPow)
112  {
113  return (ceil(x / pow(10.0, decPow))) * pow(10.0, decPow); // decimal shift right, ceiling, decimal shift left
114  }
115 
126  inline double roundDecimal(double x, int decPow)
127  {
128  if (x > 0)
129  return (floor(0.5 + x / pow(10.0, decPow))) * pow(10.0, decPow);
130 
131  return -((floor(0.5 + fabs(x) / pow(10.0, decPow))) * pow(10.0, decPow));
132  }
133 
139  inline double intervalTransformation(double x, double left1, double right1, double left2, double right2)
140  {
141  return left2 + (x - left1) * (right2 - left2) / (right1 - left1);
142  }
143 
151  inline double linear2log(double x)
152  {
153  return log10(x + 1); //+1 to avoid negative logarithms
154  }
155 
163  inline double log2linear(double x)
164  {
165  return pow(10, x) - 1;
166  }
167 
173  inline bool isOdd(UInt x)
174  {
175  return (x & 1) != 0;
176  }
177 
183  template <typename T>
184  T round(T x)
185  {
186  if (x >= T(0))
187  {
188  return T(floor(x + T(0.5)));
189  }
190  else
191  {
192  return T(ceil(x - T(0.5)));
193  }
194  }
195 
201  inline bool approximatelyEqual(double a, double b, double tol)
202  {
203  return std::fabs(a - b) <= tol;
204  }
205 
214  template <typename T>
215  T gcd(T a, T b)
216  {
217  T c;
218  while (b != 0)
219  {
220  c = a % b;
221  a = b;
222  b = c;
223  }
224  return a;
225  }
226 
239  template <typename T>
240  T gcd(T a, T b, T & u1, T & u2)
241  {
242  u1 = 1;
243  u2 = 0;
244  T u3 = a;
245 
246  T v1 = 0;
247  T v2 = 1;
248  T v3 = b;
249 
250  while (v3 != 0)
251  {
252  T q = u3 / v3;
253  T t1 = u1 - v1 * q;
254  T t2 = u2 - v2 * q;
255  T t3 = u3 - v3 * q;
256 
257  u1 = v1;
258  u2 = v2;
259  u3 = v3;
260 
261  v1 = t1;
262  v2 = t2;
263  v3 = t3;
264  }
265 
266  return u3;
267  }
268 
278  template <typename T>
279  T getPPM(T mz_obs, T mz_ref)
280  {
281  return (mz_obs - mz_ref) / mz_ref * 1e6;
282  }
283 
293  template <typename T>
294  T getPPMAbs(T mz_obs, T mz_ref)
295  {
296  return std::fabs(getPPM(mz_obs, mz_ref));
297  }
298 
308  template <typename T>
309  T ppmToMass(T ppm, T mz_ref)
310  {
311  return (ppm / T(1e6)) * mz_ref;
312  }
313 
314  /*
315  @brief Compute the absolute mass diff in [Th], given a ppm value and a reference point.
316 
317  The returned mass diff is always positive!
318 
319  @param ppm Parts-per-million error
320  @param mz_ref Reference m/z
321  @return The absolute mass diff in [Th]
322  */
323  template <typename T>
324  T ppmToMassAbs(T ppm, T mz_ref)
325  {
326  return std::fabs(ppmToMass(ppm, mz_ref));
327  }
328 
342  inline std::pair<double, double> getTolWindow(double val, double tol, bool ppm)
343  {
344  double left, right;
345 
346  if (ppm)
347  {
348  left = val - val * tol * 1e-6;
349  right = val / (1.0 - tol * 1e-6);
350  }
351  else
352  {
353  left = val - tol;
354  right = val + tol;
355  }
356 
357  return std::make_pair(left, right);
358  }
359 
363  template <typename T1> typename T1::value_type quantile(const T1 &x, double q)
364  {
365  if (x.empty()) throw Exception::InvalidParameter(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION,
366  "Quantile requested from empty container.");
367  if (q < 0.0) q = 0.;
368  if (q > 1.0) q = 1.;
369 
370  const auto n = x.size();
371  const auto id = std::max(0., n * q - 1); // -1 for c++ index starting at 0
372  const auto lo = floor(id);
373  const auto hi = ceil(id);
374  const auto qs = x[lo];
375  const auto h = (id - lo);
376 
377  return (1.0 - h) * qs + h * x[hi];
378  }
379 
380  // portable random shuffle
381  class OPENMS_DLLAPI RandomShuffler
382  {
383  public:
384  explicit RandomShuffler(int seed):
385  rng_(boost::mt19937_64(seed))
386  {}
387 
388  explicit RandomShuffler(const boost::mt19937_64& mt_rng):
389  rng_(mt_rng)
390  {}
391 
392  RandomShuffler() = default;
393  ~RandomShuffler() = default;
394 
395  boost::mt19937_64 rng_;
396  template <class RandomAccessIterator>
397  void portable_random_shuffle (RandomAccessIterator first, RandomAccessIterator last)
398  {
399  for (auto i = (last-first)-1; i > 0; --i) // OMS_CODING_TEST_EXCLUDE
400  {
401  boost::uniform_int<decltype(i)> d(0, i);
402  std::swap(first[i], first[d(rng_)]);
403  }
404  }
405 
406  void seed(uint64_t val)
407  {
408  rng_.seed(val);
409  }
410  };
411  } // namespace Math
412 } // namespace OpenMS
413 
Exception indicating that an invalid parameter was handed over to an algorithm.
Definition: Exception.h:315
Definition: MathFunctions.h:382
RandomShuffler(int seed)
Definition: MathFunctions.h:384
boost::mt19937_64 rng_
Definition: MathFunctions.h:395
void seed(uint64_t val)
Definition: MathFunctions.h:406
RandomShuffler(const boost::mt19937_64 &mt_rng)
Definition: MathFunctions.h:388
void portable_random_shuffle(RandomAccessIterator first, RandomAccessIterator last)
Definition: MathFunctions.h:397
unsigned int UInt
Unsigned integer type.
Definition: Types.h:68
#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:215
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:139
double linear2log(double x)
Transforms a number from linear to log10 scale. Avoids negative logarithms by adding 1.
Definition: MathFunctions.h:151
T round(T x)
Rounds the value.
Definition: MathFunctions.h:184
double log2linear(double x)
Transforms a number from log10 to to linear scale. Subtracts the 1 added by linear2log(double)
Definition: MathFunctions.h:163
double ceilDecimal(double x, int decPow)
rounds x up to the next decimal power 10 ^ decPow
Definition: MathFunctions.h:111
bool approximatelyEqual(double a, double b, double tol)
Returns if a is approximately equal b , allowing a tolerance of tol.
Definition: MathFunctions.h:201
double roundDecimal(double x, int decPow)
rounds x to the next decimal power 10 ^ decPow
Definition: MathFunctions.h:126
bool isOdd(UInt x)
Returns true if the given integer is odd.
Definition: MathFunctions.h:173
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:41
T getPPM(T mz_obs, T mz_ref)
Compute parts-per-million of two m/z values.
Definition: MathFunctions.h:279
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:363
T ppmToMass(T ppm, T mz_ref)
Compute the mass diff in [Th], given a ppm value and a reference point.
Definition: MathFunctions.h:309
bool contains(T value, T min, T max)
Is a value contained in [min, max] ?
Definition: MathFunctions.h:62
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:87
T getPPMAbs(T mz_obs, T mz_ref)
Compute absolute parts-per-million of two m/z values.
Definition: MathFunctions.h:294
T ppmToMassAbs(T ppm, T mz_ref)
Definition: MathFunctions.h:324
std::pair< double, double > getTolWindow(double val, double tol, bool ppm)
Return tolerance window around val given tolerance tol.
Definition: MathFunctions.h:342
Main OpenMS namespace.
Definition: FeatureDeconvolution.h:22