Thanks to visit codestin.com
Credit goes to github.com

Skip to content

BUG: Overflow in tan and tanh for large complex values #5510

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 51 additions & 1 deletion numpy/core/include/numpy/npy_math.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,9 @@ double npy_copysign(double x, double y);
double npy_nextafter(double x, double y);
double npy_spacing(double x);

double npy_ldexp(double x, int exp);
double npy_frexp(double x, int* exp);

/*
* IEEE 754 fpu handling. Those are guaranteed to be macros
*/
Expand Down Expand Up @@ -258,8 +261,11 @@ float npy_copysignf(float x, float y);
float npy_nextafterf(float x, float y);
float npy_spacingf(float x);

float npy_ldexpf(float x, int exp);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

npy_ldexp and npy_frexp in all three flavors already exist in master. These came in as part of #4852, which pulled the ldexp and frexp changes from this.

float npy_frexpf(float x, int* exp);

/*
* float C99 math functions
* long double C99 math functions
*/

npy_longdouble npy_sinl(npy_longdouble x);
Expand Down Expand Up @@ -302,6 +308,9 @@ npy_longdouble npy_copysignl(npy_longdouble x, npy_longdouble y);
npy_longdouble npy_nextafterl(npy_longdouble x, npy_longdouble y);
npy_longdouble npy_spacingl(npy_longdouble x);

npy_longdouble npy_ldexpl(npy_longdouble x, int exp);
npy_longdouble npy_frexpl(npy_longdouble x, int* exp);

/*
* Non standard functions
*/
Expand Down Expand Up @@ -425,6 +434,19 @@ npy_cdouble npy_csqrt(npy_cdouble z);

npy_cdouble npy_ccos(npy_cdouble z);
npy_cdouble npy_csin(npy_cdouble z);
npy_cdouble npy_ctan(npy_cdouble z);

npy_cdouble npy_ccosh(npy_cdouble z);
npy_cdouble npy_csinh(npy_cdouble z);
npy_cdouble npy_ctanh(npy_cdouble z);

npy_cdouble npy_cacos(npy_cdouble z);
npy_cdouble npy_casin(npy_cdouble z);
npy_cdouble npy_catan(npy_cdouble z);

npy_cdouble npy_cacosh(npy_cdouble z);
npy_cdouble npy_casinh(npy_cdouble z);
npy_cdouble npy_catanh(npy_cdouble z);

/*
* Single precision complex functions
Expand All @@ -440,6 +462,20 @@ npy_cfloat npy_csqrtf(npy_cfloat z);

npy_cfloat npy_ccosf(npy_cfloat z);
npy_cfloat npy_csinf(npy_cfloat z);
npy_cfloat npy_ctanf(npy_cfloat z);

npy_cfloat npy_ccoshf(npy_cfloat z);
npy_cfloat npy_csinhf(npy_cfloat z);
npy_cfloat npy_ctanhf(npy_cfloat z);

npy_cfloat npy_cacosf(npy_cfloat z);
npy_cfloat npy_casinf(npy_cfloat z);
npy_cfloat npy_catanf(npy_cfloat z);

npy_cfloat npy_cacoshf(npy_cfloat z);
npy_cfloat npy_casinhf(npy_cfloat z);
npy_cfloat npy_catanhf(npy_cfloat z);


/*
* Extended precision complex functions
Expand All @@ -455,6 +491,20 @@ npy_clongdouble npy_csqrtl(npy_clongdouble z);

npy_clongdouble npy_ccosl(npy_clongdouble z);
npy_clongdouble npy_csinl(npy_clongdouble z);
npy_clongdouble npy_ctanl(npy_clongdouble z);

npy_clongdouble npy_ccoshl(npy_clongdouble z);
npy_clongdouble npy_csinhl(npy_clongdouble z);
npy_clongdouble npy_ctanhl(npy_clongdouble z);

npy_clongdouble npy_cacosl(npy_clongdouble z);
npy_clongdouble npy_casinl(npy_clongdouble z);
npy_clongdouble npy_catanl(npy_clongdouble z);

npy_clongdouble npy_cacoshl(npy_clongdouble z);
npy_clongdouble npy_casinhl(npy_clongdouble z);
npy_clongdouble npy_catanhl(npy_clongdouble z);


/*
* Functions that set the floating point error
Expand Down
39 changes: 38 additions & 1 deletion numpy/core/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,32 @@ def check_prec(prec):
else:
priv.extend([(fname2def(f), 1) for f in flist])

flist = [f + prec for f in C99_COMPLEX_FUNCS_CHECKED]
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes me wonder if these tests shouldn't be done in python.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There was some discussion of using ctypes to call these functions from python. I didn't go down that route since we then need to find libc ourselves, but doing it this way allowed the tool chain to find it for us. I suppose we could make a tiny module that simply exposes them to python and then use that for the tests.

decl = dict([(f, True) for f in flist])
exists = []
if not config.check_funcs_once(flist, call=decl, decl=decl,
libraries=mathlibs):
for f in C99_COMPLEX_FUNCS_CHECKED:
if config.check_func(f + prec, call=True, decl=True,
libraries=mathlibs):
exists.append(f)
else:
exists.extend(C99_COMPLEX_FUNCS_CHECKED)

if len(exists) > 0:
fp = open(join('.', 'numpy', 'core', 'src', 'npymath',
'test_c99complex.c'), 'r')
obody = fp.read()
fp.close()
precname = {'f':'FLOAT', '':'DOUBLE', 'l':'LONGDOUBLE'}[prec]
for f in exists:
body = obody.replace('PYTESTPRECISION', precname) \
.replace('PYTESTFUNC', f.upper())
inc_dir = join('.', 'numpy', 'core', 'src', 'npymath')
if config.try_run(body, libraries=mathlibs,
include_dirs=[inc_dir]):
priv.append((fname2def(f + prec), 1))

check_prec('')
check_prec('f')
check_prec('l')
Expand Down Expand Up @@ -683,7 +709,8 @@ def get_mathlib_info(*args):
npymath_sources = [join('src', 'npymath', 'npy_math.c.src'),
join('src', 'npymath', 'ieee754.c.src'),
join('src', 'npymath', 'npy_math_complex.c.src'),
join('src', 'npymath', 'halffloat.c')]
join('src', 'npymath', 'halffloat.c'),
join('src', 'npymath', 'fpstatus.c')]
config.add_installed_library('npymath',
sources=npymath_sources + [get_mathlib_info],
install_dir='lib')
Expand Down Expand Up @@ -973,6 +1000,16 @@ def generate_umath_c(ext, build_dir):
config.add_extension('operand_flag_tests',
sources = [join('src', 'umath', 'operand_flag_tests.c.src')])

#######################################################################
# npymath_tests module #
#######################################################################

config.add_extension('npymath_tests',
sources = [join('src', 'npymath', 'npymath_tests.c')],
depends = ['test_c99complex.c'],
libraries = ['npymath']
)

config.add_data_dir('tests')
config.add_data_dir('tests/data')

Expand Down
6 changes: 4 additions & 2 deletions numpy/core/setup_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,10 @@ def check_api_version(apiversion, codegen_dir):

C99_COMPLEX_TYPES = ['complex double', 'complex float', 'complex long double']

C99_COMPLEX_FUNCS = ['creal', 'cimag', 'cabs', 'carg', 'cexp', 'csqrt', 'clog',
'ccos', 'csin', 'cpow']
C99_COMPLEX_FUNCS = ['creal', 'cimag', 'cabs', 'carg']
C99_COMPLEX_FUNCS_CHECKED = ['cacos', 'casin', 'catan', 'cacosh', 'casinh',
'catanh', 'ccos', 'csin', 'ctan', 'ccosh', 'csinh',
'ctanh', 'cexp', 'clog', 'cpow', 'csqrt']

def fname2def(name):
return "HAVE_%s" % name.upper()
Expand Down
Loading