Skip to content

Commit

Permalink
ENH: improve erf performance by unroll loops and __builtin_isnan
Browse files Browse the repository at this point in the history
Unrolling polynomial evaluations and replace isnan with builtin to
double speed up erf(|x| < 1) and erfc by about 30%.
GCC does unfortunately not replace isnan with builtins automatically.
  • Loading branch information
juliantaylor committed Mar 21, 2015
1 parent a784547 commit f9e381b
Showing 1 changed file with 13 additions and 3 deletions.
16 changes: 13 additions & 3 deletions scipy/special/cephes/ndtr.c
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,16 @@
#include <float.h> /* DBL_EPSILON */
#include "mconf.h"

#if !defined(__clang__) && defined(__GNUC__) && defined(__GNUC_MINOR__)
#if __GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)
#pragma GCC optimize("unroll-loops")
#define cephes_isnan(x) __builtin_isnan(x)
#endif
#endif
#ifndef cephes_isnan
#define cephes_isnan(x) npy_isnan(x)
#endif


extern double SQRTH;
extern double MAXLOG;
Expand Down Expand Up @@ -408,7 +418,7 @@ double ndtr(double a)
{
double x, y, z;

if (npy_isnan(a)) {
if (cephes_isnan(a)) {
mtherr("ndtr", DOMAIN);
return (NPY_NAN);
}
Expand All @@ -434,7 +444,7 @@ double erfc(double a)
{
double p, q, x, y, z;

if (npy_isnan(a)) {
if (cephes_isnan(a)) {
mtherr("erfc", DOMAIN);
return (NPY_NAN);
}
Expand Down Expand Up @@ -485,7 +495,7 @@ double erf(double x)
{
double y, z;

if (npy_isnan(x)) {
if (cephes_isnan(x)) {
mtherr("erf", DOMAIN);
return (NPY_NAN);
}
Expand Down

0 comments on commit f9e381b

Please sign in to comment.