summaryrefslogtreecommitdiff
path: root/sal
diff options
context:
space:
mode:
authorEike Rathke <erack@redhat.com>2015-10-24 22:44:25 +0200
committerEike Rathke <erack@redhat.com>2015-10-24 22:46:03 +0000
commita62bc6a65abb47adb0e4caff7e38823c15b302fc (patch)
treee13ad9edb8d9eb793f02171807e71df1f4aa19cd /sal
parent14cd70ba5af2dcd47dbeafe9cbbb43662448d454 (diff)
replace implementation of rtl_math_erf() and rtl_math_erfc()
... with ::std::erf() and ::std::erfc() of C++11 Change-Id: I8ccc86ec4d6d71a92409770fc119f72e7084073a Reviewed-on: https://gerrit.libreoffice.org/19583 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Eike Rathke <erack@redhat.com> Tested-by: Eike Rathke <erack@redhat.com>
Diffstat (limited to 'sal')
-rw-r--r--sal/rtl/math.cxx229
1 files changed, 4 insertions, 225 deletions
diff --git a/sal/rtl/math.cxx b/sal/rtl/math.cxx
index 3ec6fe0d489d..5a624e10ccc2 100644
--- a/sal/rtl/math.cxx
+++ b/sal/rtl/math.cxx
@@ -68,131 +68,6 @@ static double getN10Exp( int nExp )
return 1.0;
}
-/** Approximation algorithm for erf for 0 < x < 0.65. */
-static void lcl_Erf0065( double x, double& fVal )
-{
- static const double pn[] = {
- 1.12837916709551256,
- 1.35894887627277916E-1,
- 4.03259488531795274E-2,
- 1.20339380863079457E-3,
- 6.49254556481904354E-5
- };
- static const double qn[] = {
- 1.00000000000000000,
- 4.53767041780002545E-1,
- 8.69936222615385890E-2,
- 8.49717371168693357E-3,
- 3.64915280629351082E-4
- };
- double fPSum = 0.0;
- double fQSum = 0.0;
- double fXPow = 1.0;
- for ( unsigned int i = 0; i <= 4; ++i )
- {
- fPSum += pn[i]*fXPow;
- fQSum += qn[i]*fXPow;
- fXPow *= x*x;
- }
- fVal = x * fPSum / fQSum;
-}
-
-/** Approximation algorithm for erfc for 0.65 < x < 6.0. */
-static void lcl_Erfc0600( double x, double& fVal )
-{
- double fPSum = 0.0;
- double fQSum = 0.0;
- double fXPow = 1.0;
- const double *pn;
- const double *qn;
-
- if ( x < 2.2 )
- {
- static const double pn22[] = {
- 9.99999992049799098E-1,
- 1.33154163936765307,
- 8.78115804155881782E-1,
- 3.31899559578213215E-1,
- 7.14193832506776067E-2,
- 7.06940843763253131E-3
- };
- static const double qn22[] = {
- 1.00000000000000000,
- 2.45992070144245533,
- 2.65383972869775752,
- 1.61876655543871376,
- 5.94651311286481502E-1,
- 1.26579413030177940E-1,
- 1.25304936549413393E-2
- };
- pn = pn22;
- qn = qn22;
- }
- else /* if ( x < 6.0 ) this is true, but the compiler does not know */
- {
- static const double pn60[] = {
- 9.99921140009714409E-1,
- 1.62356584489366647,
- 1.26739901455873222,
- 5.81528574177741135E-1,
- 1.57289620742838702E-1,
- 2.25716982919217555E-2
- };
- static const double qn60[] = {
- 1.00000000000000000,
- 2.75143870676376208,
- 3.37367334657284535,
- 2.38574194785344389,
- 1.05074004614827206,
- 2.78788439273628983E-1,
- 4.00072964526861362E-2
- };
- pn = pn60;
- qn = qn60;
- }
-
- for ( unsigned int i = 0; i < 6; ++i )
- {
- fPSum += pn[i]*fXPow;
- fQSum += qn[i]*fXPow;
- fXPow *= x;
- }
- fQSum += qn[6]*fXPow;
- fVal = exp( -1.0*x*x )* fPSum / fQSum;
-}
-
-/** Approximation algorithm for erfc for 6.0 < x < 26.54 (but used for all
- x > 6.0). */
-static void lcl_Erfc2654( double x, double& fVal )
-{
- static const double pn[] = {
- 5.64189583547756078E-1,
- 8.80253746105525775,
- 3.84683103716117320E1,
- 4.77209965874436377E1,
- 8.08040729052301677
- };
- static const double qn[] = {
- 1.00000000000000000,
- 1.61020914205869003E1,
- 7.54843505665954743E1,
- 1.12123870801026015E2,
- 3.73997570145040850E1
- };
-
- double fPSum = 0.0;
- double fQSum = 0.0;
- double fXPow = 1.0;
-
- for ( unsigned int i = 0; i <= 4; ++i )
- {
- fPSum += pn[i]*fXPow;
- fQSum += qn[i]*fXPow;
- fXPow /= x*x;
- }
- fVal = exp(-1.0*x*x)*fPSum / (x*fQSum);
-}
-
namespace {
double const nKorrVal[] = {
@@ -1166,112 +1041,16 @@ double SAL_CALL rtl_math_atanh( double fValue ) SAL_THROW_EXTERN_C()
return 0.5 * rtl_math_log1p( 2.0 * fValue / (1.0-fValue) );
}
-/** Parent error function (erf) that calls different algorithms based on the
- value of x. It takes care of cases where x is negative as erf is an odd
- function i.e. erf(-x) = -erf(x).
-
- Kramer, W., and Blomquist, F., 2000, Algorithms with Guaranteed Error Bounds
- for the Error Function and the Complementary Error Function
-
- http://www.math.uni-wuppertal.de/wrswt/literatur_en.html
-
- @author Kohei Yoshida <kohei@openoffice.org>
-
- @see #i55735#
- */
+/** Parent error function (erf) */
double SAL_CALL rtl_math_erf( double x ) SAL_THROW_EXTERN_C()
{
- if( x == 0.0 )
- return 0.0;
-
- // Otherwise we may end up in endless recursion through rtl_math_erfc().
- if (!::rtl::math::isFinite(x))
- {
- // See http://en.cppreference.com/w/cpp/numeric/math/erf
- if (::rtl::math::isInf(x))
- {
- if (::rtl::math::isSignBitSet(x))
- return -1.0;
- else
- return 1.0;
- }
- // It is a NaN.
- return x;
- }
-
- bool bNegative = false;
- if ( x < 0.0 )
- {
- x = fabs( x );
- bNegative = true;
- }
-
- double fErf = 1.0;
- if ( x < 1.0e-10 )
- fErf = (double) (x*1.1283791670955125738961589031215452L);
- else if ( x < 0.65 )
- lcl_Erf0065( x, fErf );
- else
- fErf = 1.0 - rtl_math_erfc( x );
-
- if ( bNegative )
- fErf *= -1.0;
-
- return fErf;
+ return ::std::erf(x);
}
-/** Parent complementary error function (erfc) that calls different algorithms
- based on the value of x. It takes care of cases where x is negative as erfc
- satisfies relationship erfc(-x) = 2 - erfc(x). See the comment for Erf(x)
- for the source publication.
-
- @author Kohei Yoshida <kohei@openoffice.org>
-
- @see #i55735#, moved from module scaddins (#i97091#)
-
- */
+/** Parent complementary error function (erfc) */
double SAL_CALL rtl_math_erfc( double x ) SAL_THROW_EXTERN_C()
{
- if ( x == 0.0 )
- return 1.0;
-
- // Otherwise we may end up in endless recursion through rtl_math_erf().
- if (!::rtl::math::isFinite(x))
- {
- // See http://en.cppreference.com/w/cpp/numeric/math/erfc
- if (::rtl::math::isInf(x))
- {
- if (::rtl::math::isSignBitSet(x))
- return 2.0;
- else
- return 0.0;
- }
- // It is a NaN.
- return x;
- }
-
- bool bNegative = false;
- if ( x < 0.0 )
- {
- x = fabs( x );
- bNegative = true;
- }
-
- double fErfc = 0.0;
- if ( x >= 0.65 )
- {
- if ( x < 6.0 )
- lcl_Erfc0600( x, fErfc );
- else
- lcl_Erfc2654( x, fErfc );
- }
- else
- fErfc = 1.0 - rtl_math_erf( x );
-
- if ( bNegative )
- fErfc = 2.0 - fErfc;
-
- return fErfc;
+ return ::std::erfc(x);
}
/** improved accuracy of asinh for |x| large and for x near zero