File indexing completed on 2026-09-28 09:20:53
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef _MathUtils_Core_HeaderFile
0015 #define _MathUtils_Core_HeaderFile
0016
0017 #include <math_Vector.hxx>
0018
0019 #include <cmath>
0020 #include <algorithm>
0021 #include <limits>
0022
0023
0024 namespace MathUtils
0025 {
0026
0027
0028 inline constexpr double THE_EPSILON = std::numeric_limits<double>::epsilon();
0029
0030
0031 inline constexpr double THE_ZERO_TOL = 1.0e-15;
0032
0033
0034 inline constexpr double THE_PI = 3.14159265358979323846;
0035
0036
0037 inline constexpr double THE_2PI = 6.28318530717958647692;
0038
0039
0040 inline constexpr double THE_GOLDEN_RATIO = 1.618033988749895;
0041
0042
0043 inline constexpr double THE_GOLDEN_SECTION = 0.381966011250105;
0044
0045
0046
0047
0048
0049
0050 inline constexpr double Clamp(double theValue, double theLower, double theUpper)
0051 {
0052 return (theValue < theLower) ? theLower : ((theValue > theUpper) ? theUpper : theValue);
0053 }
0054
0055
0056
0057
0058
0059 inline bool IsZero(double theValue, double theTolerance = THE_ZERO_TOL)
0060 {
0061 return std::abs(theValue) < theTolerance;
0062 }
0063
0064
0065
0066
0067
0068
0069 inline bool IsEqual(double theA, double theB, double theTolerance = THE_ZERO_TOL)
0070 {
0071 const double aDiff = std::abs(theA - theB);
0072 const double aScale = std::max({1.0, std::abs(theA), std::abs(theB)});
0073 return aDiff < theTolerance * aScale;
0074 }
0075
0076
0077
0078
0079
0080
0081 inline double SafeDiv(double theNumerator, double theDenominator, double theDefault = 0.0)
0082 {
0083 return IsZero(theDenominator) ? theDefault : theNumerator / theDenominator;
0084 }
0085
0086
0087
0088
0089 inline int Sign(double theValue)
0090 {
0091 if (theValue > THE_ZERO_TOL)
0092 return 1;
0093 if (theValue < -THE_ZERO_TOL)
0094 return -1;
0095 return 0;
0096 }
0097
0098
0099
0100
0101
0102
0103 inline double SignTransfer(double theA, double theB)
0104 {
0105 return (theB >= 0.0) ? std::abs(theA) : -std::abs(theA);
0106 }
0107
0108
0109
0110
0111 inline constexpr double Sqr(double theValue)
0112 {
0113 return theValue * theValue;
0114 }
0115
0116
0117
0118
0119 inline constexpr double Cube(double theValue)
0120 {
0121 return theValue * theValue * theValue;
0122 }
0123
0124
0125
0126
0127
0128 inline double CubeRoot(double theValue)
0129 {
0130 return (theValue >= 0.0) ? std::cbrt(theValue) : -std::cbrt(-theValue);
0131 }
0132
0133
0134
0135
0136 inline bool IsFinite(double theValue)
0137 {
0138 return std::isfinite(theValue);
0139 }
0140
0141
0142
0143
0144
0145
0146 inline double ComputeScaleFactor(const double* theCoeffs, int theCount)
0147 {
0148 double aMaxAbs = 0.0;
0149 for (int i = 0; i < theCount; ++i)
0150 {
0151 aMaxAbs = std::max(aMaxAbs, std::abs(theCoeffs[i]));
0152 }
0153
0154 if (aMaxAbs < THE_ZERO_TOL || aMaxAbs > 1.0e15)
0155 {
0156
0157 int anExp = 0;
0158 std::frexp(aMaxAbs, &anExp);
0159 return std::ldexp(1.0, -anExp + 1);
0160 }
0161
0162 return 1.0;
0163 }
0164
0165
0166
0167
0168
0169 inline double DotProduct(const math_Vector& theA, const math_Vector& theB)
0170 {
0171 double aSum = 0.0;
0172 const int aLower = theA.Lower();
0173 const int aUpper = theA.Upper();
0174 for (int i = aLower; i <= aUpper; ++i)
0175 {
0176 aSum += theA(i) * theB(i);
0177 }
0178 return aSum;
0179 }
0180
0181
0182
0183
0184 inline double VectorNorm(const math_Vector& theVec)
0185 {
0186 double aSum = 0.0;
0187 for (int i = theVec.Lower(); i <= theVec.Upper(); ++i)
0188 {
0189 aSum += theVec(i) * theVec(i);
0190 }
0191 return std::sqrt(aSum);
0192 }
0193
0194
0195
0196
0197 inline double VectorInfNorm(const math_Vector& theVec)
0198 {
0199 double aMax = 0.0;
0200 for (int i = theVec.Lower(); i <= theVec.Upper(); ++i)
0201 {
0202 aMax = std::max(aMax, std::abs(theVec(i)));
0203 }
0204 return aMax;
0205 }
0206
0207 }
0208
0209 #endif