summaryrefslogtreecommitdiff
path: root/boost/math/special_functions/ellint_1.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/math/special_functions/ellint_1.hpp')
-rw-r--r--boost/math/special_functions/ellint_1.hpp14
1 files changed, 13 insertions, 1 deletions
diff --git a/boost/math/special_functions/ellint_1.hpp b/boost/math/special_functions/ellint_1.hpp
index da16bc6f26..62a0bf3fde 100644
--- a/boost/math/special_functions/ellint_1.hpp
+++ b/boost/math/special_functions/ellint_1.hpp
@@ -103,10 +103,22 @@ T ellint_f_imp(T phi, T k, const Policy& pol)
BOOST_MATH_INSTRUMENT_VARIABLE(rphi);
}
T sinp = sin(rphi);
+ sinp *= sinp;
T cosp = cos(rphi);
+ cosp *= cosp;
+ T c = 1 / sinp;
BOOST_MATH_INSTRUMENT_VARIABLE(sinp);
BOOST_MATH_INSTRUMENT_VARIABLE(cosp);
- result = s * sinp * ellint_rf_imp(T(cosp * cosp), T(1 - k * k * sinp * sinp), T(1), pol);
+ if(sinp > tools::min_value<T>())
+ {
+ //
+ // Use http://dlmf.nist.gov/19.25#E5, note that
+ // c-1 simplifies to cot^2(rphi) which avoid cancellation:
+ //
+ result = rphi == 0 ? static_cast<T>(0) : static_cast<T>(s * ellint_rf_imp(T(cosp / sinp), T(c - k * k), c, pol));
+ }
+ else
+ result = s * sin(rphi);
BOOST_MATH_INSTRUMENT_VARIABLE(result);
if(m != 0)
{