annotate Python/pymath.c @ 49955:878d40468c4e legacy-trunk

Issue #4384: Added logging integration with warnings module using captureWarnings(). This change includes a NullHandler which does nothing; it will be of use to library developers who want to avoid the "No handlers could be found for logger XXX" message which can appear if the library user doesn't configure logging.
author Vinay Sajip <vinay_sajip@yahoo.co.uk>
date Wed, 03 Dec 2008 23:22:58 +0000
parents 922b9e03b260
children 79a6c63ac5b0 f9f2ed79b00f
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
3 #ifndef HAVE_HYPOT
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
4 double hypot(double x, double y)
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
5 {
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
6 double yx;
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
7
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
8 x = fabs(x);
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
9 y = fabs(y);
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
10 if (x < y) {
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
11 double temp = x;
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
12 x = y;
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
13 y = temp;
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
14 }
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
15 if (x == 0.)
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
16 return 0.;
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
17 else {
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
18 yx = y/x;
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
19 return x*sqrt(1.+yx*yx);
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
20 }
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
21 }
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
22 #endif /* HAVE_HYPOT */
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
23
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
24 #ifndef HAVE_COPYSIGN
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
25 static double
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
26 copysign(double x, double y)
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
27 {
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
28 /* use atan2 to distinguish -0. from 0. */
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
29 if (y > 0. || (y == 0. && atan2(y, -1.) > 0.)) {
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
30 return fabs(x);
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
31 } else {
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
32 return -fabs(x);
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
33 }
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
34 }
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
35 #endif /* HAVE_COPYSIGN */
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
36
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
37 #ifndef HAVE_LOG1P
49267
922b9e03b260 any platform without HAVE_LOG1P should have DBL_EPSILON in <float.h>
Andrew MacIntyre <andymac@bullseye.apana.org.au>
parents: 46477
diff changeset
38 #include <float.h>
922b9e03b260 any platform without HAVE_LOG1P should have DBL_EPSILON in <float.h>
Andrew MacIntyre <andymac@bullseye.apana.org.au>
parents: 46477
diff changeset
39
46477
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
40 double
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
41 log1p(double x)
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
42 {
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
43 /* For x small, we use the following approach. Let y be the nearest
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
44 float to 1+x, then
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
45
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
46 1+x = y * (1 - (y-1-x)/y)
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
47
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
48 so log(1+x) = log(y) + log(1-(y-1-x)/y). Since (y-1-x)/y is tiny,
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
49 the second term is well approximated by (y-1-x)/y. If abs(x) >=
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
50 DBL_EPSILON/2 or the rounding-mode is some form of round-to-nearest
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
51 then y-1-x will be exactly representable, and is computed exactly
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
52 by (y-1)-x.
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
53
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
54 If abs(x) < DBL_EPSILON/2 and the rounding mode is not known to be
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
55 round-to-nearest then this method is slightly dangerous: 1+x could
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
56 be rounded up to 1+DBL_EPSILON instead of down to 1, and in that
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
57 case y-1-x will not be exactly representable any more and the
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
58 result can be off by many ulps. But this is easily fixed: for a
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
59 floating-point number |x| < DBL_EPSILON/2., the closest
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
60 floating-point number to log(1+x) is exactly x.
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
61 */
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
62
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
63 double y;
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
64 if (fabs(x) < DBL_EPSILON/2.) {
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
65 return x;
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
66 } else if (-0.5 <= x && x <= 1.) {
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
67 /* WARNING: it's possible than an overeager compiler
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
68 will incorrectly optimize the following two lines
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
69 to the equivalent of "return log(1.+x)". If this
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
70 happens, then results from log1p will be inaccurate
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
71 for small x. */
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
72 y = 1.+x;
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
73 return log(y)-((y-1.)-x)/y;
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
74 } else {
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
75 /* NaNs and infinities should end up here */
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
76 return log(1.+x);
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
77 }
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
78 }
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
79 #endif /* HAVE_LOG1P */
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
80
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
81 /*
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
82 * ====================================================
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
83 * 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
84 *
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
85 * 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
86 * Permission to use, copy, modify, and distribute this
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
87 * software is freely granted, provided that this notice
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
88 * is preserved.
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
89 * ====================================================
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
90 */
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
91
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
92 static const double ln2 = 6.93147180559945286227E-01;
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
93 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
94 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
95 static const double zero = 0.0;
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
96
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
97 /* asinh(x)
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
98 * Method :
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
99 * Based on
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
100 * asinh(x) = sign(x) * log [ |x| + sqrt(x*x+1) ]
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
101 * we have
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
102 * asinh(x) := x if 1+x*x=1,
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
103 * := sign(x)*(log(x)+ln2)) for large |x|, else
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
104 * := sign(x)*log(2|x|+1/(|x|+sqrt(x*x+1))) if|x|>2, else
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
105 * := sign(x)*log1p(|x| + x^2/(1 + sqrt(1+x^2)))
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
106 */
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
107
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
108 #ifndef HAVE_ASINH
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
109 double
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
110 asinh(double x)
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
111 {
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
112 double w;
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
113 double absx = fabs(x);
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
114
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
115 if (Py_IS_NAN(x) || Py_IS_INFINITY(x)) {
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
116 return x+x;
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
117 }
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
118 if (absx < two_pow_m28) { /* |x| < 2**-28 */
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
119 return x; /* return x inexact except 0 */
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
120 }
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
121 if (absx > two_pow_p28) { /* |x| > 2**28 */
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
122 w = log(absx)+ln2;
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
123 }
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
124 else if (absx > 2.0) { /* 2 < |x| < 2**28 */
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
125 w = log(2.0*absx + 1.0 / (sqrt(x*x + 1.0) + absx));
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 else { /* 2**-28 <= |x| < 2= */
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
128 double t = x*x;
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
129 w = log1p(absx + t / (1.0 + sqrt(1.0 + t)));
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
130 }
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
131 return copysign(w, x);
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
132
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 #endif /* HAVE_ASINH */
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 /* acosh(x)
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
137 * Method :
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
138 * Based on
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
139 * acosh(x) = log [ x + sqrt(x*x-1) ]
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
140 * we have
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
141 * acosh(x) := log(x)+ln2, if x is large; else
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
142 * acosh(x) := log(2x-1/(sqrt(x*x-1)+x)) if x>2; else
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
143 * acosh(x) := log1p(t+sqrt(2.0*t+t*t)); where t=x-1.
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
144 *
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
145 * Special cases:
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
146 * 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
147 * acosh(NaN) is NaN without signal.
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
148 */
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
149
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
150 #ifndef HAVE_ACOSH
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
151 double
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
152 acosh(double x)
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
153 {
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
154 if (Py_IS_NAN(x)) {
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
155 return x+x;
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
156 }
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
157 if (x < 1.) { /* x < 1; return a signaling NaN */
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
158 errno = EDOM;
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
159 #ifdef Py_NAN
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
160 return Py_NAN;
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
161 #else
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
162 return (x-x)/(x-x);
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
163 #endif
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
164 }
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
165 else if (x >= two_pow_p28) { /* x > 2**28 */
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
166 if (Py_IS_INFINITY(x)) {
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
167 return x+x;
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
168 } else {
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
169 return log(x)+ln2; /* acosh(huge)=log(2x) */
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
170 }
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
171 }
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
172 else if (x == 1.) {
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
173 return 0.0; /* acosh(1) = 0 */
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
174 }
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
175 else if (x > 2.) { /* 2 < x < 2**28 */
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
176 double t = x*x;
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
177 return log(2.0*x - 1.0 / (x + sqrt(t - 1.0)));
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
178 }
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
179 else { /* 1 < x <= 2 */
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
180 double t = x - 1.0;
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
181 return log1p(t + sqrt(2.0*t + t*t));
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
182 }
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
183 }
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
184 #endif /* HAVE_ACOSH */
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
185
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
186 /* atanh(x)
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
187 * Method :
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
188 * 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
189 * 2.For x>=0.5
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
190 * 1 2x x
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
191 * atanh(x) = --- * log(1 + -------) = 0.5 * log1p(2 * --------)
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
192 * 2 1 - x 1 - x
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 * For x<0.5
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
195 * 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
196 *
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
197 * Special cases:
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
198 * 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
199 * 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
200 *
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
201 */
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
202
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
203 #ifndef HAVE_ATANH
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
204 double
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
205 atanh(double x)
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
206 {
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
207 double absx;
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
208 double t;
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
209
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
210 if (Py_IS_NAN(x)) {
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
211 return x+x;
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
212 }
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
213 absx = fabs(x);
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
214 if (absx >= 1.) { /* |x| >= 1 */
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
215 errno = EDOM;
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
216 #ifdef Py_NAN
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
217 return Py_NAN;
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
218 #else
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
219 return x/zero;
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
220 #endif
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
221 }
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
222 if (absx < two_pow_m28) { /* |x| < 2**-28 */
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
223 return x;
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
224 }
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
225 if (absx < 0.5) { /* |x| < 0.5 */
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
226 t = absx+absx;
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
227 t = 0.5 * log1p(t + t*absx / (1.0 - absx));
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
228 }
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
229 else { /* 0.5 <= |x| <= 1.0 */
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
230 t = 0.5 * log1p((absx + absx) / (1.0 - absx));
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
231 }
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
232 return copysign(t, x);
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
233 }
b69f443ef480 Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
diff changeset
234 #endif /* HAVE_ATANH */