mirror of
https://github.com/boostorg/math.git
synced 2026-01-25 06:22:09 +00:00
[#420] Protect unused branches with size_t overflow when compiled pre-C++17.
Replace 'if BOOST_AUTODIFF_IF_CONSTEXPR' with 'BOOST_IF_CONSTEXPR'.
This commit is contained in:
@@ -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 <typename RealType2, size_t Order2>
|
||||
fvar<RealType, Order>::fvar(fvar<RealType2, Order2> const& cr) {
|
||||
for (size_t i = 0; i <= (std::min)(Order, Order2); ++i)
|
||||
v[i] = static_cast<RealType>(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<RealType>(0));
|
||||
}
|
||||
|
||||
@@ -732,7 +725,7 @@ template <typename RealType2, size_t Order2>
|
||||
fvar<RealType, Order>& fvar<RealType, Order>::operator*=(fvar<RealType2, Order2> const& cr) {
|
||||
using diff_t = typename std::array<RealType, Order + 1>::difference_type;
|
||||
promote<RealType, RealType2> 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<RealType, Order>& fvar<RealType, Order>::operator/=(fvar<RealType2, Order2>
|
||||
using diff_t = typename std::array<RealType, Order + 1>::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<RealType, Order>, fvar<RealType2, Order2>> fvar<RealType, Order>::o
|
||||
promote<fvar<RealType, Order>, fvar<RealType2, Order2>> 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<RealType, Order>, fvar<RealType2, Order2>> fvar<RealType, Order>::o
|
||||
promote<fvar<RealType, Order>, fvar<RealType2, Order2>> 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<RealType, Order>, fvar<RealType2, Order2>> fvar<RealType, Order>::o
|
||||
using diff_t = typename std::array<RealType, Order + 1>::difference_type;
|
||||
promote<RealType, RealType2> const zero(0);
|
||||
promote<fvar<RealType, Order>, fvar<RealType2, Order2>> 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<RealType, Order>, fvar<RealType2, Order2>> fvar<RealType, Order>::o
|
||||
promote<RealType, RealType2> const zero(0);
|
||||
promote<fvar<RealType, Order>, fvar<RealType2, Order2>> 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<RealType, Order>, fvar<RealType2, Order2>> fvar<RealType, Order>::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<RealType, Order> operator/(typename fvar<RealType, Order>::root_type const&
|
||||
using diff_t = typename std::array<RealType, Order + 1>::difference_type;
|
||||
fvar<RealType, Order> 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<RealType1, Order1>, fvar<RealType2, Order2>> pow(fvar<RealType1, Or
|
||||
root_type const x0 = static_cast<root_type>(x);
|
||||
root_type const y0 = static_cast<root_type>(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<RealType1, Order1>, fvar<RealType2, Order2>> pow(fvar<RealType1, Or
|
||||
lognx.front() = fvar<root_type, order>(1);
|
||||
#ifndef BOOST_NO_CXX17_IF_CONSTEXPR
|
||||
lognx[1] = log(make_fvar<root_type, order>(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<root_type, order>(x0));
|
||||
#endif
|
||||
for (size_t i = 1; i < order; ++i)
|
||||
@@ -1485,14 +1478,14 @@ fvar<RealType, Order> sqrt(fvar<RealType, Order> const& cr) {
|
||||
root_type derivatives[order + 1];
|
||||
root_type const x = static_cast<root_type>(cr);
|
||||
*derivatives = sqrt(x);
|
||||
if BOOST_AUTODIFF_IF_CONSTEXPR (order == 0)
|
||||
BOOST_IF_CONSTEXPR (order == 0)
|
||||
return fvar<RealType, Order>(*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<RealType, Order + 1>::difference_type;
|
||||
@@ -1515,10 +1508,14 @@ fvar<RealType, Order> log(fvar<RealType, Order> const& cr) {
|
||||
using root_type = typename fvar<RealType, Order>::root_type;
|
||||
constexpr size_t order = fvar<RealType, Order>::order_sum;
|
||||
root_type const d0 = log(static_cast<root_type>(cr));
|
||||
if BOOST_AUTODIFF_IF_CONSTEXPR (order == 0)
|
||||
BOOST_IF_CONSTEXPR (order == 0)
|
||||
return fvar<RealType, Order>(d0);
|
||||
else {
|
||||
#ifndef BOOST_NO_CXX17_IF_CONSTEXPR
|
||||
auto const d1 = make_fvar<root_type, order - 1>(static_cast<root_type>(cr)).inverse(); // log'(x) = 1 / x
|
||||
#else // for compilers that compile this branch when order == 0.
|
||||
auto const d1 = make_fvar<root_type, order - 0>(static_cast<root_type>(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<RealType, Order> cos(fvar<RealType, Order> const& cr) {
|
||||
using root_type = typename fvar<RealType, Order>::root_type;
|
||||
constexpr size_t order = fvar<RealType, Order>::order_sum;
|
||||
root_type const d0 = cos(static_cast<root_type>(cr));
|
||||
if BOOST_AUTODIFF_IF_CONSTEXPR (order == 0)
|
||||
BOOST_IF_CONSTEXPR (order == 0)
|
||||
return fvar<RealType, Order>(d0);
|
||||
else {
|
||||
root_type const d1 = -sin(static_cast<root_type>(cr));
|
||||
@@ -1560,7 +1557,7 @@ fvar<RealType, Order> sin(fvar<RealType, Order> const& cr) {
|
||||
using root_type = typename fvar<RealType, Order>::root_type;
|
||||
constexpr size_t order = fvar<RealType, Order>::order_sum;
|
||||
root_type const d0 = sin(static_cast<root_type>(cr));
|
||||
if BOOST_AUTODIFF_IF_CONSTEXPR (order == 0)
|
||||
BOOST_IF_CONSTEXPR (order == 0)
|
||||
return fvar<RealType, Order>(d0);
|
||||
else {
|
||||
root_type const d1 = cos(static_cast<root_type>(cr));
|
||||
@@ -1575,10 +1572,14 @@ fvar<RealType, Order> asin(fvar<RealType, Order> const& cr) {
|
||||
using root_type = typename fvar<RealType, Order>::root_type;
|
||||
constexpr size_t order = fvar<RealType, Order>::order_sum;
|
||||
root_type const d0 = asin(static_cast<root_type>(cr));
|
||||
if BOOST_AUTODIFF_IF_CONSTEXPR (order == 0)
|
||||
BOOST_IF_CONSTEXPR (order == 0)
|
||||
return fvar<RealType, Order>(d0);
|
||||
else {
|
||||
#ifndef BOOST_NO_CXX17_IF_CONSTEXPR
|
||||
auto x = make_fvar<root_type, order - 1>(static_cast<root_type>(cr));
|
||||
#else // for compilers that compile this branch when order == 0.
|
||||
auto x = make_fvar<root_type, order - 0>(static_cast<root_type>(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<RealType, Order> tan(fvar<RealType, Order> const& cr) {
|
||||
using root_type = typename fvar<RealType, Order>::root_type;
|
||||
constexpr size_t order = fvar<RealType, Order>::order_sum;
|
||||
root_type const d0 = tan(static_cast<root_type>(cr));
|
||||
if BOOST_AUTODIFF_IF_CONSTEXPR (order == 0)
|
||||
BOOST_IF_CONSTEXPR (order == 0)
|
||||
return fvar<RealType, Order>(d0);
|
||||
else {
|
||||
#ifndef BOOST_NO_CXX17_IF_CONSTEXPR
|
||||
auto c = cos(make_fvar<root_type, order - 1>(static_cast<root_type>(cr)));
|
||||
#else // for compilers that compile this branch when order == 0.
|
||||
auto c = cos(make_fvar<root_type, order - 0>(static_cast<root_type>(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<RealType, Order> atan(fvar<RealType, Order> const& cr) {
|
||||
using root_type = typename fvar<RealType, Order>::root_type;
|
||||
constexpr size_t order = fvar<RealType, Order>::order_sum;
|
||||
root_type const d0 = atan(static_cast<root_type>(cr));
|
||||
if BOOST_AUTODIFF_IF_CONSTEXPR (order == 0)
|
||||
BOOST_IF_CONSTEXPR (order == 0)
|
||||
return fvar<RealType, Order>(d0);
|
||||
else {
|
||||
#ifndef BOOST_NO_CXX17_IF_CONSTEXPR
|
||||
auto x = make_fvar<root_type, order - 1>(static_cast<root_type>(cr));
|
||||
#else // for compilers that compile this branch when order == 0.
|
||||
auto x = make_fvar<root_type, order - 0>(static_cast<root_type>(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<RealType, Order> atan2(fvar<RealType, Order> const& cr,
|
||||
using root_type = typename fvar<RealType, Order>::root_type;
|
||||
constexpr size_t order = fvar<RealType, Order>::order_sum;
|
||||
root_type const d0 = atan2(static_cast<root_type>(cr), ca);
|
||||
if BOOST_AUTODIFF_IF_CONSTEXPR (order == 0)
|
||||
BOOST_IF_CONSTEXPR (order == 0)
|
||||
return fvar<RealType, Order>(d0);
|
||||
else {
|
||||
#ifndef BOOST_NO_CXX17_IF_CONSTEXPR
|
||||
auto y = make_fvar<root_type, order - 1>(static_cast<root_type>(cr));
|
||||
#else // for compilers that compile this branch when order == 0.
|
||||
auto y = make_fvar<root_type, order - 0>(static_cast<root_type>(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<RealType, Order> atan2(typename fvar<RealType, Order>::root_type const& ca,
|
||||
using root_type = typename fvar<RealType, Order>::root_type;
|
||||
constexpr size_t order = fvar<RealType, Order>::order_sum;
|
||||
root_type const d0 = atan2(ca, static_cast<root_type>(cr));
|
||||
if BOOST_AUTODIFF_IF_CONSTEXPR (order == 0)
|
||||
BOOST_IF_CONSTEXPR (order == 0)
|
||||
return fvar<RealType, Order>(d0);
|
||||
else {
|
||||
#ifndef BOOST_NO_CXX17_IF_CONSTEXPR
|
||||
auto x = make_fvar<root_type, order - 1>(static_cast<root_type>(cr));
|
||||
#else // for compilers that compile this branch when order == 0.
|
||||
auto x = make_fvar<root_type, order - 0>(static_cast<root_type>(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<RealType1, Order1>, fvar<RealType2, Order2>> atan2(fvar<RealType1,
|
||||
root_type const y = static_cast<root_type>(cr1);
|
||||
root_type const x = static_cast<root_type>(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<RealType1, Order1>::order_sum;
|
||||
@@ -1746,10 +1763,14 @@ fvar<RealType, Order> acos(fvar<RealType, Order> const& cr) {
|
||||
using root_type = typename fvar<RealType, Order>::root_type;
|
||||
constexpr size_t order = fvar<RealType, Order>::order_sum;
|
||||
root_type const d0 = acos(static_cast<root_type>(cr));
|
||||
if BOOST_AUTODIFF_IF_CONSTEXPR (order == 0)
|
||||
BOOST_IF_CONSTEXPR (order == 0)
|
||||
return fvar<RealType, Order>(d0);
|
||||
else {
|
||||
#ifndef BOOST_NO_CXX17_IF_CONSTEXPR
|
||||
auto x = make_fvar<root_type, order - 1>(static_cast<root_type>(cr));
|
||||
#else // for compilers that compile this branch when order == 0.
|
||||
auto x = make_fvar<root_type, order - 0>(static_cast<root_type>(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<RealType, Order> acosh(fvar<RealType, Order> const& cr) {
|
||||
using root_type = typename fvar<RealType, Order>::root_type;
|
||||
constexpr size_t order = fvar<RealType, Order>::order_sum;
|
||||
root_type const d0 = acosh(static_cast<root_type>(cr));
|
||||
if BOOST_AUTODIFF_IF_CONSTEXPR (order == 0)
|
||||
BOOST_IF_CONSTEXPR (order == 0)
|
||||
return fvar<RealType, Order>(d0);
|
||||
else {
|
||||
#ifndef BOOST_NO_CXX17_IF_CONSTEXPR
|
||||
auto x = make_fvar<root_type, order - 1>(static_cast<root_type>(cr));
|
||||
#else // for compilers that compile this branch when order == 0.
|
||||
auto x = make_fvar<root_type, order - 0>(static_cast<root_type>(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<RealType, Order> asinh(fvar<RealType, Order> const& cr) {
|
||||
using root_type = typename fvar<RealType, Order>::root_type;
|
||||
constexpr size_t order = fvar<RealType, Order>::order_sum;
|
||||
root_type const d0 = asinh(static_cast<root_type>(cr));
|
||||
if BOOST_AUTODIFF_IF_CONSTEXPR (order == 0)
|
||||
BOOST_IF_CONSTEXPR (order == 0)
|
||||
return fvar<RealType, Order>(d0);
|
||||
else {
|
||||
#ifndef BOOST_NO_CXX17_IF_CONSTEXPR
|
||||
auto x = make_fvar<root_type, order - 1>(static_cast<root_type>(cr));
|
||||
#else // for compilers that compile this branch when order == 0.
|
||||
auto x = make_fvar<root_type, order - 0>(static_cast<root_type>(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<RealType, Order> atanh(fvar<RealType, Order> const& cr) {
|
||||
using root_type = typename fvar<RealType, Order>::root_type;
|
||||
constexpr size_t order = fvar<RealType, Order>::order_sum;
|
||||
root_type const d0 = atanh(static_cast<root_type>(cr));
|
||||
if BOOST_AUTODIFF_IF_CONSTEXPR (order == 0)
|
||||
BOOST_IF_CONSTEXPR (order == 0)
|
||||
return fvar<RealType, Order>(d0);
|
||||
else {
|
||||
#ifndef BOOST_NO_CXX17_IF_CONSTEXPR
|
||||
auto x = make_fvar<root_type, order - 1>(static_cast<root_type>(cr));
|
||||
#else // for compilers that compile this branch when order == 0.
|
||||
auto x = make_fvar<root_type, order - 0>(static_cast<root_type>(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<RealType, Order> cosh(fvar<RealType, Order> const& cr) {
|
||||
using root_type = typename fvar<RealType, Order>::root_type;
|
||||
constexpr size_t order = fvar<RealType, Order>::order_sum;
|
||||
root_type const d0 = cosh(static_cast<root_type>(cr));
|
||||
if BOOST_AUTODIFF_IF_CONSTEXPR (order == 0)
|
||||
BOOST_IF_CONSTEXPR (order == 0)
|
||||
return fvar<RealType, Order>(d0);
|
||||
else {
|
||||
root_type const derivatives[2]{d0, sinh(static_cast<root_type>(cr))};
|
||||
@@ -1821,7 +1854,7 @@ fvar<RealType, Order> digamma(fvar<RealType, Order> const& cr) {
|
||||
constexpr size_t order = fvar<RealType, Order>::order_sum;
|
||||
root_type const x = static_cast<root_type>(cr);
|
||||
root_type const d0 = digamma(x);
|
||||
if BOOST_AUTODIFF_IF_CONSTEXPR (order == 0)
|
||||
BOOST_IF_CONSTEXPR (order == 0)
|
||||
return fvar<RealType, Order>(d0);
|
||||
else {
|
||||
static_assert(order <= static_cast<size_t>((std::numeric_limits<int>::max)()),
|
||||
@@ -1837,10 +1870,14 @@ fvar<RealType, Order> erf(fvar<RealType, Order> const& cr) {
|
||||
using root_type = typename fvar<RealType, Order>::root_type;
|
||||
constexpr size_t order = fvar<RealType, Order>::order_sum;
|
||||
root_type const d0 = erf(static_cast<root_type>(cr));
|
||||
if BOOST_AUTODIFF_IF_CONSTEXPR (order == 0)
|
||||
BOOST_IF_CONSTEXPR (order == 0)
|
||||
return fvar<RealType, Order>(d0);
|
||||
else {
|
||||
#ifndef BOOST_NO_CXX17_IF_CONSTEXPR
|
||||
auto x = make_fvar<root_type, order - 1>(static_cast<root_type>(cr)); // d1 = 2/sqrt(pi)*exp(-x*x)
|
||||
#else // for compilers that compile this branch when order == 0.
|
||||
auto x = make_fvar<root_type, order - 0>(static_cast<root_type>(cr)); // d1 = 2/sqrt(pi)*exp(-x*x)
|
||||
#endif
|
||||
auto const d1 = 2 * constants::one_div_root_pi<root_type>() * 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<RealType, Order> erfc(fvar<RealType, Order> const& cr) {
|
||||
using root_type = typename fvar<RealType, Order>::root_type;
|
||||
constexpr size_t order = fvar<RealType, Order>::order_sum;
|
||||
root_type const d0 = erfc(static_cast<root_type>(cr));
|
||||
if BOOST_AUTODIFF_IF_CONSTEXPR (order == 0)
|
||||
BOOST_IF_CONSTEXPR (order == 0)
|
||||
return fvar<RealType, Order>(d0);
|
||||
else {
|
||||
#ifndef BOOST_NO_CXX17_IF_CONSTEXPR
|
||||
auto x = make_fvar<root_type, order - 1>(static_cast<root_type>(cr)); // erfc'(x) = -erf'(x)
|
||||
#else // for compilers that compile this branch when order == 0.
|
||||
auto x = make_fvar<root_type, order - 0>(static_cast<root_type>(cr)); // erfc'(x) = -erf'(x)
|
||||
#endif
|
||||
auto const d1 = -2 * constants::one_div_root_pi<root_type>() * 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<RealType, Order> lambert_w0(fvar<RealType, Order> const& cr) {
|
||||
constexpr size_t order = fvar<RealType, Order>::order_sum;
|
||||
root_type derivatives[order + 1];
|
||||
*derivatives = lambert_w0(static_cast<root_type>(cr));
|
||||
if BOOST_AUTODIFF_IF_CONSTEXPR (order == 0)
|
||||
BOOST_IF_CONSTEXPR (order == 0)
|
||||
return fvar<RealType, Order>(*derivatives);
|
||||
else {
|
||||
root_type const expw = exp(*derivatives);
|
||||
derivatives[1] = 1 / (static_cast<root_type>(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<RealType, Order + 1>::difference_type;
|
||||
@@ -1906,7 +1947,7 @@ fvar<RealType, Order> lgamma(fvar<RealType, Order> const& cr) {
|
||||
constexpr size_t order = fvar<RealType, Order>::order_sum;
|
||||
root_type const x = static_cast<root_type>(cr);
|
||||
root_type const d0 = lgamma(x);
|
||||
if BOOST_AUTODIFF_IF_CONSTEXPR (order == 0)
|
||||
BOOST_IF_CONSTEXPR (order == 0)
|
||||
return fvar<RealType, Order>(d0);
|
||||
else {
|
||||
static_assert(order <= static_cast<size_t>((std::numeric_limits<int>::max)()) + 1,
|
||||
@@ -1923,7 +1964,7 @@ fvar<RealType, Order> sinc(fvar<RealType, Order> const& cr) {
|
||||
using root_type = typename fvar<RealType, Order>::root_type;
|
||||
constexpr size_t order = fvar<RealType, Order>::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<RealType, Order>(*taylor);
|
||||
else {
|
||||
for (size_t n = 2; n <= order; n += 2)
|
||||
@@ -1938,7 +1979,7 @@ fvar<RealType, Order> sinh(fvar<RealType, Order> const& cr) {
|
||||
using root_type = typename fvar<RealType, Order>::root_type;
|
||||
constexpr size_t order = fvar<RealType, Order>::order_sum;
|
||||
root_type const d0 = sinh(static_cast<root_type>(cr));
|
||||
if BOOST_AUTODIFF_IF_CONSTEXPR (fvar<RealType, Order>::order_sum == 0)
|
||||
BOOST_IF_CONSTEXPR (fvar<RealType, Order>::order_sum == 0)
|
||||
return fvar<RealType, Order>(d0);
|
||||
else {
|
||||
root_type const derivatives[2]{d0, cosh(static_cast<root_type>(cr))};
|
||||
@@ -1959,7 +2000,7 @@ fvar<RealType, Order> tgamma(fvar<RealType, Order> const& cr) {
|
||||
using std::tgamma;
|
||||
using root_type = typename fvar<RealType, Order>::root_type;
|
||||
constexpr size_t order = fvar<RealType, Order>::order_sum;
|
||||
if BOOST_AUTODIFF_IF_CONSTEXPR (order == 0)
|
||||
BOOST_IF_CONSTEXPR (order == 0)
|
||||
return fvar<RealType, Order>(tgamma(static_cast<root_type>(cr)));
|
||||
else {
|
||||
if (cr < 0)
|
||||
|
||||
Reference in New Issue
Block a user