From 34028cfa37073847784cfe651de1cc11581c710f Mon Sep 17 00:00:00 2001 From: Alexandre Hoffmann Date: Fri, 24 Jul 2026 16:01:44 +0200 Subject: [PATCH 01/19] Change integrate function parameter to rvalue reference --- include/LNIT/GaussHermiteQuadrature.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/LNIT/GaussHermiteQuadrature.hpp b/include/LNIT/GaussHermiteQuadrature.hpp index 9f9fafd..c0c0f6b 100644 --- a/include/LNIT/GaussHermiteQuadrature.hpp +++ b/include/LNIT/GaussHermiteQuadrature.hpp @@ -24,7 +24,7 @@ class GaussHermiteQuadrature constexpr GaussHermiteQuadrature() {} ///< @brief Default constructor. - template constexpr LongScalar integrate(const Function& f) const; + template constexpr LongScalar integrate(Function&& f) const; private: static constexpr std::array s_wi = { Scalar(0.72500244352094499799), Scalar(0.55908539234713480356), Scalar(0.48645731979545141956), Scalar(0.44287166385270444111), Scalar(0.41289257970879246181), From 14f34a921902e3b15a48519ad7449f78d163cc7d Mon Sep 17 00:00:00 2001 From: Alexandre Hoffmann Date: Fri, 24 Jul 2026 16:03:39 +0200 Subject: [PATCH 02/19] Change function parameter type to rvalue reference --- include/LNIT/GaussLaguerreQuadrature.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/LNIT/GaussLaguerreQuadrature.hpp b/include/LNIT/GaussLaguerreQuadrature.hpp index 1d0522e..ed3df28 100644 --- a/include/LNIT/GaussLaguerreQuadrature.hpp +++ b/include/LNIT/GaussLaguerreQuadrature.hpp @@ -38,7 +38,7 @@ class GaussLaguerreQuadrature * @param a Upper bound of integration (default = 0). * @return Approximated integral value. */ - template constexpr LongScalar integrateLeftInfinite (const Function& f, const Scalar& a = Scalar{}) const; + template constexpr LongScalar integrateLeftInfinite (Function&& f, const Scalar& a = Scalar{}) const; /** * @brief Approximate integral over the right semi-infinite interval. * @@ -53,7 +53,7 @@ class GaussLaguerreQuadrature * @param a Lower bound of integration (default = 0). * @return Approximated integral value. */ - template constexpr LongScalar integrateRightInfinite (const Function& f, const Scalar& a = Scalar{}) const; + template constexpr LongScalar integrateRightInfinite (Function&& f, const Scalar& a = Scalar{}) const; private: static constexpr std::array s_wi = { Scalar(0.11077730587320757274), Scalar(0.25810528128189475158), Scalar(0.40622176868437369247), Scalar(0.55526230959922306292), Scalar(0.70555738765958285661), From ac6d11c9817e2706a23a8b9bb1d1d47d05f5ce09 Mon Sep 17 00:00:00 2001 From: Alexandre Hoffmann Date: Fri, 24 Jul 2026 16:04:20 +0200 Subject: [PATCH 03/19] Change function parameter from const& to && --- include/LNIT/GaussLaguerreQuadrature_impl.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/LNIT/GaussLaguerreQuadrature_impl.hpp b/include/LNIT/GaussLaguerreQuadrature_impl.hpp index 9fa7486..f5210df 100644 --- a/include/LNIT/GaussLaguerreQuadrature_impl.hpp +++ b/include/LNIT/GaussLaguerreQuadrature_impl.hpp @@ -18,7 +18,7 @@ extern template class GaussLaguerreQuadrature; //// method implementations //// template template -constexpr LongScalar GaussLaguerreQuadrature::integrateLeftInfinite(const Function& f, const Scalar& a) const +constexpr LongScalar GaussLaguerreQuadrature::integrateLeftInfinite(Function&& f, const Scalar& a) const { const auto fx = s_xi | std::views::transform([&f, &a](const Scalar& x) -> LongScalar { @@ -29,7 +29,7 @@ constexpr LongScalar GaussLaguerreQuadrature::integrateLeftI } template template -constexpr LongScalar GaussLaguerreQuadrature::integrateRightInfinite(const Function& f, const Scalar& a) const +constexpr LongScalar GaussLaguerreQuadrature::integrateRightInfinite(Function&& f, const Scalar& a) const { const auto fx = s_xi | std::views::transform([&f, &a](const Scalar& x) -> LongScalar { From fe0850121e01e38775cd2c35238f20706a020a52 Mon Sep 17 00:00:00 2001 From: Alexandre Hoffmann Date: Fri, 24 Jul 2026 16:04:41 +0200 Subject: [PATCH 04/19] Change integrate function parameter to rvalue reference --- include/LNIT/GaussHermiteQuadrature_impl.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/LNIT/GaussHermiteQuadrature_impl.hpp b/include/LNIT/GaussHermiteQuadrature_impl.hpp index bd88aab..db3adca 100644 --- a/include/LNIT/GaussHermiteQuadrature_impl.hpp +++ b/include/LNIT/GaussHermiteQuadrature_impl.hpp @@ -22,7 +22,7 @@ extern template class GaussHermiteQuadrature; //// method implementations //// template template -constexpr LongScalar GaussHermiteQuadrature::integrate(const Function& f) const +constexpr LongScalar GaussHermiteQuadrature::integrate(Function&& f) const { const auto fx = s_xi | std::views::transform([&f](const Scalar& x) -> LongScalar { From 0a17d59fe5c2d8962aa98d81bd75b548bb30e612 Mon Sep 17 00:00:00 2001 From: Alexandre Hoffmann Date: Fri, 24 Jul 2026 16:07:33 +0200 Subject: [PATCH 05/19] Change function parameter type from const& to && --- .../AdaptiveQuadratureBase.hpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/include/LNIT/AdaptiveQuadratures/AdaptiveQuadratureBase.hpp b/include/LNIT/AdaptiveQuadratures/AdaptiveQuadratureBase.hpp index 799e2ee..4d7e6c6 100644 --- a/include/LNIT/AdaptiveQuadratures/AdaptiveQuadratureBase.hpp +++ b/include/LNIT/AdaptiveQuadratures/AdaptiveQuadratureBase.hpp @@ -65,7 +65,7 @@ class AdaptiveQuadratureBase * * @return Pair (integral, estimated error). */ - template constexpr std::pair estimateIntegral(const Function& f, const Scalar& xmin, const Scalar& xmax) { return derived().estimateIntegralImpl(f, xmin, xmax); } + template constexpr std::pair estimateIntegral(Function&& f, const Scalar& xmin, const Scalar& xmax) { return derived().estimateIntegralImpl(f, xmin, xmax); } /** * @brief Perform adaptive quadrature on [xmin, xmax]. @@ -75,9 +75,9 @@ class AdaptiveQuadratureBase * @param xmax Upper bound of interval. * @return Approximation of the integral. */ - template LongScalar integrate(const Function& f, const Scalar& xmin, const Scalar& xmax); + template LongScalar integrate(Function&& f, const Scalar& xmin, const Scalar& xmax); - template LongScalar integrateWithHints(const Function& f, const std::span mu, const Scalar& sigma); + template LongScalar integrateWithHints(Function&& f, const std::span mu, const Scalar& sigma); /** * @brief Perform adaptive quadrature on (-inf, xmax]. @@ -94,7 +94,7 @@ class AdaptiveQuadratureBase * @param xmax Upper bound of interval. * @return Approximation of the integral. */ - template LongScalar integrateLeftInfinite(const Function& f, const Scalar& xmax); + template LongScalar integrateLeftInfinite(Function&& f, const Scalar& xmax); /** * @brief Perform adaptive quadrature on [xmin, inf). @@ -111,7 +111,7 @@ class AdaptiveQuadratureBase * @param xmax Upper bound of interval. * @return Approximation of the integral. */ - template LongScalar integrateRightInfinite(const Function& f, const Scalar& xmin); + template LongScalar integrateRightInfinite(Function&& f, const Scalar& xmin); /** * @brief Perform adaptive quadrature on (-inf, inf). @@ -126,7 +126,7 @@ class AdaptiveQuadratureBase * \f] * Finally addapt the quadrature over [xmin, xmax]. */ - template LongScalar integrate(const Function& f); + template LongScalar integrate(Function&& f); /** * @brief Perform adaptive quadrature on (-inf, inf) using a coordinate-remapping technique. @@ -141,9 +141,9 @@ class AdaptiveQuadratureBase * \int_{-1}^{1} f(x(t))\frac{1 + t^2}{(1 - t^2)^2} dt. * \f] */ - template LongScalar remapAndIntegrate(const Function& f); + template LongScalar remapAndIntegrate(Function&& f); - template std::invoke_result_t integrateWithoutAdaptation(const Function& f) const; + template std::invoke_result_t integrateWithoutAdaptation(Function&& f) const; constexpr Size getMaxIt() const { return m_maxIt; } ///< @brief Maximum iterations allowed. constexpr Size getNits() const { return m_it; } ///< @brief Number of iterations performed. @@ -170,7 +170,7 @@ class AdaptiveQuadratureBase constexpr std::span getSubIntervals() const { return m_intervals; } private: - template LongScalar adaptQuadrature(const Function& func); + template LongScalar adaptQuadrature(Function&& func); std::vector m_intervals; std::vector m_subIntergrals; From 8d3f3fda4e68f08785b4d22defcf24cb83d92fad Mon Sep 17 00:00:00 2001 From: Alexandre Hoffmann Date: Fri, 24 Jul 2026 16:14:00 +0200 Subject: [PATCH 06/19] Change Function parameter to rvalue reference --- .../AdaptiveQuadratureBase_impl.hpp | 42 ++++++++++--------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/include/LNIT/AdaptiveQuadratures/AdaptiveQuadratureBase_impl.hpp b/include/LNIT/AdaptiveQuadratures/AdaptiveQuadratureBase_impl.hpp index 6a60cb9..94eb773 100644 --- a/include/LNIT/AdaptiveQuadratures/AdaptiveQuadratureBase_impl.hpp +++ b/include/LNIT/AdaptiveQuadratures/AdaptiveQuadratureBase_impl.hpp @@ -28,7 +28,7 @@ AdaptiveQuadratureBase::AdaptiveQuadratureBase(const Size& maxIt, const } template template -auto AdaptiveQuadratureBase::adaptQuadrature(const Function& f) -> LongScalar +auto AdaptiveQuadratureBase::adaptQuadrature(Function&& f) -> LongScalar { using std::abs; using std::isfinite; @@ -72,7 +72,7 @@ auto AdaptiveQuadratureBase::adaptQuadrature(const Function& f) -> Long } template template -auto AdaptiveQuadratureBase::integrate(const Function& f, const Scalar& xmin, const Scalar& xmax) -> LongScalar +auto AdaptiveQuadratureBase::integrate(Function&& f, const Scalar& xmin, const Scalar& xmax) -> LongScalar { using std::ceil; @@ -102,11 +102,11 @@ auto AdaptiveQuadratureBase::integrate(const Function& f, const Scalar& } if (m_out) { fmt::print(m_out, "#NumericalIntegrator adapting quadrature over [{}, {}]\n", xmin, xmax); } - return adaptQuadrature(f); + return adaptQuadrature(std::forward(f)); } template template -auto AdaptiveQuadratureBase::integrateWithHints(const Function& f, const std::span mu, const Scalar& sigma) -> LongScalar +auto AdaptiveQuadratureBase::integrateWithHints(Function&& f, const std::span mu, const Scalar& sigma) -> LongScalar { using std::abs; using std::isfinite; @@ -182,11 +182,11 @@ auto AdaptiveQuadratureBase::integrateWithHints(const Function& f, cons } if (m_out) { fmt::print(m_out, "#NumericalIntegrator adapting quadrature over {}\n", m_intervals); } - return adaptQuadrature(f); + return adaptQuadrature(std::forward(f)); } template template -auto AdaptiveQuadratureBase::integrateLeftInfinite(const Function& f, const Scalar& xmax) -> LongScalar +auto AdaptiveQuadratureBase::integrateLeftInfinite(Function&& f, const Scalar& xmax) -> LongScalar { using std::isfinite; using std::abs; @@ -200,11 +200,11 @@ auto AdaptiveQuadratureBase::integrateLeftInfinite(const Function& f, c xmin *= 2; leftIntegral = gLaguerreQuad.integrateLeftInfinite(f, xmin); } - return isfinite(leftIntegral) ? integrate(f, xmin, xmax) : NumTraits::NaN; + return isfinite(leftIntegral) ? integrate(std::forward(f), xmin, xmax) : NumTraits::NaN; } template template -auto AdaptiveQuadratureBase::integrateRightInfinite(const Function& f, const Scalar& xmin) -> LongScalar +auto AdaptiveQuadratureBase::integrateRightInfinite(Function&& f, const Scalar& xmin) -> LongScalar { using std::isfinite; using std::abs; @@ -218,11 +218,15 @@ auto AdaptiveQuadratureBase::integrateRightInfinite(const Function& f, xmax *= 2; rightIntegral = gLaguerreQuad.integrateRightInfinite(f, xmax); } - return isfinite(rightIntegral) ? integrate(f, xmin, xmax) : NumTraits::NaN; + const LongScalar ret = isfinite(rightIntegral) + ? integrate(std::forward(f), xmin, xmax) + : NumTraits::NaN; + + return ret; } template template -auto AdaptiveQuadratureBase::integrate(const Function& f) -> LongScalar +auto AdaptiveQuadratureBase::integrate(Function&& f) -> LongScalar { using std::isfinite; using std::abs; @@ -237,17 +241,19 @@ auto AdaptiveQuadratureBase::integrate(const Function& f) -> LongScalar leftIntegral = gLaguerreQuad.integrateLeftInfinite(f, xmin); } - return isfinite(leftIntegral) ? integrateRightInfinite(f, xmin) : NumTraits::NaN; + const LongScalar ret = isfinite(leftIntegral) + ? integrateRightInfinite(std::forward(f), xmin) + : NumTraits::NaN; + + return ret; } template template -auto AdaptiveQuadratureBase::remapAndIntegrate(const Function& f) -> LongScalar +auto AdaptiveQuadratureBase::remapAndIntegrate(Function&& f) -> LongScalar { using std::isnan; - constexpr Scalar eps = {}; - - const auto fref = [&f](const Scalar t) -> LongScalar + return integrate([&f](const Scalar t) -> LongScalar { const LongScalar fx = f(t / (1 - t*t)); const Scalar dxdt = (1 + t*t) / ((1 - t*t)*(1 - t*t)); @@ -255,13 +261,11 @@ auto AdaptiveQuadratureBase::remapAndIntegrate(const Function& f) -> Lo return isnan(fx*dxdt) ? LongScalar{} : fx*dxdt; - }; - - return integrate(fref, -1, 1); + }, -1, 1); } template template -auto AdaptiveQuadratureBase::integrateWithoutAdaptation(const Function& f) const -> std::invoke_result_t +auto AdaptiveQuadratureBase::integrateWithoutAdaptation(Function&& f) const -> std::invoke_result_t { const auto localIntegrals = m_intervals | std::views::transform([&self = derived(), &f](const Interval& interval) -> std::invoke_result_t { From b8670f9979e552f3b1dad3289879c12354be4133 Mon Sep 17 00:00:00 2001 From: Alexandre Hoffmann Date: Fri, 24 Jul 2026 16:14:43 +0200 Subject: [PATCH 07/19] Change function parameter types to rvalue references --- .../AdaptiveQuadratures/ClenshawCurtisAdaptiveQuadrature.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/LNIT/AdaptiveQuadratures/ClenshawCurtisAdaptiveQuadrature.hpp b/include/LNIT/AdaptiveQuadratures/ClenshawCurtisAdaptiveQuadrature.hpp index ae2a1ae..e2832f3 100644 --- a/include/LNIT/AdaptiveQuadratures/ClenshawCurtisAdaptiveQuadrature.hpp +++ b/include/LNIT/AdaptiveQuadratures/ClenshawCurtisAdaptiveQuadrature.hpp @@ -45,9 +45,9 @@ class ClenshawCurtisAdaptiveQuadrature : public AdaptiveQuadratureBase< Clenshaw * @param xmax Upper bound. * @return Pair (integral, estimated error). */ - template constexpr std::pair estimateIntegralImpl(const Function& f, const Scalar& xmin, const Scalar& xmax); + template constexpr std::pair estimateIntegralImpl(Function&& f, const Scalar& xmin, const Scalar& xmax); - template constexpr std::invoke_result_t integrateImpl(const Function& f, const Scalar& xmin, const Scalar& xmax) const; + template constexpr std::invoke_result_t integrateImpl(Function&& f, const Scalar& xmin, const Scalar& xmax) const; constexpr Scalar getMaxDeltaXImpl(const Scalar& xmin, const Scalar& xmax) const { return (xmax - xmin)*misc::maxDiff(std::span{s_xi}); } private: From 30a2fcf1840bf740b7aa9ff9f8a6e7ce07fd0b22 Mon Sep 17 00:00:00 2001 From: Alexandre Hoffmann Date: Fri, 24 Jul 2026 16:15:34 +0200 Subject: [PATCH 08/19] Change function parameter from const reference to rvalue reference --- .../ClenshawCurtisAdaptiveQuadrature_impl.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/LNIT/AdaptiveQuadratures/ClenshawCurtisAdaptiveQuadrature_impl.hpp b/include/LNIT/AdaptiveQuadratures/ClenshawCurtisAdaptiveQuadrature_impl.hpp index 756c74b..4bb6e06 100644 --- a/include/LNIT/AdaptiveQuadratures/ClenshawCurtisAdaptiveQuadrature_impl.hpp +++ b/include/LNIT/AdaptiveQuadratures/ClenshawCurtisAdaptiveQuadrature_impl.hpp @@ -21,7 +21,7 @@ extern template class ClenshawCurtisAdaptiveQuadrature //// method implementations //// template template -constexpr auto ClenshawCurtisAdaptiveQuadrature::estimateIntegralImpl(const Function& f, const Scalar& xmin, const Scalar& xmax) -> std::pair +constexpr auto ClenshawCurtisAdaptiveQuadrature::estimateIntegralImpl(Function&& f, const Scalar& xmin, const Scalar& xmax) -> std::pair { using std::abs; @@ -52,7 +52,7 @@ constexpr auto ClenshawCurtisAdaptiveQuadrature::estimateIntegralImpl(cons } template template -constexpr auto ClenshawCurtisAdaptiveQuadrature::integrateImpl(const Function& f, const Scalar& xmin, const Scalar& xmax) const -> std::invoke_result_t +constexpr auto ClenshawCurtisAdaptiveQuadrature::integrateImpl(Function&& f, const Scalar& xmin, const Scalar& xmax) const -> std::invoke_result_t { const auto fx = s_xi | std::views::transform([&f, &xmin, &xmax](const Scalar& xi) -> std::invoke_result_t { From fac70398943478708dabb6860b57a320b2dc92a4 Mon Sep 17 00:00:00 2001 From: Alexandre Hoffmann Date: Fri, 24 Jul 2026 16:17:02 +0200 Subject: [PATCH 09/19] Change function parameter types to rvalue references --- .../ClenshawCurtisHybridAdaptiveQuadrature.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/LNIT/AdaptiveQuadratures/ClenshawCurtisHybridAdaptiveQuadrature.hpp b/include/LNIT/AdaptiveQuadratures/ClenshawCurtisHybridAdaptiveQuadrature.hpp index 75a97ce..8ef1005 100644 --- a/include/LNIT/AdaptiveQuadratures/ClenshawCurtisHybridAdaptiveQuadrature.hpp +++ b/include/LNIT/AdaptiveQuadratures/ClenshawCurtisHybridAdaptiveQuadrature.hpp @@ -48,9 +48,9 @@ class ClenshawCurtisHybridAdaptiveQuadrature : public AdaptiveQuadratureBase< Cl * @param xmax Upper bound. * @return Pair (integral, estimated error). */ - template constexpr std::pair estimateIntegralImpl(const Function& f, const Scalar& xmin, const Scalar& xmax); + template constexpr std::pair estimateIntegralImpl(Function&& f, const Scalar& xmin, const Scalar& xmax); - template constexpr std::invoke_result_t integrateImpl(const Function& f, const Scalar& xmin, const Scalar& xmax) const; + template constexpr std::invoke_result_t integrateImpl(Function&& f, const Scalar& xmin, const Scalar& xmax) const; constexpr Scalar getMaxDeltaXImpl(const Scalar& xmin, const Scalar& xmax) const { return (xmax - xmin)*misc::maxDiff(std::span{s_xi}); } private: From b0991c67edc3fdc2ddcf6d55738b17c52551e9cd Mon Sep 17 00:00:00 2001 From: Alexandre Hoffmann Date: Fri, 24 Jul 2026 16:17:44 +0200 Subject: [PATCH 10/19] Change Function parameter to rvalue reference in methods --- .../ClenshawCurtisHybridAdaptiveQuadrature_impl.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/LNIT/AdaptiveQuadratures/ClenshawCurtisHybridAdaptiveQuadrature_impl.hpp b/include/LNIT/AdaptiveQuadratures/ClenshawCurtisHybridAdaptiveQuadrature_impl.hpp index 8247edf..34bec7a 100644 --- a/include/LNIT/AdaptiveQuadratures/ClenshawCurtisHybridAdaptiveQuadrature_impl.hpp +++ b/include/LNIT/AdaptiveQuadratures/ClenshawCurtisHybridAdaptiveQuadrature_impl.hpp @@ -20,7 +20,7 @@ extern template class ClenshawCurtisHybridAdaptiveQuadrature template -constexpr auto ClenshawCurtisHybridAdaptiveQuadrature::estimateIntegralImpl(const Function& f, const Scalar& xmin, const Scalar& xmax) -> std::pair +constexpr auto ClenshawCurtisHybridAdaptiveQuadrature::estimateIntegralImpl(Function&& f, const Scalar& xmin, const Scalar& xmax) -> std::pair { using std::abs; @@ -38,7 +38,7 @@ constexpr auto ClenshawCurtisHybridAdaptiveQuadrature::estimateIntegralImp } template template -constexpr auto ClenshawCurtisHybridAdaptiveQuadrature::integrateImpl(const Function& f, const Scalar& xmin, const Scalar& xmax) const -> std::invoke_result_t +constexpr auto ClenshawCurtisHybridAdaptiveQuadrature::integrateImpl(Function&& f, const Scalar& xmin, const Scalar& xmax) const -> std::invoke_result_t { const auto fx = s_xi | std::views::transform([&f, &xmin, &xmax](const Scalar& xi) -> std::invoke_result_t { From d2d4f51d14e10c9223970580269e52dee560994d Mon Sep 17 00:00:00 2001 From: Alexandre Hoffmann Date: Fri, 24 Jul 2026 16:18:11 +0200 Subject: [PATCH 11/19] Change function parameter from const& to && --- include/LNIT/AdaptiveQuadratures/GLCCAdaptiveQuadrature.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/LNIT/AdaptiveQuadratures/GLCCAdaptiveQuadrature.hpp b/include/LNIT/AdaptiveQuadratures/GLCCAdaptiveQuadrature.hpp index 40d7ba5..1c58758 100644 --- a/include/LNIT/AdaptiveQuadratures/GLCCAdaptiveQuadrature.hpp +++ b/include/LNIT/AdaptiveQuadratures/GLCCAdaptiveQuadrature.hpp @@ -49,9 +49,9 @@ class GLCCAdaptiveQuadrature : public AdaptiveQuadratureBase< GLCCAdaptiveQuadra * @param xmax Upper bound. * @return Pair (integral, estimated error). */ - template constexpr std::pair estimateIntegralImpl(const Function& f, const Scalar& xmin, const Scalar& xmax) const; + template constexpr std::pair estimateIntegralImpl(Function&& f, const Scalar& xmin, const Scalar& xmax) const; - template constexpr std::invoke_result_t integrateImpl(const Function& f, const Scalar& xmin, const Scalar& xmax) const; + template constexpr std::invoke_result_t integrateImpl(Function&& f, const Scalar& xmin, const Scalar& xmax) const; constexpr Scalar getMaxDeltaXImpl(const Scalar xmin, const Scalar xmax) const { return (xmax - xmin)*misc::maxDiff(std::span{s_xi_cc}); } private: From 256d39245dd1c62212676cff81b620f088d1ccdd Mon Sep 17 00:00:00 2001 From: Alexandre Hoffmann Date: Fri, 24 Jul 2026 16:18:43 +0200 Subject: [PATCH 12/19] Change function parameter from const& to && --- .../LNIT/AdaptiveQuadratures/GLCCAdaptiveQuadrature_impl.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/LNIT/AdaptiveQuadratures/GLCCAdaptiveQuadrature_impl.hpp b/include/LNIT/AdaptiveQuadratures/GLCCAdaptiveQuadrature_impl.hpp index 906dadc..7306575 100644 --- a/include/LNIT/AdaptiveQuadratures/GLCCAdaptiveQuadrature_impl.hpp +++ b/include/LNIT/AdaptiveQuadratures/GLCCAdaptiveQuadrature_impl.hpp @@ -20,7 +20,7 @@ extern template class GLCCAdaptiveQuadrature; //// method implementations //// template template -constexpr auto GLCCAdaptiveQuadrature::estimateIntegralImpl(const Function& f, const Scalar& xmin, const Scalar& xmax) const -> std::pair +constexpr auto GLCCAdaptiveQuadrature::estimateIntegralImpl(Function&& f, const Scalar& xmin, const Scalar& xmax) const -> std::pair { using std::abs; @@ -43,7 +43,7 @@ constexpr auto GLCCAdaptiveQuadrature::estimateIntegralImpl(const Function } template template -constexpr auto GLCCAdaptiveQuadrature::integrateImpl(const Function& f, const Scalar& xmin, const Scalar& xmax) const -> std::invoke_result_t +constexpr auto GLCCAdaptiveQuadrature::integrateImpl(Function&& f, const Scalar& xmin, const Scalar& xmax) const -> std::invoke_result_t { const auto fx = s_xi_gl | std::views::transform([&f, &xmin, &xmax](const Scalar& xi) -> std::invoke_result_t { From 6b193a4a561e6c4295bc90c789c48105e5775e37 Mon Sep 17 00:00:00 2001 From: Alexandre Hoffmann Date: Fri, 24 Jul 2026 16:19:06 +0200 Subject: [PATCH 13/19] Change function parameter types to rvalue references --- .../AdaptiveQuadratures/GaussLegendreAdaptiveQuadrature.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/LNIT/AdaptiveQuadratures/GaussLegendreAdaptiveQuadrature.hpp b/include/LNIT/AdaptiveQuadratures/GaussLegendreAdaptiveQuadrature.hpp index c88c134..4b15474 100644 --- a/include/LNIT/AdaptiveQuadratures/GaussLegendreAdaptiveQuadrature.hpp +++ b/include/LNIT/AdaptiveQuadratures/GaussLegendreAdaptiveQuadrature.hpp @@ -36,9 +36,9 @@ class GaussLegendreAdaptiveQuadrature : public AdaptiveQuadratureBase< GaussLege * @param xmax Upper bound. * @return Pair (integral, estimated error). */ - template constexpr std::pair estimateIntegralImpl(const Function& f, const Scalar& xmin, const Scalar& xmax); + template constexpr std::pair estimateIntegralImpl(Function&& f, const Scalar& xmin, const Scalar& xmax); - template constexpr std::invoke_result_t integrateImpl(const Function& f, const Scalar& xmin, const Scalar& xmax) const; + template constexpr std::invoke_result_t integrateImpl(Function&& f, const Scalar& xmin, const Scalar& xmax) const; inline constexpr Scalar getMaxDeltaXImpl(const Scalar xmin, const Scalar xmax) const { return (xmax - xmin)*misc::maxDiff(std::span{s_xi}); } private: From 5054a534ecd37f4b254a766ef8cd61d21fdc144a Mon Sep 17 00:00:00 2001 From: Alexandre Hoffmann Date: Fri, 24 Jul 2026 16:19:28 +0200 Subject: [PATCH 14/19] Change function parameter from const& to && --- .../GaussLegendreAdaptiveQuadrature_impl.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/LNIT/AdaptiveQuadratures/GaussLegendreAdaptiveQuadrature_impl.hpp b/include/LNIT/AdaptiveQuadratures/GaussLegendreAdaptiveQuadrature_impl.hpp index bf3fdff..a348c84 100644 --- a/include/LNIT/AdaptiveQuadratures/GaussLegendreAdaptiveQuadrature_impl.hpp +++ b/include/LNIT/AdaptiveQuadratures/GaussLegendreAdaptiveQuadrature_impl.hpp @@ -20,7 +20,7 @@ extern template class GaussLegendreAdaptiveQuadrature; //// method implementations //// template template -constexpr auto GaussLegendreAdaptiveQuadrature::estimateIntegralImpl(const Function& f, const Scalar& xmin, const Scalar& xmax) -> std::pair +constexpr auto GaussLegendreAdaptiveQuadrature::estimateIntegralImpl(Function&& f, const Scalar& xmin, const Scalar& xmax) -> std::pair { using std::abs; @@ -43,7 +43,7 @@ constexpr auto GaussLegendreAdaptiveQuadrature::estimateIntegralImpl(const } template template -constexpr auto GaussLegendreAdaptiveQuadrature::integrateImpl(const Function& f, const Scalar& xmin, const Scalar& xmax) const -> std::invoke_result_t +constexpr auto GaussLegendreAdaptiveQuadrature::integrateImpl(Function&& f, const Scalar& xmin, const Scalar& xmax) const -> std::invoke_result_t { const auto fx = s_xi | std::views::transform([&f, &xmin, &xmax](const Scalar& xi) -> std::invoke_result_t { From e45d8b53cfbf359a6052bc133f8638dabd8486e4 Mon Sep 17 00:00:00 2001 From: Alexandre Hoffmann Date: Fri, 24 Jul 2026 16:27:08 +0200 Subject: [PATCH 15/19] Fix inner_product range in GaussLaguerreQuadrature --- include/LNIT/GaussLaguerreQuadrature_impl.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/LNIT/GaussLaguerreQuadrature_impl.hpp b/include/LNIT/GaussLaguerreQuadrature_impl.hpp index f5210df..6723e8e 100644 --- a/include/LNIT/GaussLaguerreQuadrature_impl.hpp +++ b/include/LNIT/GaussLaguerreQuadrature_impl.hpp @@ -20,23 +20,23 @@ extern template class GaussLaguerreQuadrature; template template constexpr LongScalar GaussLaguerreQuadrature::integrateLeftInfinite(Function&& f, const Scalar& a) const { - const auto fx = s_xi | std::views::transform([&f, &a](const Scalar& x) -> LongScalar + const auto fx = s_xi | std::views::transform([&&f, &a](const Scalar& x) -> LongScalar { return f(a - x); }); - return std::inner_product(s_wi.begin(), s_wi.end(), fx.end(), LongScalar{}); + return std::inner_product(s_wi.begin(), s_wi.end(), fx.begin(), LongScalar{}); } template template constexpr LongScalar GaussLaguerreQuadrature::integrateRightInfinite(Function&& f, const Scalar& a) const { - const auto fx = s_xi | std::views::transform([&f, &a](const Scalar& x) -> LongScalar + const auto fx = s_xi | std::views::transform([&&f, &a](const Scalar& x) -> LongScalar { return f(x + a); }); - return std::inner_product(s_wi.begin(), s_wi.end(), fx.end(), LongScalar{}); + return std::inner_product(s_wi.begin(), s_wi.end(), fx.begin(), LongScalar{}); } } // namespace LNIT From 7cfb75eafd551740dd396d9130eb4c756b5868ea Mon Sep 17 00:00:00 2001 From: Alexandre Hoffmann Date: Fri, 24 Jul 2026 16:29:38 +0200 Subject: [PATCH 16/19] Fix lambda capture in GaussLaguerreQuadrature methods --- include/LNIT/GaussLaguerreQuadrature_impl.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/LNIT/GaussLaguerreQuadrature_impl.hpp b/include/LNIT/GaussLaguerreQuadrature_impl.hpp index 6723e8e..526ce53 100644 --- a/include/LNIT/GaussLaguerreQuadrature_impl.hpp +++ b/include/LNIT/GaussLaguerreQuadrature_impl.hpp @@ -20,7 +20,7 @@ extern template class GaussLaguerreQuadrature; template template constexpr LongScalar GaussLaguerreQuadrature::integrateLeftInfinite(Function&& f, const Scalar& a) const { - const auto fx = s_xi | std::views::transform([&&f, &a](const Scalar& x) -> LongScalar + const auto fx = s_xi | std::views::transform([&f, &a](const Scalar& x) -> LongScalar { return f(a - x); }); @@ -31,7 +31,7 @@ constexpr LongScalar GaussLaguerreQuadrature::integrateLeftI template template constexpr LongScalar GaussLaguerreQuadrature::integrateRightInfinite(Function&& f, const Scalar& a) const { - const auto fx = s_xi | std::views::transform([&&f, &a](const Scalar& x) -> LongScalar + const auto fx = s_xi | std::views::transform([&f, &a](const Scalar& x) -> LongScalar { return f(x + a); }); From e86d6281c05eb4543de8eb5920123801dc22bd55 Mon Sep 17 00:00:00 2001 From: Alexandre Hoffmann Date: Fri, 24 Jul 2026 16:30:23 +0200 Subject: [PATCH 17/19] Fix inner_product call to use fx.begin() --- include/LNIT/GaussHermiteQuadrature_impl.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/LNIT/GaussHermiteQuadrature_impl.hpp b/include/LNIT/GaussHermiteQuadrature_impl.hpp index db3adca..904c196 100644 --- a/include/LNIT/GaussHermiteQuadrature_impl.hpp +++ b/include/LNIT/GaussHermiteQuadrature_impl.hpp @@ -29,7 +29,7 @@ constexpr LongScalar GaussHermiteQuadrature::integrate(Funct return f(x); }); - return std::inner_product(s_wi.begin(), s_wi.end(), fx.end(), LongScalar{}); + return std::inner_product(s_wi.begin(), s_wi.end(), fx.begin(), LongScalar{}); } } // namespace LNIT From 740eb2478b1fb154b3be670d98e4195631abec6e Mon Sep 17 00:00:00 2001 From: Alexandre Hoffmann Date: Fri, 24 Jul 2026 16:44:51 +0200 Subject: [PATCH 18/19] Refactor integration logic for clarity and safety --- .../AdaptiveQuadratureBase_impl.hpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/include/LNIT/AdaptiveQuadratures/AdaptiveQuadratureBase_impl.hpp b/include/LNIT/AdaptiveQuadratures/AdaptiveQuadratureBase_impl.hpp index 94eb773..f7caedf 100644 --- a/include/LNIT/AdaptiveQuadratures/AdaptiveQuadratureBase_impl.hpp +++ b/include/LNIT/AdaptiveQuadratures/AdaptiveQuadratureBase_impl.hpp @@ -9,6 +9,7 @@ #include #include #include +#include #include @@ -200,7 +201,11 @@ auto AdaptiveQuadratureBase::integrateLeftInfinite(Function&& f, const xmin *= 2; leftIntegral = gLaguerreQuad.integrateLeftInfinite(f, xmin); } - return isfinite(leftIntegral) ? integrate(std::forward(f), xmin, xmax) : NumTraits::NaN; + const LongScalar ret = isfinite(leftIntegral) + ? integrate(std::forward(f), xmin, xmax) + : NumTraits::NaN; + + return ret; } template template @@ -255,12 +260,13 @@ auto AdaptiveQuadratureBase::remapAndIntegrate(Function&& f) -> LongSca return integrate([&f](const Scalar t) -> LongScalar { - const LongScalar fx = f(t / (1 - t*t)); - const Scalar dxdt = (1 + t*t) / ((1 - t*t)*(1 - t*t)); - - return isnan(fx*dxdt) + const LongScalar fx = f(t / (1 - t*t)); + const Scalar dxdt = (1 + t*t) / ((1 - t*t)*(1 - t*t)); + const LongScalar ret = isnan(fx*dxdt) ? LongScalar{} : fx*dxdt; + + return ret; }, -1, 1); } From 94f9aab446ffe4d1dad50892c8e90c68fda42243 Mon Sep 17 00:00:00 2001 From: Alexandre Hoffmann Date: Fri, 24 Jul 2026 16:46:09 +0200 Subject: [PATCH 19/19] Use std::forward in estimateIntegral function --- include/LNIT/AdaptiveQuadratures/AdaptiveQuadratureBase.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/LNIT/AdaptiveQuadratures/AdaptiveQuadratureBase.hpp b/include/LNIT/AdaptiveQuadratures/AdaptiveQuadratureBase.hpp index 4d7e6c6..5d95deb 100644 --- a/include/LNIT/AdaptiveQuadratures/AdaptiveQuadratureBase.hpp +++ b/include/LNIT/AdaptiveQuadratures/AdaptiveQuadratureBase.hpp @@ -65,7 +65,7 @@ class AdaptiveQuadratureBase * * @return Pair (integral, estimated error). */ - template constexpr std::pair estimateIntegral(Function&& f, const Scalar& xmin, const Scalar& xmax) { return derived().estimateIntegralImpl(f, xmin, xmax); } + template constexpr std::pair estimateIntegral(Function&& f, const Scalar& xmin, const Scalar& xmax) { return derived().estimateIntegralImpl(std::forward(f), xmin, xmax); } /** * @brief Perform adaptive quadrature on [xmin, xmax].