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

Skip to content

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

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 35 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
9e7be8c
BUG: Overflow in tan and tanh for large complex values
ewmoore Feb 22, 2013
f442ead
STY: npymath: tabs -> spaces, long lines
ewmoore Mar 1, 2013
d62c590
ENH: Check for, and use all C99 complex functions if available
ewmoore Mar 6, 2013
af5ff55
ENH: npymath: Use a better complex division algorithm.
ewmoore Mar 8, 2013
e6b99c9
MAINT: umath: generate the ldexp and frexp ufuncs like all the others.
ewmoore Mar 9, 2013
0fdaa54
MAINT: umath/npymath: Add ldexp and frexp to npymath
ewmoore Mar 9, 2013
2d33f7c
ENH: npymath: handle clog edge cases more carefully.
ewmoore Mar 10, 2013
50d6720
ENH: evaluate c99 complex funcs at build time
ewmoore Oct 1, 2013
d504ea1
BUG: NPY_LOGE2 is log(2)
ewmoore Oct 2, 2013
5362b35
BUG: Test aginst +/-TANH_HUGE
ewmoore Oct 2, 2013
e61e74f
TST: check for tanh(1000+0j) == 1 + 0j etc.
ewmoore Oct 2, 2013
852cd10
BUG: Fix up some corner cases in npy_cexp
ewmoore Oct 2, 2013
0f57b42
MAINT: remove debug print statement
ewmoore Oct 2, 2013
eb06557
MAINT: fix two typos in test_c99complex.c
ewmoore Oct 4, 2013
77705ab
ENH: Be more careful with large real parts in npy_cexp
ewmoore Oct 4, 2013
e574e29
ENH: Import the ccosh/ccos implementation from FreeBSD
ewmoore Oct 4, 2013
3710481
ENH: Import the csinh/csin implementation from FreeBSD
ewmoore Oct 4, 2013
a837853
ENH: Import the catanh/catan implemenation from FreeBSD
ewmoore Oct 9, 2013
36e0d8b
BUG: printf requires a literal for the first argument.
ewmoore Oct 9, 2013
330b54a
BUG: Py3 '-2j' is (NZERO - 2j) causes test failures
ewmoore Oct 9, 2013
def6327
ENH: Import the cacos,casin,cacosh,casinh implemenation from FreeBSD
ewmoore Oct 10, 2013
c8f13ee
TST: Enable signed zero branch cut tests
ewmoore Oct 10, 2013
eab5228
BUG: fix cpow tests to match what npy_cpow does.
ewmoore Oct 10, 2013
2b5f1ad
STY: long lines, whitespace
ewmoore Oct 10, 2013
1fb1b74
MAINT: remove gccisms and unbreak MSVC build.
ewmoore Oct 11, 2013
be42cae
MAINT: fix ldexp/frexp changes to compile with MSVC.
ewmoore Oct 11, 2013
ac075b2
MAINT: npy_a(exp,log,sqrt,fabs) don't really exist.
ewmoore Oct 15, 2013
79afefd
ENH: Run the test_c99complex.c tests with the test suite too.
ewmoore Oct 16, 2013
cfe9fcc
BUG: Fix tests to compile under MSVC
ewmoore Oct 21, 2013
cbc97fa
MAINT: pick sunmath.h from npy_math.h
ewmoore Oct 21, 2013
863d97d
MAINT: Update note about FreeBSD.
ewmoore Oct 22, 2013
2348023
MAINT: make sure npy_math builds when long double is double double
ewmoore Oct 24, 2013
5771dae
MAINT: move npy_(get,clear)_floatstatus() to their own file.
ewmoore Nov 7, 2013
566c15e
BUG Use the floating point status functions in build time tests
ewmoore Nov 7, 2013
503047b
MAINT: move test_c99complex.c to npymath
ewmoore Nov 7, 2013
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
38 changes: 36 additions & 2 deletions numpy/core/code_generators/generate_umath.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,20 @@
class FullTypeDescr(object):
pass

class FuncNameSuffix(object):
"""Stores the suffix to append when generating function names.
"""
def __init__(self, suffix):
self.suffix = suffix

class TypeDescription(object):
"""Type signature for a ufunc.

Attributes
----------
type : str
Character representing the nominal type.
func_data : str or None or FullTypeDescr, optional
func_data : str or None or FullTypeDescr or FuncNameSuffix, optional
The string representing the expression to insert into the data array, if
any.
in_ : str or None, optional
Expand Down Expand Up @@ -795,6 +801,30 @@ def english_upper(s):
None,
TD(flts),
),
'ldexp' :
Ufunc(2, 1, None,
docstrings.get('numpy.core.umath.ldexp'),
None,
[TypeDescription('e', None, 'ei', 'e'),
TypeDescription('f', None, 'fi', 'f'),
TypeDescription('e', FuncNameSuffix('long'), 'el', 'e'),
TypeDescription('f', FuncNameSuffix('long'), 'fl', 'f'),
TypeDescription('d', None, 'di', 'd'),
TypeDescription('d', FuncNameSuffix('long'), 'dl', 'd'),
TypeDescription('g', None, 'gi', 'g'),
TypeDescription('g', FuncNameSuffix('long'), 'gl', 'g'),
],
),
'frexp' :
Ufunc(1, 2, None,
docstrings.get('numpy.core.umath.frexp'),
None,
[TypeDescription('e', None, 'e', 'ei'),
TypeDescription('f', None, 'f', 'fi'),
TypeDescription('d', None, 'd', 'di'),
TypeDescription('g', None, 'g', 'gi'),
],
)
}

if sys.version_info[0] >= 3:
Expand Down Expand Up @@ -854,7 +884,7 @@ def make_arrays(funcdict):
thedict = chartotype1 # one input and one output

for t in uf.type_descriptions:
if t.func_data not in (None, FullTypeDescr):
if t.func_data not in (None, FullTypeDescr) and not isinstance(t.func_data, FuncNameSuffix):
funclist.append('NULL')
astype = ''
if not t.astype is None:
Expand All @@ -880,6 +910,10 @@ def make_arrays(funcdict):
tname = english_upper(chartoname[t.type])
datalist.append('(void *)NULL')
funclist.append('%s_%s_%s_%s' % (tname, t.in_, t.out, name))
elif isinstance(t.func_data, FuncNameSuffix):
datalist.append('(void *)NULL')
tname = english_upper(chartoname[t.type])
funclist.append('%s_%s_%s' % (tname, name, t.func_data.suffix))
else:
datalist.append('(void *)NULL')
tname = english_upper(chartoname[t.type])
Expand Down
62 changes: 62 additions & 0 deletions numpy/core/code_generators/ufunc_docstrings.py
Original file line number Diff line number Diff line change
Expand Up @@ -3312,3 +3312,65 @@ def add_newdoc(place, name, doc):
array([0, 0, 0, 0, 1])

""")

add_newdoc('numpy.core.umath', 'ldexp',
"""
Scale floating point value by a power of 2, element-wise.

Equivalent to ``x1 * 2**x2``.

Parameters
----------
x1 : array_like
Input array to be scaled.
x2 : array_like
Input array of exponents.

Returns
-------
y: ndarray
The corresponding scaled values.

See Also
--------
frexp : Extract significand and exponent from floating point number

Examples
--------
>>> np.ldexp(0.5, np.arange(-1,4))
array([ 0.25, 0.5 , 1. , 2. , 4. ])

""")

add_newdoc('numpy.core.umath', 'frexp',
"""
Extract significand and exponent from a floating point number.

All floating point numbers are of the form: ``y1 * 2**y2`` where `y1`,
the significand, is a number between 0.5 and 1, or 0 and `y2`, the
exponent, is an integer.

Parameters
----------
x: array_like
Input array.

Returns
-------
y1 : ndarray
The normalized significands from `x`.
y2 : ndarray
The exponents from `x`.

See Also
--------
ldexp : Scale floating point number by power of 2

Examples
--------
>>> np.frexp([0.25, 0.5, 1, 2, 4])
(array([ 0.5, 0.5, 0.5, 0.5, 0.5]),
array([-1, 0, 1, 2, 3], dtype=int32))

""")

56 changes: 51 additions & 5 deletions numpy/core/include/numpy/npy_math.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,6 @@ double npy_tanh(double x);
double npy_asin(double x);
double npy_acos(double x);
double npy_atan(double x);
double npy_aexp(double x);
double npy_alog(double x);
double npy_asqrt(double x);
double npy_afabs(double x);

double npy_log(double x);
double npy_log10(double x);
Expand Down Expand Up @@ -152,6 +148,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 @@ -256,8 +255,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);
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 @@ -297,6 +299,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 @@ -420,6 +425,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 @@ -435,6 +453,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 @@ -450,6 +482,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 @@ -220,6 +220,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]
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 @@ -690,7 +716,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 @@ -996,6 +1023,16 @@ def get_dotblas_sources(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 @@ -143,8 +143,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