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

Skip to content

Commit 44d0c52

Browse files
committed
BUG: Do not use system cpow directly.
Numpy computes small integer powers by multiplication, this leads to different results than the system cpow for such integers. In particular, cpow((0 + inf*1j), 2) returns (-inf + 0j) rather than (-inf + nanj). The system version probably makes more sense, but better to keep compatibility at this point. We could fix our results using cproj.
1 parent 34b5f9f commit 44d0c52

1 file changed

Lines changed: 36 additions & 25 deletions

File tree

numpy/core/src/npymath/npy_math_complex.c.src

Lines changed: 36 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include "npy_math_common.h"
3535
#include "npy_math_private.h"
3636

37+
3738
#define raise_inexact() do { volatile npy_float junk = 1 + tiny; } while(0)
3839

3940

@@ -431,7 +432,27 @@ npy_csqrt@c@(@ctype@ z)
431432
#undef THRESH
432433
#endif
433434

434-
#ifndef HAVE_CPOW@C@
435+
/*
436+
* Always use this function because of the multiplication for small
437+
* integer powers, but in the body use cpow if it is available.
438+
*/
439+
440+
/* private function for use in npy_pow{f, ,l} */
441+
#ifdef HAVE_CPOW@C@
442+
static @ctype@
443+
sys_cpow@c@(@ctype@ x, @ctype@ y)
444+
{
445+
__@ctype@_to_c99_cast xcast;
446+
__@ctype@_to_c99_cast ycast;
447+
__@ctype@_to_c99_cast ret;
448+
xcast.npy_z = x;
449+
ycast.npy_z = y;
450+
ret.c99_z = cpow@c@(xcast.c99_z, ycast.c99_z);
451+
return ret.npy_z;
452+
}
453+
#endif
454+
455+
435456
@ctype@
436457
npy_cpow@c@ (@ctype@ a, @ctype@ b)
437458
{
@@ -440,7 +461,7 @@ npy_cpow@c@ (@ctype@ a, @ctype@ b)
440461
@type@ br = npy_creal@c@(b);
441462
@type@ ai = npy_cimag@c@(a);
442463
@type@ bi = npy_cimag@c@(b);
443-
@ctype@ loga, r;
464+
@ctype@ r;
444465

445466
if (br == 0. && bi == 0.) {
446467
return npy_cpack@c@(1., 0.);
@@ -505,13 +526,21 @@ npy_cpow@c@ (@ctype@ a, @ctype@ b)
505526
}
506527
}
507528

508-
loga = npy_clog@c@(a);
509-
ar = npy_creal@c@(loga);
510-
ai = npy_cimag@c@(loga);
529+
#ifdef HAVE_CPOW@C@
530+
return sys_cpow@c@(a, b);
531+
532+
#else
533+
{
534+
@ctype@ loga = npy_clog@c@(a);
535+
536+
ar = npy_creal@c@(loga);
537+
ai = npy_cimag@c@(loga);
538+
return npy_cexp@c@(npy_cpack@c@(ar*br - ai*bi, ar*bi + ai*br));
539+
}
511540

512-
return npy_cexp@c@(npy_cpack@c@(ar * br - ai * bi, ar * bi + ai * br));
513-
}
514541
#endif
542+
}
543+
515544

516545
#ifndef HAVE_CCOS@C@
517546
@ctype@
@@ -1753,23 +1782,5 @@ npy_@kind@@c@(@ctype@ z)
17531782
#endif
17541783
/**end repeat1**/
17551784

1756-
/**begin repeat1
1757-
* #kind = cpow#
1758-
* #KIND = CPOW#
1759-
*/
1760-
#ifdef HAVE_@KIND@@C@
1761-
@ctype@
1762-
npy_@kind@@c@(@ctype@ x, @ctype@ y)
1763-
{
1764-
__@ctype@_to_c99_cast xcast;
1765-
__@ctype@_to_c99_cast ycast;
1766-
__@ctype@_to_c99_cast ret;
1767-
xcast.npy_z = x;
1768-
ycast.npy_z = y;
1769-
ret.c99_z = @kind@@c@(xcast.c99_z, ycast.c99_z);
1770-
return ret.npy_z;
1771-
}
1772-
#endif
1773-
/**end repeat1**/
17741785

17751786
/**end repeat**/

0 commit comments

Comments
 (0)