Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-28 09:20:49

0001 // Copyright (c) 2025 OPEN CASCADE SAS
0002 //
0003 // This file is part of Open CASCADE Technology software library.
0004 //
0005 // This library is free software; you can redistribute it and/or modify it under
0006 // the terms of the GNU Lesser General Public License version 2.1 as published
0007 // by the Free Software Foundation, with special exception defined in the file
0008 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
0009 // distribution for complete text of the license and disclaimer of any warranty.
0010 //
0011 // Alternatively, this file may be used under the terms of Open CASCADE
0012 // commercial license or contractual agreement.
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 //! Result for vector function integration.
0029 struct SetResult
0030 {
0031   MathUtils::Status          Status = MathUtils::Status::NotConverged;
0032   std::optional<math_Vector> Values; //!< Integral of each component
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 //! Gauss-Legendre integration of a vector-valued function.
0041 //!
0042 //! Integrates F: R -> R^N over interval [Lower, Upper]:
0043 //! Result[i] = integral_{Lower}^{Upper} F_i(x) dx
0044 //!
0045 //! Uses Gauss-Legendre quadrature applied to each component.
0046 //!
0047 //! Note: Only 1D input is supported (M=1). Multi-dimensional input
0048 //! is not implemented in the legacy API.
0049 //!
0050 //! @tparam Func function type with:
0051 //!   - int NbEquations() - number of output components
0052 //!   - bool Value(const math_Vector& theX, math_Vector& theF)
0053 //! @param theFunc vector-valued function to integrate
0054 //! @param theLower lower bound
0055 //! @param theUpper upper bound
0056 //! @param theOrder integration order (max 61)
0057 //! @return SetResult containing vector of integrals
0058 template <typename Func>
0059 SetResult GaussSet(Func& theFunc, double theLower, double theUpper, int theOrder)
0060 {
0061   SetResult aResult;
0062 
0063   // Get function dimensions
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   // Clamp order
0074   int aOrder = std::min(theOrder, 61);
0075   aOrder     = std::max(aOrder, 1);
0076 
0077   // Get Gauss points and weights
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   // Coordinate transformation
0095   const double aXm = 0.5 * (theLower + theUpper);
0096   const double aXr = 0.5 * (theUpper - theLower);
0097 
0098   // Initialize result vector
0099   math_Vector aVal(1, aNbEqua, 0.0);
0100   math_Vector aTval(1, 1); // Input vector (1D)
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   // Handle odd order case (middle point)
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   // Symmetric Gauss quadrature
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   // Scale by half-width
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 //! Gauss-Legendre integration of vector function using math_Vector bounds.
0157 //!
0158 //! Convenience overload that extracts scalar bounds from math_Vector.
0159 //!
0160 //! @tparam Func function type
0161 //! @param theFunc vector-valued function
0162 //! @param theLower lower bound vector (only first element used)
0163 //! @param theUpper upper bound vector (only first element used)
0164 //! @param theOrder integration order
0165 //! @return SetResult containing vector of integrals
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 } // namespace MathInteg
0176 
0177 #endif // _MathInteg_Set_HeaderFile