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

Skip to content

Commit ea6f909

Browse files
committed
Merge pull request #4852 from ewmoore/gen_frexp
Generate ufuncs for frexp and ldexp
2 parents 56b5f27 + 7ee56eb commit ea6f909

7 files changed

Lines changed: 91 additions & 211 deletions

File tree

numpy/core/code_generators/generate_umath.py

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@
2020
class FullTypeDescr(object):
2121
pass
2222

23+
class FuncNameSuffix(object):
24+
"""Stores the suffix to append when generating functions names.
25+
"""
26+
def __init__(self, suffix):
27+
self.suffix = suffix
28+
2329
class TypeDescription(object):
2430
"""Type signature for a ufunc.
2531
@@ -795,6 +801,30 @@ def english_upper(s):
795801
None,
796802
TD(flts),
797803
),
804+
'ldexp' :
805+
Ufunc(2, 1, None,
806+
docstrings.get('numpy.core.umath.ldexp'),
807+
None,
808+
[TypeDescription('e', None, 'ei', 'e'),
809+
TypeDescription('f', None, 'fi', 'f'),
810+
TypeDescription('e', FuncNameSuffix('long'), 'el', 'e'),
811+
TypeDescription('f', FuncNameSuffix('long'), 'fl', 'f'),
812+
TypeDescription('d', None, 'di', 'd'),
813+
TypeDescription('d', FuncNameSuffix('long'), 'dl', 'd'),
814+
TypeDescription('g', None, 'gi', 'g'),
815+
TypeDescription('g', FuncNameSuffix('long'), 'gl', 'g'),
816+
],
817+
),
818+
'frexp' :
819+
Ufunc(1, 2, None,
820+
docstrings.get('numpy.core.umath.frexp'),
821+
None,
822+
[TypeDescription('e', None, 'e', 'ei'),
823+
TypeDescription('f', None, 'f', 'fi'),
824+
TypeDescription('d', None, 'd', 'di'),
825+
TypeDescription('g', None, 'g', 'gi'),
826+
],
827+
)
798828
}
799829

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

856886
for t in uf.type_descriptions:
857-
if t.func_data not in (None, FullTypeDescr):
887+
if t.func_data not in (None, FullTypeDescr) and not isinstance(t.func_data, FuncNameSuffix):
858888
funclist.append('NULL')
859889
astype = ''
860890
if not t.astype is None:
@@ -880,6 +910,10 @@ def make_arrays(funcdict):
880910
tname = english_upper(chartoname[t.type])
881911
datalist.append('(void *)NULL')
882912
funclist.append('%s_%s_%s_%s' % (tname, t.in_, t.out, name))
913+
elif isinstance(t.func_data, FuncNameSuffix):
914+
datalist.append('(void *)NULL')
915+
tname = english_upper(chartoname[t.type])
916+
funclist.append('%s_%s_%s' % (tname, name, t.func_data.suffix))
883917
else:
884918
datalist.append('(void *)NULL')
885919
tname = english_upper(chartoname[t.type])

numpy/core/code_generators/ufunc_docstrings.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3324,9 +3324,6 @@ def add_newdoc(place, name, doc):
33243324
33253325
""")
33263326

3327-
# This doc is not currently used, but has been converted to a C string
3328-
# that can be found in numpy/core/src/umath/umathmodule.c where the
3329-
# frexp ufunc is constructed.
33303327
add_newdoc('numpy.core.umath', 'frexp',
33313328
"""
33323329
Decompose the elements of x into mantissa and twos exponent.
@@ -3372,9 +3369,6 @@ def add_newdoc(place, name, doc):
33723369
33733370
""")
33743371

3375-
# This doc is not currently used, but has been converted to a C string
3376-
# that can be found in numpy/core/src/umath/umathmodule.c where the
3377-
# ldexp ufunc is constructed.
33783372
add_newdoc('numpy.core.umath', 'ldexp',
33793373
"""
33803374
Returns x1 * 2**x2, element-wise.

numpy/core/include/numpy/npy_math.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -118,10 +118,6 @@ double npy_tanh(double x);
118118
double npy_asin(double x);
119119
double npy_acos(double x);
120120
double npy_atan(double x);
121-
double npy_aexp(double x);
122-
double npy_alog(double x);
123-
double npy_asqrt(double x);
124-
double npy_afabs(double x);
125121

126122
double npy_log(double x);
127123
double npy_log10(double x);
@@ -147,6 +143,8 @@ double npy_log2(double x);
147143
double npy_atan2(double x, double y);
148144
double npy_pow(double x, double y);
149145
double npy_modf(double x, double* y);
146+
double npy_frexp(double x, int* y);
147+
double npy_ldexp(double n, int y);
150148

151149
double npy_copysign(double x, double y);
152150
double npy_nextafter(double x, double y);
@@ -251,6 +249,8 @@ float npy_powf(float x, float y);
251249
float npy_fmodf(float x, float y);
252250

253251
float npy_modff(float x, float* y);
252+
float npy_frexpf(float x, int* y);
253+
float npy_ldexpf(float x, int y);
254254

255255
float npy_copysignf(float x, float y);
256256
float npy_nextafterf(float x, float y);
@@ -292,6 +292,8 @@ npy_longdouble npy_powl(npy_longdouble x, npy_longdouble y);
292292
npy_longdouble npy_fmodl(npy_longdouble x, npy_longdouble y);
293293

294294
npy_longdouble npy_modfl(npy_longdouble x, npy_longdouble* y);
295+
npy_longdouble npy_frexpl(npy_longdouble x, int* y);
296+
npy_longdouble npy_ldexpl(npy_longdouble x, int y);
295297

296298
npy_longdouble npy_copysignl(npy_longdouble x, npy_longdouble y);
297299
npy_longdouble npy_nextafterl(npy_longdouble x, npy_longdouble y);

numpy/core/src/npymath/npy_math.c.src

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,7 @@ double npy_log2(double x)
343343
* asinh, acosh, atanh
344344
*
345345
* hypot, atan2, pow, fmod, modf
346+
* ldexp, frexp
346347
*
347348
* We assume the above are always available in their double versions.
348349
*
@@ -405,6 +406,26 @@ double npy_log2(double x)
405406
}
406407
#endif
407408

409+
#ifdef ldexp@c@
410+
#undef ldexp@c@
411+
#endif
412+
#ifndef HAVE_LDEXP@C@
413+
@type@ npy_ldexp@c@(@type@ x, int exp)
414+
{
415+
return (@type@) npy_ldexp((double)x, exp);
416+
}
417+
#endif
418+
419+
#ifdef frexp@c@
420+
#undef frexp@c@
421+
#endif
422+
#ifndef HAVE_FREXP@C@
423+
@type@ npy_frexp@c@(@type@ x, int* exp)
424+
{
425+
return (@type@) npy_frexp(x, exp);
426+
}
427+
#endif
428+
408429
/**end repeat**/
409430

410431

@@ -451,6 +472,20 @@ double npy_log2(double x)
451472
}
452473
#endif
453474

475+
#ifdef HAVE_LDEXP@C@
476+
@type@ npy_ldexp@c@(@type@ x, int exp)
477+
{
478+
return ldexp@c@(x, exp);
479+
}
480+
#endif
481+
482+
#ifdef HAVE_FREXP@C@
483+
@type@ npy_frexp@c@(@type@ x, int* exp)
484+
{
485+
return frexp@c@(x, exp);
486+
}
487+
#endif
488+
454489
/**end repeat**/
455490

456491

numpy/core/src/umath/loops.c.src

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1743,25 +1743,22 @@ NPY_NO_EXPORT void
17431743
}
17441744
}
17451745

1746-
#ifdef HAVE_FREXP@C@
17471746
NPY_NO_EXPORT void
17481747
@TYPE@_frexp(char **args, npy_intp *dimensions, npy_intp *steps, void *NPY_UNUSED(func))
17491748
{
17501749
UNARY_LOOP_TWO_OUT {
17511750
const @type@ in1 = *(@type@ *)ip1;
1752-
*((@type@ *)op1) = frexp@c@(in1, (int *)op2);
1751+
*((@type@ *)op1) = npy_frexp@c@(in1, (int *)op2);
17531752
}
17541753
}
1755-
#endif
17561754

1757-
#ifdef HAVE_LDEXP@C@
17581755
NPY_NO_EXPORT void
17591756
@TYPE@_ldexp(char **args, npy_intp *dimensions, npy_intp *steps, void *NPY_UNUSED(func))
17601757
{
17611758
BINARY_LOOP {
17621759
const @type@ in1 = *(@type@ *)ip1;
17631760
const int in2 = *(int *)ip2;
1764-
*((@type@ *)op1) = ldexp@c@(in1, in2);
1761+
*((@type@ *)op1) = npy_ldexp@c@(in1, in2);
17651762
}
17661763
}
17671764

@@ -1778,23 +1775,22 @@ NPY_NO_EXPORT void
17781775
const long in2 = *(long *)ip2;
17791776
if (((int)in2) == in2) {
17801777
/* Range OK */
1781-
*((@type@ *)op1) = ldexp@c@(in1, ((int)in2));
1778+
*((@type@ *)op1) = npy_ldexp@c@(in1, ((int)in2));
17821779
}
17831780
else {
17841781
/*
17851782
* Outside npy_int range -- also ldexp will overflow in this case,
17861783
* given that exponent has less bits than npy_int.
17871784
*/
17881785
if (in2 > 0) {
1789-
*((@type@ *)op1) = ldexp@c@(in1, NPY_MAX_INT);
1786+
*((@type@ *)op1) = npy_ldexp@c@(in1, NPY_MAX_INT);
17901787
}
17911788
else {
1792-
*((@type@ *)op1) = ldexp@c@(in1, NPY_MIN_INT);
1789+
*((@type@ *)op1) = npy_ldexp@c@(in1, NPY_MIN_INT);
17931790
}
17941791
}
17951792
}
17961793
}
1797-
#endif
17981794

17991795
#define @TYPE@_true_divide @TYPE@_divide
18001796

@@ -2059,25 +2055,22 @@ HALF_modf(char **args, npy_intp *dimensions, npy_intp *steps, void *NPY_UNUSED(f
20592055
}
20602056
}
20612057

2062-
#ifdef HAVE_FREXPF
20632058
NPY_NO_EXPORT void
20642059
HALF_frexp(char **args, npy_intp *dimensions, npy_intp *steps, void *NPY_UNUSED(func))
20652060
{
20662061
UNARY_LOOP_TWO_OUT {
20672062
const float in1 = npy_half_to_float(*(npy_half *)ip1);
2068-
*((npy_half *)op1) = npy_float_to_half(frexpf(in1, (int *)op2));
2063+
*((npy_half *)op1) = npy_float_to_half(npy_frexpf(in1, (int *)op2));
20692064
}
20702065
}
2071-
#endif
20722066

2073-
#ifdef HAVE_LDEXPF
20742067
NPY_NO_EXPORT void
20752068
HALF_ldexp(char **args, npy_intp *dimensions, npy_intp *steps, void *NPY_UNUSED(func))
20762069
{
20772070
BINARY_LOOP {
20782071
const float in1 = npy_half_to_float(*(npy_half *)ip1);
20792072
const int in2 = *(int *)ip2;
2080-
*((npy_half *)op1) = npy_float_to_half(ldexpf(in1, in2));
2073+
*((npy_half *)op1) = npy_float_to_half(npy_ldexpf(in1, in2));
20812074
}
20822075
}
20832076

@@ -2094,23 +2087,22 @@ HALF_ldexp_long(char **args, npy_intp *dimensions, npy_intp *steps, void *NPY_UN
20942087
const long in2 = *(long *)ip2;
20952088
if (((int)in2) == in2) {
20962089
/* Range OK */
2097-
*((npy_half *)op1) = npy_float_to_half(ldexpf(in1, ((int)in2)));
2090+
*((npy_half *)op1) = npy_float_to_half(npy_ldexpf(in1, ((int)in2)));
20982091
}
20992092
else {
21002093
/*
21012094
* Outside npy_int range -- also ldexp will overflow in this case,
21022095
* given that exponent has less bits than npy_int.
21032096
*/
21042097
if (in2 > 0) {
2105-
*((npy_half *)op1) = npy_float_to_half(ldexpf(in1, NPY_MAX_INT));
2098+
*((npy_half *)op1) = npy_float_to_half(npy_ldexpf(in1, NPY_MAX_INT));
21062099
}
21072100
else {
2108-
*((npy_half *)op1) = npy_float_to_half(ldexpf(in1, NPY_MIN_INT));
2101+
*((npy_half *)op1) = npy_float_to_half(npy_ldexpf(in1, NPY_MIN_INT));
21092102
}
21102103
}
21112104
}
21122105
}
2113-
#endif
21142106

21152107
#define HALF_true_divide HALF_divide
21162108

numpy/core/src/umath/loops.h.src

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -248,17 +248,13 @@ NPY_NO_EXPORT void
248248
NPY_NO_EXPORT void
249249
@TYPE@_modf(char **args, npy_intp *dimensions, npy_intp *steps, void *NPY_UNUSED(func));
250250

251-
#ifdef HAVE_FREXP@C@
252251
NPY_NO_EXPORT void
253252
@TYPE@_frexp(char **args, npy_intp *dimensions, npy_intp *steps, void *NPY_UNUSED(func));
254-
#endif
255253

256-
#ifdef HAVE_LDEXP@C@
257254
NPY_NO_EXPORT void
258255
@TYPE@_ldexp(char **args, npy_intp *dimensions, npy_intp *steps, void *NPY_UNUSED(func));
259256
NPY_NO_EXPORT void
260257
@TYPE@_ldexp_long(char **args, npy_intp *dimensions, npy_intp *steps, void *NPY_UNUSED(func));
261-
#endif
262258

263259
#define @TYPE@_true_divide @TYPE@_divide
264260

0 commit comments

Comments
 (0)