OpenMS
MathFunctions.h
Go to the documentation of this file.
1 // --------------------------------------------------------------------------
2 // OpenMS -- Open-Source Mass Spectrometry
3 // --------------------------------------------------------------------------
4 // Copyright The OpenMS Team -- Eberhard Karls University Tuebingen,
5 // ETH Zurich, and Freie Universitaet Berlin 2002-2023.
6 //
7 // This software is released under a three-clause BSD license:
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright
11 // notice, this list of conditions and the following disclaimer in the
12 // documentation and/or other materials provided with the distribution.
13 // * Neither the name of any author or any participating institution
14 // may be used to endorse or promote products derived from this software
15 // without specific prior written permission.
16 // For a full list of authors, refer to the file AUTHORS.
17 // --------------------------------------------------------------------------
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 // ARE DISCLAIMED. IN NO EVENT SHALL ANY OF THE AUTHORS OR THE CONTRIBUTING
22 // INSTITUTIONS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25 // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27 // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28 // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 //
30 // --------------------------------------------------------------------------
31 // $Maintainer: Timo Sachsenberg$
32 // $Authors: Marc Sturm $
33 // --------------------------------------------------------------------------
34 
35 #pragma once
36 
37 #include <OpenMS/CONCEPT/Types.h>
39 #include <OpenMS/CONCEPT/Macros.h>
40 
41 #include <boost/random/mersenne_twister.hpp> // for mt19937_64
42 #include <boost/random/uniform_int.hpp>
43 #include <cmath>
44 #include <utility> // for std::pair
45 
46 namespace OpenMS
47 {
55  namespace Math
56  {
57 
66  template<typename T>
67  bool extendRange(T& min, T& max, const T& value)
68  {
69  if (value < min)
70  {
71  min = value;
72  return true;
73  }
74  if (value > max)
75  {
76  max = value;
77  return true;
78  }
79  return false;
80  }
81 
87  template<typename T>
88  bool contains(T value, T min, T max)
89  {
90  return min <= value && value <= max;
91  }
92 
113  inline std::pair<double,double> zoomIn(const double left, const double right, const float factor, const float align)
114  {
115  OPENMS_PRECONDITION(factor >= 0, "Factor must be >=0")
116  OPENMS_PRECONDITION(align >= 0, "align must be >=0")
117  OPENMS_PRECONDITION(align <= 1, "align must be <=1")
118  std::pair<double, double> res;
119  auto old_width = right - left;
120  auto offset_left = (1.0f - factor) * old_width * align;
121  res.first = left + offset_left;
122  res.second = res.first + old_width * factor;
123  return res;
124  }
125 
137  inline double ceilDecimal(double x, int decPow)
138  {
139  return (ceil(x / pow(10.0, decPow))) * pow(10.0, decPow); // decimal shift right, ceiling, decimal shift left
140  }
141 
152  inline double roundDecimal(double x, int decPow)
153  {
154  if (x > 0)
155  return (floor(0.5 + x / pow(10.0, decPow))) * pow(10.0, decPow);
156 
157  return -((floor(0.5 + fabs(x) / pow(10.0, decPow))) * pow(10.0, decPow));
158  }
159 
165  inline double intervalTransformation(double x, double left1, double right1, double left2, double right2)
166  {
167  return left2 + (x - left1) * (right2 - left2) / (right1 - left1);
168  }
169 
177  inline double linear2log(double x)
178  {
179  return log10(x + 1); //+1 to avoid negative logarithms
180  }
181 
189  inline double log2linear(double x)
190  {
191  return pow(10, x) - 1;
192  }
193 
199  inline bool isOdd(UInt x)
200  {
201  return (x & 1) != 0;
202  }
203 
209  template <typename T>
210  T round(T x)
211  {
212  if (x >= T(0))
213  {
214  return T(floor(x + T(0.5)));
215  }
216  else
217  {
218  return T(ceil(x - T(0.5)));
219  }
220  }
221 
227  inline bool approximatelyEqual(double a, double b, double tol)
228  {
229  return std::fabs(a - b) <= tol;
230  }
231 
240  template <typename T>
241  T gcd(T a, T b)
242  {
243  T c;
244  while (b != 0)
245  {
246  c = a % b;
247  a = b;
248  b = c;
249  }
250  return a;
251  }
252 
265  template <typename T>
266  T gcd(T a, T b, T & u1, T & u2)
267  {
268  u1 = 1;
269  u2 = 0;
270  T u3 = a;
271 
272  T v1 = 0;
273  T v2 = 1;
274  T v3 = b;
275 
276  while (v3 != 0)
277  {
278  T q = u3 / v3;
279  T t1 = u1 - v1 * q;
280  T t2 = u2 - v2 * q;
281  T t3 = u3 - v3 * q;
282 
283  u1 = v1;
284  u2 = v2;
285  u3 = v3;
286 
287  v1 = t1;
288  v2 = t2;
289  v3 = t3;
290  }
291 
292  return u3;
293  }
294 
304  template <typename T>
305  T getPPM(T mz_obs, T mz_ref)
306  {
307  return (mz_obs - mz_ref) / mz_ref * 1e6;
308  }
309 
319  template <typename T>
320  T getPPMAbs(T mz_obs, T mz_ref)
321  {
322  return std::fabs(getPPM(mz_obs, mz_ref));
323  }
324 
334  template <typename T>
335  T ppmToMass(T ppm, T mz_ref)
336  {
337  return (ppm / T(1e6)) * mz_ref;
338  }
339 
340  /*
341  @brief Compute the absolute mass diff in [Th], given a ppm value and a reference point.
342 
343  The returned mass diff is always positive!
344 
345  @param ppm Parts-per-million error
346  @param mz_ref Reference m/z
347  @return The absolute mass diff in [Th]
348  */
349  template <typename T>
350  T ppmToMassAbs(T ppm, T mz_ref)
351  {
352  return std::fabs(ppmToMass(ppm, mz_ref));
353  }
354 
368  inline std::pair<double, double> getTolWindow(double val, double tol, bool ppm)
369  {
370  double left, right;
371 
372  if (ppm)
373  {
374  left = val - val * tol * 1e-6;
375  right = val / (1.0 - tol * 1e-6);
376  }
377  else
378  {
379  left = val - tol;
380  right = val + tol;
381  }
382 
383  return std::make_pair(left, right);
384  }
385 
389  template <typename T1> typename T1::value_type quantile(const T1 &x, double q)
390  {
391  if (x.empty()) throw Exception::InvalidParameter(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION,
392  "Quantile requested from empty container.");
393  if (q < 0.0) q = 0.;
394  if (q > 1.0) q = 1.;
395 
396  const auto n = x.size();
397  const auto id = std::max(0., n * q - 1); // -1 for c++ index starting at 0
398  const auto lo = floor(id);
399  const auto hi = ceil(id);
400  const auto qs = x[lo];
401  const auto h = (id - lo);
402 
403  return (1.0 - h) * qs + h * x[hi];
404  }
405 
406  // portable random shuffle
407  class OPENMS_DLLAPI RandomShuffler
408  {
409  public:
410  explicit RandomShuffler(int seed):
411  rng_(boost::mt19937_64(seed))
412  {}
413 
414  explicit RandomShuffler(const boost::mt19937_64& mt_rng):
415  rng_(mt_rng)
416  {}
417 
418  RandomShuffler() = default;
419  ~RandomShuffler() = default;
420 
421  boost::mt19937_64 rng_;
422  template <class RandomAccessIterator>
423  void portable_random_shuffle (RandomAccessIterator first, RandomAccessIterator last)
424  {
425  for (auto i = (last-first)-1; i > 0; --i) // OMS_CODING_TEST_EXCLUDE
426  {
427  boost::uniform_int<decltype(i)> d(0, i);
428  std::swap(first[i], first[d(rng_)]);
429  }
430  }
431 
432  void seed(uint64_t val)
433  {
434  rng_.seed(val);
435  }
436  };
437  } // namespace Math
438 } // namespace OpenMS
439 
Exception indicating that an invalid parameter was handed over to an algorithm.
Definition: Exception.h:341
Definition: MathFunctions.h:408
RandomShuffler(int seed)
Definition: MathFunctions.h:410
boost::mt19937_64 rng_
Definition: MathFunctions.h:421
void seed(uint64_t val)
Definition: MathFunctions.h:432
RandomShuffler(const boost::mt19937_64 &mt_rng)
Definition: MathFunctions.h:414
void portable_random_shuffle(RandomAccessIterator first, RandomAccessIterator last)
Definition: MathFunctions.h:423
unsigned int UInt
Unsigned integer type.
Definition: Types.h:94
#define OPENMS_PRECONDITION(condition, message)
Precondition macro.
Definition: openms/include/OpenMS/CONCEPT/Macros.h:120
T gcd(T a, T b)
Returns the greatest common divisor (gcd) of two numbers by applying the Euclidean algorithm.
Definition: MathFunctions.h:241
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:165
double linear2log(double x)
Transforms a number from linear to log10 scale. Avoids negative logarithms by adding 1.
Definition: MathFunctions.h:177
T round(T x)
Rounds the value.
Definition: MathFunctions.h:210
double log2linear(double x)
Transforms a number from log10 to to linear scale. Subtracts the 1 added by linear2log(double)
Definition: MathFunctions.h:189
double ceilDecimal(double x, int decPow)
rounds x up to the next decimal power 10 ^ decPow
Definition: MathFunctions.h:137
bool approximatelyEqual(double a, double b, double tol)
Returns if a is approximately equal b , allowing a tolerance of tol.
Definition: MathFunctions.h:227
double roundDecimal(double x, int decPow)
rounds x to the next decimal power 10 ^ decPow
Definition: MathFunctions.h:152
bool isOdd(UInt x)
Returns true if the given integer is odd.
Definition: MathFunctions.h:199
const double c
Definition: Constants.h:214
const double h
Definition: Constants.h:167
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:67
T getPPM(T mz_obs, T mz_ref)
Compute parts-per-million of two m/z values.
Definition: MathFunctions.h:305
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:389
T ppmToMass(T ppm, T mz_ref)
Compute the mass diff in [Th], given a ppm value and a reference point.
Definition: MathFunctions.h:335
bool contains(T value, T min, T max)
Is a value contained in [min, max] ?
Definition: MathFunctions.h:88
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:113
T getPPMAbs(T mz_obs, T mz_ref)
Compute absolute parts-per-million of two m/z values.
Definition: MathFunctions.h:320
T ppmToMassAbs(T ppm, T mz_ref)
Definition: MathFunctions.h:350
std::pair< double, double > getTolWindow(double val, double tol, bool ppm)
Return tolerance window around val given tolerance tol.
Definition: MathFunctions.h:368
Main OpenMS namespace.
Definition: FeatureDeconvolution.h:48