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_Convergence_HeaderFile
0015 #define _MathUtils_Convergence_HeaderFile
0016
0017 #include <MathUtils_Config.hxx>
0018 #include <MathUtils_Core.hxx>
0019 #include <math_Vector.hxx>
0020
0021 #include <cmath>
0022
0023
0024 namespace MathUtils
0025 {
0026
0027
0028
0029
0030
0031
0032
0033 inline bool IsXConverged(double theXOld, double theXNew, double theTolerance)
0034 {
0035 const double aDiff = std::abs(theXNew - theXOld);
0036 const double aScale = std::max(1.0, std::abs(theXNew));
0037 return aDiff < theTolerance * aScale;
0038 }
0039
0040
0041
0042
0043
0044 inline bool IsFConverged(double theFValue, double theTolerance)
0045 {
0046 return std::abs(theFValue) < theTolerance;
0047 }
0048
0049
0050
0051
0052
0053
0054
0055
0056 inline bool IsConverged(double theXOld, double theXNew, double theFValue, const Config& theConfig)
0057 {
0058 return IsXConverged(theXOld, theXNew, theConfig.XTolerance)
0059 || IsFConverged(theFValue, theConfig.FTolerance);
0060 }
0061
0062
0063
0064
0065
0066
0067
0068
0069 inline bool IsMinConverged(double theXOld,
0070 double theXNew,
0071 double theFOld,
0072 double theFNew,
0073 const Config& theConfig)
0074 {
0075
0076 if (IsXConverged(theXOld, theXNew, theConfig.XTolerance))
0077 {
0078 return true;
0079 }
0080
0081
0082 const double aFDiff = std::abs(theFNew - theFOld);
0083 const double aFScale = std::max(1.0, std::abs(theFNew));
0084 return aFDiff < theConfig.FTolerance * aFScale;
0085 }
0086
0087
0088
0089
0090
0091
0092 inline bool IsVectorConverged(const math_Vector& theOld,
0093 const math_Vector& theNew,
0094 double theTolerance)
0095 {
0096 double aMaxDiff = 0.0;
0097 double aMaxScale = 1.0;
0098 for (int i = theOld.Lower(); i <= theOld.Upper(); ++i)
0099 {
0100 aMaxDiff = std::max(aMaxDiff, std::abs(theNew(i) - theOld(i)));
0101 aMaxScale = std::max(aMaxScale, std::abs(theNew(i)));
0102 }
0103 return aMaxDiff < theTolerance * aMaxScale;
0104 }
0105
0106
0107
0108
0109
0110 inline bool IsGradientConverged(const math_Vector& theGradient, double theTolerance)
0111 {
0112 double aNormSq = 0.0;
0113 for (int i = theGradient.Lower(); i <= theGradient.Upper(); ++i)
0114 {
0115 aNormSq += Sqr(theGradient(i));
0116 }
0117 return std::sqrt(aNormSq) < theTolerance;
0118 }
0119
0120
0121
0122
0123 inline double InfinityNorm(const math_Vector& theVector)
0124 {
0125 double aMax = 0.0;
0126 for (int i = theVector.Lower(); i <= theVector.Upper(); ++i)
0127 {
0128 aMax = std::max(aMax, std::abs(theVector(i)));
0129 }
0130 return aMax;
0131 }
0132
0133
0134
0135
0136 inline double EuclideanNorm(const math_Vector& theVector)
0137 {
0138 double aSumSq = 0.0;
0139 for (int i = theVector.Lower(); i <= theVector.Upper(); ++i)
0140 {
0141 aSumSq += Sqr(theVector(i));
0142 }
0143 return std::sqrt(aSumSq);
0144 }
0145
0146 }
0147
0148 #endif