File indexing completed on 2026-09-28 09:20:49
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef _MathInteg_Set_HeaderFile
0015 #define _MathInteg_Set_HeaderFile
0016
0017 #include <MathUtils_Types.hxx>
0018 #include <MathUtils_Config.hxx>
0019 #include <math_Vector.hxx>
0020 #include <MathUtils_GaussKronrodWeights.hxx>
0021
0022 #include <cmath>
0023
0024 namespace MathInteg
0025 {
0026 using namespace MathUtils;
0027
0028
0029 struct SetResult
0030 {
0031 MathUtils::Status Status = MathUtils::Status::NotConverged;
0032 std::optional<math_Vector> Values;
0033 int NbEquations = 0;
0034
0035 bool IsDone() const { return Status == MathUtils::Status::OK; }
0036
0037 explicit operator bool() const { return IsDone(); }
0038 };
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058 template <typename Func>
0059 SetResult GaussSet(Func& theFunc, double theLower, double theUpper, int theOrder)
0060 {
0061 SetResult aResult;
0062
0063
0064 const int aNbEqua = theFunc.NbEquations();
0065 if (aNbEqua <= 0)
0066 {
0067 aResult.Status = Status::InvalidInput;
0068 return aResult;
0069 }
0070
0071 aResult.NbEquations = aNbEqua;
0072
0073
0074 int aOrder = std::min(theOrder, 61);
0075 aOrder = std::max(aOrder, 1);
0076
0077
0078 math_Vector aGP(1, aOrder);
0079 math_Vector aGW(1, aOrder);
0080 if (!GetOrderedGaussPointsAndWeights(aOrder, aGP, aGW))
0081 {
0082 aResult.Status = Status::InvalidInput;
0083 return aResult;
0084 }
0085
0086 math_Vector aPoints(0, aOrder - 1);
0087 math_Vector aWeights(0, aOrder - 1);
0088 for (int i = 0; i < aOrder; ++i)
0089 {
0090 aPoints(i) = aGP(i + 1);
0091 aWeights(i) = aGW(i + 1);
0092 }
0093
0094
0095 const double aXm = 0.5 * (theLower + theUpper);
0096 const double aXr = 0.5 * (theUpper - theLower);
0097
0098
0099 math_Vector aVal(1, aNbEqua, 0.0);
0100 math_Vector aTval(1, 1);
0101 math_Vector aFVal1(1, aNbEqua);
0102 math_Vector aFVal2(1, aNbEqua);
0103
0104 const int aInd = aOrder / 2;
0105 const int aInd1 = (aOrder + 1) / 2;
0106
0107
0108 if (aInd1 > aInd)
0109 {
0110 aTval(1) = aXm;
0111 if (!theFunc.Value(aTval, aVal))
0112 {
0113 aResult.Status = Status::NotConverged;
0114 return aResult;
0115 }
0116 for (int j = 1; j <= aNbEqua; ++j)
0117 {
0118 aVal(j) *= aWeights(aInd1 - 1);
0119 }
0120 }
0121
0122
0123 for (int i = 0; i < aInd; ++i)
0124 {
0125 aTval(1) = aXm + aXr * aPoints(i);
0126 if (!theFunc.Value(aTval, aFVal1))
0127 {
0128 aResult.Status = Status::NotConverged;
0129 return aResult;
0130 }
0131
0132 aTval(1) = aXm - aXr * aPoints(i);
0133 if (!theFunc.Value(aTval, aFVal2))
0134 {
0135 aResult.Status = Status::NotConverged;
0136 return aResult;
0137 }
0138
0139 for (int j = 1; j <= aNbEqua; ++j)
0140 {
0141 aVal(j) += (aFVal1(j) + aFVal2(j)) * aWeights(i);
0142 }
0143 }
0144
0145
0146 for (int j = 1; j <= aNbEqua; ++j)
0147 {
0148 aVal(j) *= aXr;
0149 }
0150
0151 aResult.Values = aVal;
0152 aResult.Status = Status::OK;
0153 return aResult;
0154 }
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166 template <typename Func>
0167 SetResult GaussSet(Func& theFunc,
0168 const math_Vector& theLower,
0169 const math_Vector& theUpper,
0170 int theOrder)
0171 {
0172 return GaussSet(theFunc, theLower(theLower.Lower()), theUpper(theUpper.Lower()), theOrder);
0173 }
0174
0175 }
0176
0177 #endif