GCC Code Coverage Report


Directory: ./
File: include/2geom/math-utils.h
Date: 2024-03-18 17:01:34
Exec Total Coverage
Lines: 17 17 100.0%
Functions: 3 4 75.0%
Branches: 4 4 100.0%

Line Branch Exec Source
1 /**
2 * \file
3 * \brief Low level math functions and compatibility wrappers
4 *//*
5 * Authors:
6 * Johan Engelen <goejendaagh@zonnet.nl>
7 * Michael G. Sloan <mgsloan@gmail.com>
8 * Krzysztof KosiƄski <tweenk.pl@gmail.com>
9 * Copyright 2006-2009 Authors
10 *
11 * This library is free software; you can redistribute it and/or
12 * modify it either under the terms of the GNU Lesser General Public
13 * License version 2.1 as published by the Free Software Foundation
14 * (the "LGPL") or, at your option, under the terms of the Mozilla
15 * Public License Version 1.1 (the "MPL"). If you do not alter this
16 * notice, a recipient may use your version of this file under either
17 * the MPL or the LGPL.
18 *
19 * You should have received a copy of the LGPL along with this library
20 * in the file COPYING-LGPL-2.1; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 * You should have received a copy of the MPL along with this library
23 * in the file COPYING-MPL-1.1
24 *
25 * The contents of this file are subject to the Mozilla Public License
26 * Version 1.1 (the "License"); you may not use this file except in
27 * compliance with the License. You may obtain a copy of the License at
28 * http://www.mozilla.org/MPL/
29 *
30 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
31 * OF ANY KIND, either express or implied. See the LGPL or the MPL for
32 * the specific language governing rights and limitations.
33 *
34 */
35
36 #ifndef LIB2GEOM_SEEN_MATH_UTILS_H
37 #define LIB2GEOM_SEEN_MATH_UTILS_H
38
39 #include <math.h> // sincos is usually only available in math.h
40 #include <array>
41 #include <cmath>
42 #include <utility> // for std::pair
43 #include <boost/math/special_functions/fpclassify.hpp>
44
45 namespace Geom {
46
47 /** @brief Sign function - indicates the sign of a numeric type.
48 * Mathsy people will know this is basically the derivative of abs, except for the fact
49 * that it is defined on 0.
50 * @return -1 when x is negative, 1 when positive, and 0 if equal to 0. */
51 4243330 template <class T> inline int sgn(const T& x) {
52
4/4
✓ Branch 0 taken 2040821 times.
✓ Branch 1 taken 2202277 times.
✓ Branch 2 taken 2192617 times.
✓ Branch 3 taken 9660 times.
4243330 return (x < 0 ? -1 : (x > 0 ? 1 : 0) );
53 // can we 'optimize' this with:
54 // return ( (T(0) < x) - (x < T(0)) );
55 }
56
57 2461 template <class T> inline T sqr(const T& x) {return x * x;}
58 template <class T> inline T cube(const T& x) {return x * x * x;}
59
60 /** Between function - returns true if a number x is within a range: (min < x) && (max > x).
61 * The values delimiting the range and the number must have the same type.
62 */
63 template <class T> inline const T& between (const T& min, const T& max, const T& x)
64 { return (min < x) && (max > x); }
65
66 /** @brief Returns @a x rounded to the nearest multiple of \f$10^{p}\f$.
67
68 Implemented in terms of round, i.e. we make no guarantees as to what happens if x is
69 half way between two rounded numbers.
70
71 Note: places is the number of decimal places without using scientific (e) notation, not the
72 number of significant figures. This function may not be suitable for values of x whose
73 magnitude is so far from 1 that one would want to use scientific (e) notation.
74
75 places may be negative: e.g. places = -2 means rounding to a multiple of .01
76 **/
77 inline double decimal_round(double x, int p) {
78 //TODO: possibly implement with modulus instead?
79 double const multiplier = ::pow(10.0, p);
80 return ::round( x * multiplier ) / multiplier;
81 }
82
83 /** @brief Simultaneously compute a sine and a cosine of the same angle.
84 * This function can be up to 2 times faster than separate computation, depending
85 * on the platform. It uses the standard library function sincos() if available.
86 * @param angle Angle
87 * @param sin_ Variable that will store the sine
88 * @param cos_ Variable that will store the cosine */
89 422624 inline void sincos(double angle, double &sin_, double &cos_) {
90 #ifdef HAVE_SINCOS
91 422624 ::sincos(angle, &sin_, &cos_);
92 #else
93 sin_ = ::sin(angle);
94 cos_ = ::cos(angle);
95 #endif
96 422624 }
97
98 /** @brief Scale the doubles in the passed array to make them "reasonably large".
99 *
100 * All doubles in the passed array will get scaled by the same power of 2 (which is
101 * a lossless operation) in such a way that their geometric average gets closer to 1.
102 *
103 * @tparam N The size of the passed array.
104 * @param[in,out] values The doubles to be rescaled in place.
105 * @return The exponent in the power of two by which the doubles got scaled.
106 */
107 template <size_t N>
108 40166 inline int rescale_homogenous(std::array<double, N> &values)
109 {
110 if constexpr (N == 0) {
111 return 0;
112 }
113 40166 std::array<int, N> exponents;
114 40166 std::array<double, N> mantissas;
115 40166 int average = 0;
116 220940 for (size_t i = 0; i < N; i++) {
117 180774 mantissas[i] = std::frexp(values[i], &exponents[i]);
118 180774 average += exponents[i];
119 }
120 40166 average /= (int)N;
121 220940 for (size_t i = 0; i < N; i++) {
122 180774 values[i] = std::ldexp(mantissas[i], exponents[i] - average);
123 }
124 40166 return -average;
125 }
126
127 } // end namespace Geom
128
129 #endif // LIB2GEOM_SEEN_MATH_UTILS_H
130
131 /*
132 Local Variables:
133 mode:c++
134 c-file-style:"stroustrup"
135 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
136 indent-tabs-mode:nil
137 fill-column:99
138 End:
139 */
140 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
141