Mercurial > cpython-lru_cache-weakref
annotate Python/pymath.c @ 66978:aed2bbafa550 3.1
Blocked revisions 87324 via svnmerge
........
r87324 | r.david.murray | 2010-12-16 14:08:51 -0500 (Thu, 16 Dec 2010) | 9 lines
#10719: restore messages generated on invalid compileall args
Before the introduction of filename arguments to compileall it gave semi useful
messages about not being able to 'list' names that weren't valid directories.
This fix restores that behavior. In addition to the test for this case, the
patch also adds a test for the default behavior of compileall when no arguments
are provided, and fixes a bug in one of the previously added tests.
........
| author | R. David Murray <rdmurray@bitdance.com> |
|---|---|
| date | Thu, 16 Dec 2010 19:10:16 +0000 |
| parents | f197407bdba2 |
| children | 3c9232a684ae |
| rev | line source |
|---|---|
|
46477
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
1 #include "Python.h" |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
2 |
|
51485
f9f2ed79b00f
Merged revisions 69459 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
49270
diff
changeset
|
3 #ifdef X87_DOUBLE_ROUNDING |
|
f9f2ed79b00f
Merged revisions 69459 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
49270
diff
changeset
|
4 /* On x86 platforms using an x87 FPU, this function is called from the |
|
f9f2ed79b00f
Merged revisions 69459 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
49270
diff
changeset
|
5 Py_FORCE_DOUBLE macro (defined in pymath.h) to force a floating-point |
|
f9f2ed79b00f
Merged revisions 69459 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
49270
diff
changeset
|
6 number out of an 80-bit x87 FPU register and into a 64-bit memory location, |
|
f9f2ed79b00f
Merged revisions 69459 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
49270
diff
changeset
|
7 thus rounding from extended precision to double precision. */ |
|
f9f2ed79b00f
Merged revisions 69459 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
49270
diff
changeset
|
8 double _Py_force_double(double x) |
|
f9f2ed79b00f
Merged revisions 69459 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
49270
diff
changeset
|
9 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
10 volatile double y; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
11 y = x; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
12 return y; |
|
51485
f9f2ed79b00f
Merged revisions 69459 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
49270
diff
changeset
|
13 } |
|
f9f2ed79b00f
Merged revisions 69459 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
49270
diff
changeset
|
14 #endif |
|
f9f2ed79b00f
Merged revisions 69459 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
49270
diff
changeset
|
15 |
|
53240
28645a961004
The SSE2 detection and enabling could potentially cause
Mark Dickinson <dickinsm@gmail.com>
parents:
53223
diff
changeset
|
16 #ifdef HAVE_GCC_ASM_FOR_X87 |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
51485
diff
changeset
|
17 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
51485
diff
changeset
|
18 /* inline assembly for getting and setting the 387 FPU control word on |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
51485
diff
changeset
|
19 gcc/x86 */ |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
51485
diff
changeset
|
20 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
51485
diff
changeset
|
21 unsigned short _Py_get_387controlword(void) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
51485
diff
changeset
|
22 unsigned short cw; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
51485
diff
changeset
|
23 __asm__ __volatile__ ("fnstcw %0" : "=m" (cw)); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
51485
diff
changeset
|
24 return cw; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
51485
diff
changeset
|
25 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
51485
diff
changeset
|
26 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
51485
diff
changeset
|
27 void _Py_set_387controlword(unsigned short cw) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
51485
diff
changeset
|
28 __asm__ __volatile__ ("fldcw %0" : : "m" (cw)); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
51485
diff
changeset
|
29 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
51485
diff
changeset
|
30 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
51485
diff
changeset
|
31 #endif |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
51485
diff
changeset
|
32 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
51485
diff
changeset
|
33 |
|
46477
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
34 #ifndef HAVE_HYPOT |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
35 double hypot(double x, double y) |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
36 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
37 double yx; |
|
46477
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
38 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
39 x = fabs(x); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
40 y = fabs(y); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
41 if (x < y) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
42 double temp = x; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
43 x = y; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
44 y = temp; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
45 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
46 if (x == 0.) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
47 return 0.; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
48 else { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
49 yx = y/x; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
50 return x*sqrt(1.+yx*yx); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
51 } |
|
46477
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
52 } |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
53 #endif /* HAVE_HYPOT */ |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
54 |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
55 #ifndef HAVE_COPYSIGN |
|
53223
8209b6c32e61
Merged revisions 71705 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
53221
diff
changeset
|
56 double |
|
46477
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
57 copysign(double x, double y) |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
58 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
59 /* use atan2 to distinguish -0. from 0. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
60 if (y > 0. || (y == 0. && atan2(y, -1.) > 0.)) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
61 return fabs(x); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
62 } else { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
63 return -fabs(x); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
64 } |
|
46477
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
65 } |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
66 #endif /* HAVE_COPYSIGN */ |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
67 |
|
53221
c5c8680ee0b1
Add check for C99 round function to configure, and define
Mark Dickinson <dickinsm@gmail.com>
parents:
53185
diff
changeset
|
68 #ifndef HAVE_ROUND |
|
c5c8680ee0b1
Add check for C99 round function to configure, and define
Mark Dickinson <dickinsm@gmail.com>
parents:
53185
diff
changeset
|
69 double |
|
c5c8680ee0b1
Add check for C99 round function to configure, and define
Mark Dickinson <dickinsm@gmail.com>
parents:
53185
diff
changeset
|
70 round(double x) |
|
c5c8680ee0b1
Add check for C99 round function to configure, and define
Mark Dickinson <dickinsm@gmail.com>
parents:
53185
diff
changeset
|
71 { |
|
c5c8680ee0b1
Add check for C99 round function to configure, and define
Mark Dickinson <dickinsm@gmail.com>
parents:
53185
diff
changeset
|
72 double absx, y; |
|
c5c8680ee0b1
Add check for C99 round function to configure, and define
Mark Dickinson <dickinsm@gmail.com>
parents:
53185
diff
changeset
|
73 absx = fabs(x); |
|
c5c8680ee0b1
Add check for C99 round function to configure, and define
Mark Dickinson <dickinsm@gmail.com>
parents:
53185
diff
changeset
|
74 y = floor(absx); |
|
c5c8680ee0b1
Add check for C99 round function to configure, and define
Mark Dickinson <dickinsm@gmail.com>
parents:
53185
diff
changeset
|
75 if (absx - y >= 0.5) |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
76 y += 1.0; |
|
53221
c5c8680ee0b1
Add check for C99 round function to configure, and define
Mark Dickinson <dickinsm@gmail.com>
parents:
53185
diff
changeset
|
77 return copysign(y, x); |
|
c5c8680ee0b1
Add check for C99 round function to configure, and define
Mark Dickinson <dickinsm@gmail.com>
parents:
53185
diff
changeset
|
78 } |
|
c5c8680ee0b1
Add check for C99 round function to configure, and define
Mark Dickinson <dickinsm@gmail.com>
parents:
53185
diff
changeset
|
79 #endif /* HAVE_ROUND */ |
|
c5c8680ee0b1
Add check for C99 round function to configure, and define
Mark Dickinson <dickinsm@gmail.com>
parents:
53185
diff
changeset
|
80 |
|
46477
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
81 #ifndef HAVE_LOG1P |
|
49270
e86ed113535c
Merged revisions 66552-66553 via svnmerge from
Andrew MacIntyre <andymac@bullseye.apana.org.au>
parents:
46477
diff
changeset
|
82 #include <float.h> |
|
e86ed113535c
Merged revisions 66552-66553 via svnmerge from
Andrew MacIntyre <andymac@bullseye.apana.org.au>
parents:
46477
diff
changeset
|
83 |
|
46477
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
84 double |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
85 log1p(double x) |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
86 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
87 /* For x small, we use the following approach. Let y be the nearest |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
88 float to 1+x, then |
|
46477
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
89 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
90 1+x = y * (1 - (y-1-x)/y) |
|
46477
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
91 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
92 so log(1+x) = log(y) + log(1-(y-1-x)/y). Since (y-1-x)/y is tiny, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
93 the second term is well approximated by (y-1-x)/y. If abs(x) >= |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
94 DBL_EPSILON/2 or the rounding-mode is some form of round-to-nearest |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
95 then y-1-x will be exactly representable, and is computed exactly |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
96 by (y-1)-x. |
|
46477
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
97 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
98 If abs(x) < DBL_EPSILON/2 and the rounding mode is not known to be |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
99 round-to-nearest then this method is slightly dangerous: 1+x could |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
100 be rounded up to 1+DBL_EPSILON instead of down to 1, and in that |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
101 case y-1-x will not be exactly representable any more and the |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
102 result can be off by many ulps. But this is easily fixed: for a |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
103 floating-point number |x| < DBL_EPSILON/2., the closest |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
104 floating-point number to log(1+x) is exactly x. |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
105 */ |
|
46477
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
106 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
107 double y; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
108 if (fabs(x) < DBL_EPSILON/2.) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
109 return x; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
110 } else if (-0.5 <= x && x <= 1.) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
111 /* WARNING: it's possible than an overeager compiler |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
112 will incorrectly optimize the following two lines |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
113 to the equivalent of "return log(1.+x)". If this |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
114 happens, then results from log1p will be inaccurate |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
115 for small x. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
116 y = 1.+x; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
117 return log(y)-((y-1.)-x)/y; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
118 } else { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
119 /* NaNs and infinities should end up here */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
120 return log(1.+x); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
121 } |
|
46477
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
122 } |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
123 #endif /* HAVE_LOG1P */ |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
124 |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
125 /* |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
126 * ==================================================== |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
127 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
128 * |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
129 * Developed at SunPro, a Sun Microsystems, Inc. business. |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
130 * Permission to use, copy, modify, and distribute this |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
131 * software is freely granted, provided that this notice |
|
46477
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
132 * is preserved. |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
133 * ==================================================== |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
134 */ |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
135 |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
136 static const double ln2 = 6.93147180559945286227E-01; |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
137 static const double two_pow_m28 = 3.7252902984619141E-09; /* 2**-28 */ |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
138 static const double two_pow_p28 = 268435456.0; /* 2**28 */ |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
139 static const double zero = 0.0; |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
140 |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
141 /* asinh(x) |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
142 * Method : |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
143 * Based on |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
144 * asinh(x) = sign(x) * log [ |x| + sqrt(x*x+1) ] |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
145 * we have |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
146 * asinh(x) := x if 1+x*x=1, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
147 * := sign(x)*(log(x)+ln2)) for large |x|, else |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
148 * := sign(x)*log(2|x|+1/(|x|+sqrt(x*x+1))) if|x|>2, else |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
149 * := sign(x)*log1p(|x| + x^2/(1 + sqrt(1+x^2))) |
|
46477
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
150 */ |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
151 |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
152 #ifndef HAVE_ASINH |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
153 double |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
154 asinh(double x) |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
155 { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
156 double w; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
157 double absx = fabs(x); |
|
46477
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
158 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
159 if (Py_IS_NAN(x) || Py_IS_INFINITY(x)) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
160 return x+x; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
161 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
162 if (absx < two_pow_m28) { /* |x| < 2**-28 */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
163 return x; /* return x inexact except 0 */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
164 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
165 if (absx > two_pow_p28) { /* |x| > 2**28 */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
166 w = log(absx)+ln2; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
167 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
168 else if (absx > 2.0) { /* 2 < |x| < 2**28 */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
169 w = log(2.0*absx + 1.0 / (sqrt(x*x + 1.0) + absx)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
170 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
171 else { /* 2**-28 <= |x| < 2= */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
172 double t = x*x; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
173 w = log1p(absx + t / (1.0 + sqrt(1.0 + t))); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
174 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
175 return copysign(w, x); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
176 |
|
46477
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
177 } |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
178 #endif /* HAVE_ASINH */ |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
179 |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
180 /* acosh(x) |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
181 * Method : |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
182 * Based on |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
183 * acosh(x) = log [ x + sqrt(x*x-1) ] |
|
46477
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
184 * we have |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
185 * acosh(x) := log(x)+ln2, if x is large; else |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
186 * acosh(x) := log(2x-1/(sqrt(x*x-1)+x)) if x>2; else |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
187 * acosh(x) := log1p(t+sqrt(2.0*t+t*t)); where t=x-1. |
|
46477
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
188 * |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
189 * Special cases: |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
190 * acosh(x) is NaN with signal if x<1. |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
191 * acosh(NaN) is NaN without signal. |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
192 */ |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
193 |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
194 #ifndef HAVE_ACOSH |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
195 double |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
196 acosh(double x) |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
197 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
198 if (Py_IS_NAN(x)) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
199 return x+x; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
200 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
201 if (x < 1.) { /* x < 1; return a signaling NaN */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
202 errno = EDOM; |
|
46477
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
203 #ifdef Py_NAN |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
204 return Py_NAN; |
|
46477
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
205 #else |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
206 return (x-x)/(x-x); |
|
46477
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
207 #endif |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
208 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
209 else if (x >= two_pow_p28) { /* x > 2**28 */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
210 if (Py_IS_INFINITY(x)) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
211 return x+x; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
212 } else { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
213 return log(x)+ln2; /* acosh(huge)=log(2x) */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
214 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
215 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
216 else if (x == 1.) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
217 return 0.0; /* acosh(1) = 0 */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
218 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
219 else if (x > 2.) { /* 2 < x < 2**28 */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
220 double t = x*x; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
221 return log(2.0*x - 1.0 / (x + sqrt(t - 1.0))); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
222 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
223 else { /* 1 < x <= 2 */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
224 double t = x - 1.0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
225 return log1p(t + sqrt(2.0*t + t*t)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
226 } |
|
46477
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
227 } |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
228 #endif /* HAVE_ACOSH */ |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
229 |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
230 /* atanh(x) |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
231 * Method : |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
232 * 1.Reduced x to positive by atanh(-x) = -atanh(x) |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
233 * 2.For x>=0.5 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
234 * 1 2x x |
|
46477
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
235 * atanh(x) = --- * log(1 + -------) = 0.5 * log1p(2 * --------) |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
236 * 2 1 - x 1 - x |
|
46477
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
237 * |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
238 * For x<0.5 |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
239 * atanh(x) = 0.5*log1p(2x+2x*x/(1-x)) |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
240 * |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
241 * Special cases: |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
242 * atanh(x) is NaN if |x| >= 1 with signal; |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
243 * atanh(NaN) is that NaN with no signal; |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
244 * |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
245 */ |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
246 |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
247 #ifndef HAVE_ATANH |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
248 double |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
249 atanh(double x) |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
250 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
251 double absx; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
252 double t; |
|
46477
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
253 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
254 if (Py_IS_NAN(x)) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
255 return x+x; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
256 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
257 absx = fabs(x); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
258 if (absx >= 1.) { /* |x| >= 1 */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
259 errno = EDOM; |
|
46477
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
260 #ifdef Py_NAN |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
261 return Py_NAN; |
|
46477
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
262 #else |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
263 return x/zero; |
|
46477
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
264 #endif |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
265 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
266 if (absx < two_pow_m28) { /* |x| < 2**-28 */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
267 return x; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
268 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
269 if (absx < 0.5) { /* |x| < 0.5 */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
270 t = absx+absx; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
271 t = 0.5 * log1p(t + t*absx / (1.0 - absx)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
272 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
273 else { /* 0.5 <= |x| <= 1.0 */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
274 t = 0.5 * log1p((absx + absx) / (1.0 - absx)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
275 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
53240
diff
changeset
|
276 return copysign(t, x); |
|
46477
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
277 } |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff
changeset
|
278 #endif /* HAVE_ATANH */ |
