diff --git a/include/boost/math/differentiation/autodiff.hpp b/include/boost/math/differentiation/autodiff.hpp index a5a6d86cb..5c6a9e8dd 100644 --- a/include/boost/math/differentiation/autodiff.hpp +++ b/include/boost/math/differentiation/autodiff.hpp @@ -449,13 +449,6 @@ class fvar { #endif }; -// C++11 compatibility -#ifdef BOOST_NO_CXX17_IF_CONSTEXPR -#define BOOST_AUTODIFF_IF_CONSTEXPR -#else -#define BOOST_AUTODIFF_IF_CONSTEXPR constexpr -#endif - // Standard Library Support Requirements // fabs(cr1) | RealType @@ -676,7 +669,7 @@ template fvar::fvar(fvar const& cr) { for (size_t i = 0; i <= (std::min)(Order, Order2); ++i) v[i] = static_cast(cr.v[i]); - if BOOST_AUTODIFF_IF_CONSTEXPR (Order2 < Order) + BOOST_IF_CONSTEXPR (Order2 < Order) std::fill(v.begin() + (Order2 + 1), v.end(), static_cast(0)); } @@ -732,7 +725,7 @@ template fvar& fvar::operator*=(fvar const& cr) { using diff_t = typename std::array::difference_type; promote const zero(0); - if BOOST_AUTODIFF_IF_CONSTEXPR (Order <= Order2) + BOOST_IF_CONSTEXPR (Order <= Order2) for (size_t i = 0, j = Order; i <= Order; ++i, --j) v[j] = std::inner_product(v.cbegin(), v.cend() - diff_t(i), cr.v.crbegin() + diff_t(i), zero); else { @@ -755,11 +748,11 @@ fvar& fvar::operator/=(fvar using diff_t = typename std::array::difference_type; RealType const zero(0); v.front() /= cr.v.front(); - if BOOST_AUTODIFF_IF_CONSTEXPR (Order < Order2) + BOOST_IF_CONSTEXPR (Order < Order2) for (size_t i = 1, j = Order2 - 1, k = Order; i <= Order; ++i, --j, --k) (v[i] -= std::inner_product( cr.v.cbegin() + 1, cr.v.cend() - diff_t(j), v.crbegin() + diff_t(k), zero)) /= cr.v.front(); - else if BOOST_AUTODIFF_IF_CONSTEXPR (0 < Order2) + else BOOST_IF_CONSTEXPR (0 < Order2) for (size_t i = 1, j = Order2 - 1, k = Order; i <= Order; ++i, j && --j, --k) (v[i] -= std::inner_product( cr.v.cbegin() + 1, cr.v.cend() - diff_t(j), v.crbegin() + diff_t(k), zero)) /= cr.v.front(); @@ -794,10 +787,10 @@ promote, fvar> fvar::o promote, fvar> retval; for (size_t i = 0; i <= (std::min)(Order, Order2); ++i) retval.v[i] = v[i] + cr.v[i]; - if BOOST_AUTODIFF_IF_CONSTEXPR (Order < Order2) + BOOST_IF_CONSTEXPR (Order < Order2) for (size_t i = Order + 1; i <= Order2; ++i) retval.v[i] = cr.v[i]; - else if BOOST_AUTODIFF_IF_CONSTEXPR (Order2 < Order) + else BOOST_IF_CONSTEXPR (Order2 < Order) for (size_t i = Order2 + 1; i <= Order; ++i) retval.v[i] = v[i]; return retval; @@ -823,10 +816,10 @@ promote, fvar> fvar::o promote, fvar> retval; for (size_t i = 0; i <= (std::min)(Order, Order2); ++i) retval.v[i] = v[i] - cr.v[i]; - if BOOST_AUTODIFF_IF_CONSTEXPR (Order < Order2) + BOOST_IF_CONSTEXPR (Order < Order2) for (auto i = Order + 1; i <= Order2; ++i) retval.v[i] = -cr.v[i]; - else if BOOST_AUTODIFF_IF_CONSTEXPR (Order2 < Order) + else BOOST_IF_CONSTEXPR (Order2 < Order) for (auto i = Order2 + 1; i <= Order; ++i) retval.v[i] = v[i]; return retval; @@ -854,7 +847,7 @@ promote, fvar> fvar::o using diff_t = typename std::array::difference_type; promote const zero(0); promote, fvar> retval; - if BOOST_AUTODIFF_IF_CONSTEXPR (Order < Order2) + BOOST_IF_CONSTEXPR (Order < Order2) for (size_t i = 0, j = Order, k = Order2; i <= Order2; ++i, j && --j, --k) retval.v[i] = std::inner_product(v.cbegin(), v.cend() - diff_t(j), cr.v.crbegin() + diff_t(k), zero); else @@ -884,7 +877,7 @@ promote, fvar> fvar::o promote const zero(0); promote, fvar> retval; retval.v.front() = v.front() / cr.v.front(); - if BOOST_AUTODIFF_IF_CONSTEXPR (Order < Order2) { + BOOST_IF_CONSTEXPR (Order < Order2) { for (size_t i = 1, j = Order2 - 1; i <= Order; ++i, --j) retval.v[i] = (v[i] - std::inner_product( @@ -895,7 +888,7 @@ promote, fvar> fvar::o -std::inner_product( cr.v.cbegin() + 1, cr.v.cend() - diff_t(j), retval.v.crbegin() + diff_t(j + 1), zero) / cr.v.front(); - } else if BOOST_AUTODIFF_IF_CONSTEXPR (0 < Order2) + } else BOOST_IF_CONSTEXPR (0 < Order2) for (size_t i = 1, j = Order2 - 1, k = Order; i <= Order; ++i, j && --j, --k) retval.v[i] = (v[i] - std::inner_product( @@ -920,7 +913,7 @@ fvar operator/(typename fvar::root_type const& using diff_t = typename std::array::difference_type; fvar retval; retval.v.front() = ca / cr.v.front(); - if BOOST_AUTODIFF_IF_CONSTEXPR (0 < Order) { + BOOST_IF_CONSTEXPR (0 < Order) { RealType const zero(0); for (size_t i = 1, j = Order - 1; i <= Order; ++i, --j) retval.v[i] = @@ -1448,7 +1441,7 @@ promote, fvar> pow(fvar(x); root_type const y0 = static_cast(y); root_type dxydx[order + 1]{pow(x0, y0)}; - if BOOST_AUTODIFF_IF_CONSTEXPR (order == 0) + BOOST_IF_CONSTEXPR (order == 0) return return_type(*dxydx); else { for (size_t i = 0; i < order && y0 - i != 0; ++i) @@ -1457,7 +1450,7 @@ promote, fvar> pow(fvar(1); #ifndef BOOST_NO_CXX17_IF_CONSTEXPR lognx[1] = log(make_fvar(x0)); -#else // for compilers that compile this branch when order=0. +#else // for compilers that compile this branch when order == 0. lognx[(std::min)(size_t(1), order)] = log(make_fvar(x0)); #endif for (size_t i = 1; i < order; ++i) @@ -1485,14 +1478,14 @@ fvar sqrt(fvar const& cr) { root_type derivatives[order + 1]; root_type const x = static_cast(cr); *derivatives = sqrt(x); - if BOOST_AUTODIFF_IF_CONSTEXPR (order == 0) + BOOST_IF_CONSTEXPR (order == 0) return fvar(*derivatives); else { root_type numerator = 0.5; root_type powers = 1; #ifndef BOOST_NO_CXX17_IF_CONSTEXPR derivatives[1] = numerator / *derivatives; -#else // for compilers that compile this branch when order=0. +#else // for compilers that compile this branch when order == 0. derivatives[(std::min)(size_t(1), order)] = numerator / *derivatives; #endif using diff_t = typename std::array::difference_type; @@ -1515,10 +1508,14 @@ fvar log(fvar const& cr) { using root_type = typename fvar::root_type; constexpr size_t order = fvar::order_sum; root_type const d0 = log(static_cast(cr)); - if BOOST_AUTODIFF_IF_CONSTEXPR (order == 0) + BOOST_IF_CONSTEXPR (order == 0) return fvar(d0); else { +#ifndef BOOST_NO_CXX17_IF_CONSTEXPR auto const d1 = make_fvar(static_cast(cr)).inverse(); // log'(x) = 1 / x +#else // for compilers that compile this branch when order == 0. + auto const d1 = make_fvar(static_cast(cr)).inverse(); // log'(x) = 1 / x +#endif return cr.apply_coefficients_nonhorner(order, [&d0, &d1](size_t i) { return i ? d1[i - 1] / i : d0; }); } } @@ -1545,7 +1542,7 @@ fvar cos(fvar const& cr) { using root_type = typename fvar::root_type; constexpr size_t order = fvar::order_sum; root_type const d0 = cos(static_cast(cr)); - if BOOST_AUTODIFF_IF_CONSTEXPR (order == 0) + BOOST_IF_CONSTEXPR (order == 0) return fvar(d0); else { root_type const d1 = -sin(static_cast(cr)); @@ -1560,7 +1557,7 @@ fvar sin(fvar const& cr) { using root_type = typename fvar::root_type; constexpr size_t order = fvar::order_sum; root_type const d0 = sin(static_cast(cr)); - if BOOST_AUTODIFF_IF_CONSTEXPR (order == 0) + BOOST_IF_CONSTEXPR (order == 0) return fvar(d0); else { root_type const d1 = cos(static_cast(cr)); @@ -1575,10 +1572,14 @@ fvar asin(fvar const& cr) { using root_type = typename fvar::root_type; constexpr size_t order = fvar::order_sum; root_type const d0 = asin(static_cast(cr)); - if BOOST_AUTODIFF_IF_CONSTEXPR (order == 0) + BOOST_IF_CONSTEXPR (order == 0) return fvar(d0); else { +#ifndef BOOST_NO_CXX17_IF_CONSTEXPR auto x = make_fvar(static_cast(cr)); +#else // for compilers that compile this branch when order == 0. + auto x = make_fvar(static_cast(cr)); +#endif auto const d1 = sqrt((x *= x).negate() += 1).inverse(); // asin'(x) = 1 / sqrt(1-x*x). return cr.apply_coefficients_nonhorner(order, [&d0, &d1](size_t i) { return i ? d1[i - 1] / i : d0; }); } @@ -1590,10 +1591,14 @@ fvar tan(fvar const& cr) { using root_type = typename fvar::root_type; constexpr size_t order = fvar::order_sum; root_type const d0 = tan(static_cast(cr)); - if BOOST_AUTODIFF_IF_CONSTEXPR (order == 0) + BOOST_IF_CONSTEXPR (order == 0) return fvar(d0); else { +#ifndef BOOST_NO_CXX17_IF_CONSTEXPR auto c = cos(make_fvar(static_cast(cr))); +#else // for compilers that compile this branch when order == 0. + auto c = cos(make_fvar(static_cast(cr))); +#endif auto const d1 = (c *= c).inverse(); // tan'(x) = 1 / cos(x)^2 return cr.apply_coefficients_nonhorner(order, [&d0, &d1](size_t i) { return i ? d1[i - 1] / i : d0; }); } @@ -1605,10 +1610,14 @@ fvar atan(fvar const& cr) { using root_type = typename fvar::root_type; constexpr size_t order = fvar::order_sum; root_type const d0 = atan(static_cast(cr)); - if BOOST_AUTODIFF_IF_CONSTEXPR (order == 0) + BOOST_IF_CONSTEXPR (order == 0) return fvar(d0); else { +#ifndef BOOST_NO_CXX17_IF_CONSTEXPR auto x = make_fvar(static_cast(cr)); +#else // for compilers that compile this branch when order == 0. + auto x = make_fvar(static_cast(cr)); +#endif auto const d1 = ((x *= x) += 1).inverse(); // atan'(x) = 1 / (x*x+1). return cr.apply_coefficients(order, [&d0, &d1](size_t i) { return i ? d1[i - 1] / i : d0; }); } @@ -1621,10 +1630,14 @@ fvar atan2(fvar const& cr, using root_type = typename fvar::root_type; constexpr size_t order = fvar::order_sum; root_type const d0 = atan2(static_cast(cr), ca); - if BOOST_AUTODIFF_IF_CONSTEXPR (order == 0) + BOOST_IF_CONSTEXPR (order == 0) return fvar(d0); else { +#ifndef BOOST_NO_CXX17_IF_CONSTEXPR auto y = make_fvar(static_cast(cr)); +#else // for compilers that compile this branch when order == 0. + auto y = make_fvar(static_cast(cr)); +#endif auto const d1 = ca / ((y *= y) += (ca * ca)); // (d/dy)atan2(y,x) = x / (y*y+x*x) return cr.apply_coefficients(order, [&d0, &d1](size_t i) { return i ? d1[i - 1] / i : d0; }); } @@ -1637,10 +1650,14 @@ fvar atan2(typename fvar::root_type const& ca, using root_type = typename fvar::root_type; constexpr size_t order = fvar::order_sum; root_type const d0 = atan2(ca, static_cast(cr)); - if BOOST_AUTODIFF_IF_CONSTEXPR (order == 0) + BOOST_IF_CONSTEXPR (order == 0) return fvar(d0); else { +#ifndef BOOST_NO_CXX17_IF_CONSTEXPR auto x = make_fvar(static_cast(cr)); +#else // for compilers that compile this branch when order == 0. + auto x = make_fvar(static_cast(cr)); +#endif auto const d1 = -ca / ((x *= x) += (ca * ca)); // (d/dx)atan2(y,x) = -y / (x*x+y*y) return cr.apply_coefficients(order, [&d0, &d1](size_t i) { return i ? d1[i - 1] / i : d0; }); } @@ -1656,7 +1673,7 @@ promote, fvar> atan2(fvar(cr1); root_type const x = static_cast(cr2); root_type const d00 = atan2(y, x); - if BOOST_AUTODIFF_IF_CONSTEXPR (order == 0) + BOOST_IF_CONSTEXPR (order == 0) return return_type(d00); else { constexpr size_t order1 = fvar::order_sum; @@ -1746,10 +1763,14 @@ fvar acos(fvar const& cr) { using root_type = typename fvar::root_type; constexpr size_t order = fvar::order_sum; root_type const d0 = acos(static_cast(cr)); - if BOOST_AUTODIFF_IF_CONSTEXPR (order == 0) + BOOST_IF_CONSTEXPR (order == 0) return fvar(d0); else { +#ifndef BOOST_NO_CXX17_IF_CONSTEXPR auto x = make_fvar(static_cast(cr)); +#else // for compilers that compile this branch when order == 0. + auto x = make_fvar(static_cast(cr)); +#endif auto const d1 = sqrt((x *= x).negate() += 1).inverse().negate(); // acos'(x) = -1 / sqrt(1-x*x). return cr.apply_coefficients(order, [&d0, &d1](size_t i) { return i ? d1[i - 1] / i : d0; }); } @@ -1761,10 +1782,14 @@ fvar acosh(fvar const& cr) { using root_type = typename fvar::root_type; constexpr size_t order = fvar::order_sum; root_type const d0 = acosh(static_cast(cr)); - if BOOST_AUTODIFF_IF_CONSTEXPR (order == 0) + BOOST_IF_CONSTEXPR (order == 0) return fvar(d0); else { +#ifndef BOOST_NO_CXX17_IF_CONSTEXPR auto x = make_fvar(static_cast(cr)); +#else // for compilers that compile this branch when order == 0. + auto x = make_fvar(static_cast(cr)); +#endif auto const d1 = sqrt((x *= x) -= 1).inverse(); // acosh'(x) = 1 / sqrt(x*x-1). return cr.apply_coefficients(order, [&d0, &d1](size_t i) { return i ? d1[i - 1] / i : d0; }); } @@ -1776,10 +1801,14 @@ fvar asinh(fvar const& cr) { using root_type = typename fvar::root_type; constexpr size_t order = fvar::order_sum; root_type const d0 = asinh(static_cast(cr)); - if BOOST_AUTODIFF_IF_CONSTEXPR (order == 0) + BOOST_IF_CONSTEXPR (order == 0) return fvar(d0); else { +#ifndef BOOST_NO_CXX17_IF_CONSTEXPR auto x = make_fvar(static_cast(cr)); +#else // for compilers that compile this branch when order == 0. + auto x = make_fvar(static_cast(cr)); +#endif auto const d1 = sqrt((x *= x) += 1).inverse(); // asinh'(x) = 1 / sqrt(x*x+1). return cr.apply_coefficients(order, [&d0, &d1](size_t i) { return i ? d1[i - 1] / i : d0; }); } @@ -1791,10 +1820,14 @@ fvar atanh(fvar const& cr) { using root_type = typename fvar::root_type; constexpr size_t order = fvar::order_sum; root_type const d0 = atanh(static_cast(cr)); - if BOOST_AUTODIFF_IF_CONSTEXPR (order == 0) + BOOST_IF_CONSTEXPR (order == 0) return fvar(d0); else { +#ifndef BOOST_NO_CXX17_IF_CONSTEXPR auto x = make_fvar(static_cast(cr)); +#else // for compilers that compile this branch when order == 0. + auto x = make_fvar(static_cast(cr)); +#endif auto const d1 = ((x *= x).negate() += 1).inverse(); // atanh'(x) = 1 / (1-x*x) return cr.apply_coefficients(order, [&d0, &d1](size_t i) { return i ? d1[i - 1] / i : d0; }); } @@ -1806,7 +1839,7 @@ fvar cosh(fvar const& cr) { using root_type = typename fvar::root_type; constexpr size_t order = fvar::order_sum; root_type const d0 = cosh(static_cast(cr)); - if BOOST_AUTODIFF_IF_CONSTEXPR (order == 0) + BOOST_IF_CONSTEXPR (order == 0) return fvar(d0); else { root_type const derivatives[2]{d0, sinh(static_cast(cr))}; @@ -1821,7 +1854,7 @@ fvar digamma(fvar const& cr) { constexpr size_t order = fvar::order_sum; root_type const x = static_cast(cr); root_type const d0 = digamma(x); - if BOOST_AUTODIFF_IF_CONSTEXPR (order == 0) + BOOST_IF_CONSTEXPR (order == 0) return fvar(d0); else { static_assert(order <= static_cast((std::numeric_limits::max)()), @@ -1837,10 +1870,14 @@ fvar erf(fvar const& cr) { using root_type = typename fvar::root_type; constexpr size_t order = fvar::order_sum; root_type const d0 = erf(static_cast(cr)); - if BOOST_AUTODIFF_IF_CONSTEXPR (order == 0) + BOOST_IF_CONSTEXPR (order == 0) return fvar(d0); else { +#ifndef BOOST_NO_CXX17_IF_CONSTEXPR auto x = make_fvar(static_cast(cr)); // d1 = 2/sqrt(pi)*exp(-x*x) +#else // for compilers that compile this branch when order == 0. + auto x = make_fvar(static_cast(cr)); // d1 = 2/sqrt(pi)*exp(-x*x) +#endif auto const d1 = 2 * constants::one_div_root_pi() * exp((x *= x).negate()); return cr.apply_coefficients(order, [&d0, &d1](size_t i) { return i ? d1[i - 1] / i : d0; }); } @@ -1852,10 +1889,14 @@ fvar erfc(fvar const& cr) { using root_type = typename fvar::root_type; constexpr size_t order = fvar::order_sum; root_type const d0 = erfc(static_cast(cr)); - if BOOST_AUTODIFF_IF_CONSTEXPR (order == 0) + BOOST_IF_CONSTEXPR (order == 0) return fvar(d0); else { +#ifndef BOOST_NO_CXX17_IF_CONSTEXPR auto x = make_fvar(static_cast(cr)); // erfc'(x) = -erf'(x) +#else // for compilers that compile this branch when order == 0. + auto x = make_fvar(static_cast(cr)); // erfc'(x) = -erf'(x) +#endif auto const d1 = -2 * constants::one_div_root_pi() * exp((x *= x).negate()); return cr.apply_coefficients(order, [&d0, &d1](size_t i) { return i ? d1[i - 1] / i : d0; }); } @@ -1869,12 +1910,12 @@ fvar lambert_w0(fvar const& cr) { constexpr size_t order = fvar::order_sum; root_type derivatives[order + 1]; *derivatives = lambert_w0(static_cast(cr)); - if BOOST_AUTODIFF_IF_CONSTEXPR (order == 0) + BOOST_IF_CONSTEXPR (order == 0) return fvar(*derivatives); else { root_type const expw = exp(*derivatives); derivatives[1] = 1 / (static_cast(cr) + expw); - if BOOST_AUTODIFF_IF_CONSTEXPR (order == 1) + BOOST_IF_CONSTEXPR (order == 1) return cr.apply_derivatives_nonhorner(order, [&derivatives](size_t i) { return derivatives[i]; }); else { using diff_t = typename std::array::difference_type; @@ -1906,7 +1947,7 @@ fvar lgamma(fvar const& cr) { constexpr size_t order = fvar::order_sum; root_type const x = static_cast(cr); root_type const d0 = lgamma(x); - if BOOST_AUTODIFF_IF_CONSTEXPR (order == 0) + BOOST_IF_CONSTEXPR (order == 0) return fvar(d0); else { static_assert(order <= static_cast((std::numeric_limits::max)()) + 1, @@ -1923,7 +1964,7 @@ fvar sinc(fvar const& cr) { using root_type = typename fvar::root_type; constexpr size_t order = fvar::order_sum; root_type taylor[order + 1]{1}; // sinc(0) = 1 - if BOOST_AUTODIFF_IF_CONSTEXPR (order == 0) + BOOST_IF_CONSTEXPR (order == 0) return fvar(*taylor); else { for (size_t n = 2; n <= order; n += 2) @@ -1938,7 +1979,7 @@ fvar sinh(fvar const& cr) { using root_type = typename fvar::root_type; constexpr size_t order = fvar::order_sum; root_type const d0 = sinh(static_cast(cr)); - if BOOST_AUTODIFF_IF_CONSTEXPR (fvar::order_sum == 0) + BOOST_IF_CONSTEXPR (fvar::order_sum == 0) return fvar(d0); else { root_type const derivatives[2]{d0, cosh(static_cast(cr))}; @@ -1959,7 +2000,7 @@ fvar tgamma(fvar const& cr) { using std::tgamma; using root_type = typename fvar::root_type; constexpr size_t order = fvar::order_sum; - if BOOST_AUTODIFF_IF_CONSTEXPR (order == 0) + BOOST_IF_CONSTEXPR (order == 0) return fvar(tgamma(static_cast(cr))); else { if (cr < 0)