| Guido van Rossum | 71aa32f | 1996-01-12 01:34:57 +0000 | [diff] [blame] | 1 | /* Complex math module */ | 
 | 2 |  | 
 | 3 | /* much code borrowed from mathmodule.c */ | 
 | 4 |  | 
| Roger E. Masse | 24070ca | 1996-12-09 22:59:53 +0000 | [diff] [blame] | 5 | #include "Python.h" | 
| Mark Dickinson | f371859 | 2009-12-21 15:27:41 +0000 | [diff] [blame] | 6 | #include "_math.h" | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 7 | /* we need DBL_MAX, DBL_MIN, DBL_EPSILON, DBL_MANT_DIG and FLT_RADIX from | 
 | 8 |    float.h.  We assume that FLT_RADIX is either 2 or 16. */ | 
 | 9 | #include <float.h> | 
| Guido van Rossum | 71aa32f | 1996-01-12 01:34:57 +0000 | [diff] [blame] | 10 |  | 
| Brett Cannon | b0fc490 | 2014-10-14 17:37:02 -0400 | [diff] [blame] | 11 | #include "clinic/cmathmodule.c.h" | 
 | 12 | /*[clinic input] | 
| Brett Cannon | b0fc490 | 2014-10-14 17:37:02 -0400 | [diff] [blame] | 13 | module cmath | 
 | 14 | [clinic start generated code]*/ | 
| Serhiy Storchaka | 1009bf1 | 2015-04-03 23:53:51 +0300 | [diff] [blame] | 15 | /*[clinic end generated code: output=da39a3ee5e6b4b0d input=308d6839f4a46333]*/ | 
| Brett Cannon | b0fc490 | 2014-10-14 17:37:02 -0400 | [diff] [blame] | 16 |  | 
 | 17 | /*[python input] | 
 | 18 | class Py_complex_protected_converter(Py_complex_converter): | 
 | 19 |     def modify(self): | 
 | 20 |         return 'errno = 0; PyFPE_START_PROTECT("complex function", goto exit);' | 
 | 21 |  | 
 | 22 |  | 
 | 23 | class Py_complex_protected_return_converter(CReturnConverter): | 
 | 24 |     type = "Py_complex" | 
 | 25 |  | 
 | 26 |     def render(self, function, data): | 
 | 27 |         self.declare(data) | 
 | 28 |         data.return_conversion.append(""" | 
 | 29 | PyFPE_END_PROTECT(_return_value); | 
| Serhiy Storchaka | ebe95fd | 2016-06-09 16:02:15 +0300 | [diff] [blame] | 30 | if (errno == EDOM) { | 
| Brett Cannon | b0fc490 | 2014-10-14 17:37:02 -0400 | [diff] [blame] | 31 |     PyErr_SetString(PyExc_ValueError, "math domain error"); | 
 | 32 |     goto exit; | 
| Serhiy Storchaka | ebe95fd | 2016-06-09 16:02:15 +0300 | [diff] [blame] | 33 | } | 
 | 34 | else if (errno == ERANGE) { | 
| Brett Cannon | b0fc490 | 2014-10-14 17:37:02 -0400 | [diff] [blame] | 35 |     PyErr_SetString(PyExc_OverflowError, "math range error"); | 
 | 36 |     goto exit; | 
| Serhiy Storchaka | ebe95fd | 2016-06-09 16:02:15 +0300 | [diff] [blame] | 37 | } | 
 | 38 | else { | 
| Brett Cannon | b0fc490 | 2014-10-14 17:37:02 -0400 | [diff] [blame] | 39 |     return_value = PyComplex_FromCComplex(_return_value); | 
| Serhiy Storchaka | ebe95fd | 2016-06-09 16:02:15 +0300 | [diff] [blame] | 40 | } | 
| Brett Cannon | b0fc490 | 2014-10-14 17:37:02 -0400 | [diff] [blame] | 41 | """.strip()) | 
 | 42 | [python start generated code]*/ | 
| Serhiy Storchaka | ebe95fd | 2016-06-09 16:02:15 +0300 | [diff] [blame] | 43 | /*[python end generated code: output=da39a3ee5e6b4b0d input=345daa075b1028e7]*/ | 
| Brett Cannon | b0fc490 | 2014-10-14 17:37:02 -0400 | [diff] [blame] | 44 |  | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 45 | #if (FLT_RADIX != 2 && FLT_RADIX != 16) | 
 | 46 | #error "Modules/cmathmodule.c expects FLT_RADIX to be 2 or 16" | 
| Guido van Rossum | 71aa32f | 1996-01-12 01:34:57 +0000 | [diff] [blame] | 47 | #endif | 
 | 48 |  | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 49 | #ifndef M_LN2 | 
 | 50 | #define M_LN2 (0.6931471805599453094) /* natural log of 2 */ | 
 | 51 | #endif | 
| Guido van Rossum | 71aa32f | 1996-01-12 01:34:57 +0000 | [diff] [blame] | 52 |  | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 53 | #ifndef M_LN10 | 
 | 54 | #define M_LN10 (2.302585092994045684) /* natural log of 10 */ | 
 | 55 | #endif | 
 | 56 |  | 
 | 57 | /* | 
 | 58 |    CM_LARGE_DOUBLE is used to avoid spurious overflow in the sqrt, log, | 
 | 59 |    inverse trig and inverse hyperbolic trig functions.  Its log is used in the | 
| Ezio Melotti | 1392500 | 2011-03-16 11:05:33 +0200 | [diff] [blame] | 60 |    evaluation of exp, cos, cosh, sin, sinh, tan, and tanh to avoid unnecessary | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 61 |    overflow. | 
 | 62 |  */ | 
 | 63 |  | 
 | 64 | #define CM_LARGE_DOUBLE (DBL_MAX/4.) | 
 | 65 | #define CM_SQRT_LARGE_DOUBLE (sqrt(CM_LARGE_DOUBLE)) | 
 | 66 | #define CM_LOG_LARGE_DOUBLE (log(CM_LARGE_DOUBLE)) | 
 | 67 | #define CM_SQRT_DBL_MIN (sqrt(DBL_MIN)) | 
 | 68 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 69 | /* | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 70 |    CM_SCALE_UP is an odd integer chosen such that multiplication by | 
 | 71 |    2**CM_SCALE_UP is sufficient to turn a subnormal into a normal. | 
 | 72 |    CM_SCALE_DOWN is (-(CM_SCALE_UP+1)/2).  These scalings are used to compute | 
 | 73 |    square roots accurately when the real and imaginary parts of the argument | 
 | 74 |    are subnormal. | 
 | 75 | */ | 
 | 76 |  | 
 | 77 | #if FLT_RADIX==2 | 
 | 78 | #define CM_SCALE_UP (2*(DBL_MANT_DIG/2) + 1) | 
 | 79 | #elif FLT_RADIX==16 | 
 | 80 | #define CM_SCALE_UP (4*DBL_MANT_DIG+1) | 
 | 81 | #endif | 
 | 82 | #define CM_SCALE_DOWN (-(CM_SCALE_UP+1)/2) | 
| Guido van Rossum | 71aa32f | 1996-01-12 01:34:57 +0000 | [diff] [blame] | 83 |  | 
| Mark Dickinson | 84e6311 | 2016-08-29 13:56:58 +0100 | [diff] [blame] | 84 | /* Constants cmath.inf, cmath.infj, cmath.nan, cmath.nanj. | 
 | 85 |    cmath.nan and cmath.nanj are defined only when either | 
 | 86 |    PY_NO_SHORT_FLOAT_REPR is *not* defined (which should be | 
 | 87 |    the most common situation on machines using an IEEE 754 | 
 | 88 |    representation), or Py_NAN is defined. */ | 
 | 89 |  | 
 | 90 | static double | 
 | 91 | m_inf(void) | 
 | 92 | { | 
 | 93 | #ifndef PY_NO_SHORT_FLOAT_REPR | 
 | 94 |     return _Py_dg_infinity(0); | 
 | 95 | #else | 
 | 96 |     return Py_HUGE_VAL; | 
 | 97 | #endif | 
 | 98 | } | 
 | 99 |  | 
 | 100 | static Py_complex | 
 | 101 | c_infj(void) | 
 | 102 | { | 
 | 103 |     Py_complex r; | 
 | 104 |     r.real = 0.0; | 
 | 105 |     r.imag = m_inf(); | 
 | 106 |     return r; | 
 | 107 | } | 
 | 108 |  | 
 | 109 | #if !defined(PY_NO_SHORT_FLOAT_REPR) || defined(Py_NAN) | 
 | 110 |  | 
 | 111 | static double | 
 | 112 | m_nan(void) | 
 | 113 | { | 
 | 114 | #ifndef PY_NO_SHORT_FLOAT_REPR | 
 | 115 |     return _Py_dg_stdnan(0); | 
 | 116 | #else | 
 | 117 |     return Py_NAN; | 
 | 118 | #endif | 
 | 119 | } | 
 | 120 |  | 
 | 121 | static Py_complex | 
 | 122 | c_nanj(void) | 
 | 123 | { | 
 | 124 |     Py_complex r; | 
 | 125 |     r.real = 0.0; | 
 | 126 |     r.imag = m_nan(); | 
 | 127 |     return r; | 
 | 128 | } | 
 | 129 |  | 
 | 130 | #endif | 
 | 131 |  | 
| Guido van Rossum | 71aa32f | 1996-01-12 01:34:57 +0000 | [diff] [blame] | 132 | /* forward declarations */ | 
| Serhiy Storchaka | 1a2b24f | 2016-07-07 17:35:15 +0300 | [diff] [blame] | 133 | static Py_complex cmath_asinh_impl(PyObject *, Py_complex); | 
 | 134 | static Py_complex cmath_atanh_impl(PyObject *, Py_complex); | 
 | 135 | static Py_complex cmath_cosh_impl(PyObject *, Py_complex); | 
 | 136 | static Py_complex cmath_sinh_impl(PyObject *, Py_complex); | 
 | 137 | static Py_complex cmath_sqrt_impl(PyObject *, Py_complex); | 
 | 138 | static Py_complex cmath_tanh_impl(PyObject *, Py_complex); | 
| Raymond Hettinger | b67ad7e | 2004-06-14 07:40:10 +0000 | [diff] [blame] | 139 | static PyObject * math_error(void); | 
| Guido van Rossum | 71aa32f | 1996-01-12 01:34:57 +0000 | [diff] [blame] | 140 |  | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 141 | /* Code to deal with special values (infinities, NaNs, etc.). */ | 
 | 142 |  | 
 | 143 | /* special_type takes a double and returns an integer code indicating | 
 | 144 |    the type of the double as follows: | 
 | 145 | */ | 
 | 146 |  | 
 | 147 | enum special_types { | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 148 |     ST_NINF,            /* 0, negative infinity */ | 
 | 149 |     ST_NEG,             /* 1, negative finite number (nonzero) */ | 
 | 150 |     ST_NZERO,           /* 2, -0. */ | 
 | 151 |     ST_PZERO,           /* 3, +0. */ | 
 | 152 |     ST_POS,             /* 4, positive finite number (nonzero) */ | 
 | 153 |     ST_PINF,            /* 5, positive infinity */ | 
 | 154 |     ST_NAN              /* 6, Not a Number */ | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 155 | }; | 
 | 156 |  | 
 | 157 | static enum special_types | 
 | 158 | special_type(double d) | 
 | 159 | { | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 160 |     if (Py_IS_FINITE(d)) { | 
 | 161 |         if (d != 0) { | 
 | 162 |             if (copysign(1., d) == 1.) | 
 | 163 |                 return ST_POS; | 
 | 164 |             else | 
 | 165 |                 return ST_NEG; | 
 | 166 |         } | 
 | 167 |         else { | 
 | 168 |             if (copysign(1., d) == 1.) | 
 | 169 |                 return ST_PZERO; | 
 | 170 |             else | 
 | 171 |                 return ST_NZERO; | 
 | 172 |         } | 
 | 173 |     } | 
 | 174 |     if (Py_IS_NAN(d)) | 
 | 175 |         return ST_NAN; | 
 | 176 |     if (copysign(1., d) == 1.) | 
 | 177 |         return ST_PINF; | 
 | 178 |     else | 
 | 179 |         return ST_NINF; | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 180 | } | 
 | 181 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 182 | #define SPECIAL_VALUE(z, table)                                         \ | 
 | 183 |     if (!Py_IS_FINITE((z).real) || !Py_IS_FINITE((z).imag)) {           \ | 
 | 184 |         errno = 0;                                              \ | 
 | 185 |         return table[special_type((z).real)]                            \ | 
 | 186 |                     [special_type((z).imag)];                           \ | 
 | 187 |     } | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 188 |  | 
 | 189 | #define P Py_MATH_PI | 
 | 190 | #define P14 0.25*Py_MATH_PI | 
 | 191 | #define P12 0.5*Py_MATH_PI | 
 | 192 | #define P34 0.75*Py_MATH_PI | 
| Christian Heimes | a342c01 | 2008-04-20 21:01:16 +0000 | [diff] [blame] | 193 | #define INF Py_HUGE_VAL | 
 | 194 | #define N Py_NAN | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 195 | #define U -9.5426319407711027e33 /* unlikely value, used as placeholder */ | 
 | 196 |  | 
 | 197 | /* First, the C functions that do the real work.  Each of the c_* | 
 | 198 |    functions computes and returns the C99 Annex G recommended result | 
 | 199 |    and also sets errno as follows: errno = 0 if no floating-point | 
 | 200 |    exception is associated with the result; errno = EDOM if C99 Annex | 
 | 201 |    G recommends raising divide-by-zero or invalid for this result; and | 
 | 202 |    errno = ERANGE where the overflow floating-point signal should be | 
 | 203 |    raised. | 
 | 204 | */ | 
 | 205 |  | 
| Christian Heimes | a342c01 | 2008-04-20 21:01:16 +0000 | [diff] [blame] | 206 | static Py_complex acos_special_values[7][7]; | 
| Guido van Rossum | 71aa32f | 1996-01-12 01:34:57 +0000 | [diff] [blame] | 207 |  | 
| Brett Cannon | b0fc490 | 2014-10-14 17:37:02 -0400 | [diff] [blame] | 208 | /*[clinic input] | 
 | 209 | cmath.acos -> Py_complex_protected | 
 | 210 |  | 
 | 211 |     z: Py_complex_protected | 
 | 212 |     / | 
 | 213 |  | 
 | 214 | Return the arc cosine of z. | 
 | 215 | [clinic start generated code]*/ | 
 | 216 |  | 
| Tim Peters | 14e2640 | 2001-02-20 20:15:19 +0000 | [diff] [blame] | 217 | static Py_complex | 
| Serhiy Storchaka | 1a2b24f | 2016-07-07 17:35:15 +0300 | [diff] [blame] | 218 | cmath_acos_impl(PyObject *module, Py_complex z) | 
 | 219 | /*[clinic end generated code: output=40bd42853fd460ae input=bd6cbd78ae851927]*/ | 
| Guido van Rossum | 71aa32f | 1996-01-12 01:34:57 +0000 | [diff] [blame] | 220 | { | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 221 |     Py_complex s1, s2, r; | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 222 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 223 |     SPECIAL_VALUE(z, acos_special_values); | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 224 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 225 |     if (fabs(z.real) > CM_LARGE_DOUBLE || fabs(z.imag) > CM_LARGE_DOUBLE) { | 
 | 226 |         /* avoid unnecessary overflow for large arguments */ | 
 | 227 |         r.real = atan2(fabs(z.imag), z.real); | 
 | 228 |         /* split into cases to make sure that the branch cut has the | 
 | 229 |            correct continuity on systems with unsigned zeros */ | 
 | 230 |         if (z.real < 0.) { | 
 | 231 |             r.imag = -copysign(log(hypot(z.real/2., z.imag/2.)) + | 
 | 232 |                                M_LN2*2., z.imag); | 
 | 233 |         } else { | 
 | 234 |             r.imag = copysign(log(hypot(z.real/2., z.imag/2.)) + | 
 | 235 |                               M_LN2*2., -z.imag); | 
 | 236 |         } | 
 | 237 |     } else { | 
 | 238 |         s1.real = 1.-z.real; | 
 | 239 |         s1.imag = -z.imag; | 
| Brett Cannon | b0fc490 | 2014-10-14 17:37:02 -0400 | [diff] [blame] | 240 |         s1 = cmath_sqrt_impl(module, s1); | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 241 |         s2.real = 1.+z.real; | 
 | 242 |         s2.imag = z.imag; | 
| Brett Cannon | b0fc490 | 2014-10-14 17:37:02 -0400 | [diff] [blame] | 243 |         s2 = cmath_sqrt_impl(module, s2); | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 244 |         r.real = 2.*atan2(s1.real, s2.real); | 
 | 245 |         r.imag = m_asinh(s2.real*s1.imag - s2.imag*s1.real); | 
 | 246 |     } | 
 | 247 |     errno = 0; | 
 | 248 |     return r; | 
| Guido van Rossum | 71aa32f | 1996-01-12 01:34:57 +0000 | [diff] [blame] | 249 | } | 
 | 250 |  | 
| Guido van Rossum | c6e2290 | 1998-12-04 19:26:43 +0000 | [diff] [blame] | 251 |  | 
| Christian Heimes | a342c01 | 2008-04-20 21:01:16 +0000 | [diff] [blame] | 252 | static Py_complex acosh_special_values[7][7]; | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 253 |  | 
| Brett Cannon | b0fc490 | 2014-10-14 17:37:02 -0400 | [diff] [blame] | 254 | /*[clinic input] | 
 | 255 | cmath.acosh = cmath.acos | 
 | 256 |  | 
| Mark Dickinson | cc8617b | 2015-01-11 13:22:44 +0000 | [diff] [blame] | 257 | Return the inverse hyperbolic cosine of z. | 
| Brett Cannon | b0fc490 | 2014-10-14 17:37:02 -0400 | [diff] [blame] | 258 | [clinic start generated code]*/ | 
 | 259 |  | 
| Tim Peters | 14e2640 | 2001-02-20 20:15:19 +0000 | [diff] [blame] | 260 | static Py_complex | 
| Serhiy Storchaka | 1a2b24f | 2016-07-07 17:35:15 +0300 | [diff] [blame] | 261 | cmath_acosh_impl(PyObject *module, Py_complex z) | 
 | 262 | /*[clinic end generated code: output=3e2454d4fcf404ca input=3f61bee7d703e53c]*/ | 
| Guido van Rossum | 71aa32f | 1996-01-12 01:34:57 +0000 | [diff] [blame] | 263 | { | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 264 |     Py_complex s1, s2, r; | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 265 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 266 |     SPECIAL_VALUE(z, acosh_special_values); | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 267 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 268 |     if (fabs(z.real) > CM_LARGE_DOUBLE || fabs(z.imag) > CM_LARGE_DOUBLE) { | 
 | 269 |         /* avoid unnecessary overflow for large arguments */ | 
 | 270 |         r.real = log(hypot(z.real/2., z.imag/2.)) + M_LN2*2.; | 
 | 271 |         r.imag = atan2(z.imag, z.real); | 
 | 272 |     } else { | 
 | 273 |         s1.real = z.real - 1.; | 
 | 274 |         s1.imag = z.imag; | 
| Brett Cannon | b0fc490 | 2014-10-14 17:37:02 -0400 | [diff] [blame] | 275 |         s1 = cmath_sqrt_impl(module, s1); | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 276 |         s2.real = z.real + 1.; | 
 | 277 |         s2.imag = z.imag; | 
| Brett Cannon | b0fc490 | 2014-10-14 17:37:02 -0400 | [diff] [blame] | 278 |         s2 = cmath_sqrt_impl(module, s2); | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 279 |         r.real = m_asinh(s1.real*s2.real + s1.imag*s2.imag); | 
 | 280 |         r.imag = 2.*atan2(s1.imag, s2.real); | 
 | 281 |     } | 
 | 282 |     errno = 0; | 
 | 283 |     return r; | 
| Guido van Rossum | 71aa32f | 1996-01-12 01:34:57 +0000 | [diff] [blame] | 284 | } | 
 | 285 |  | 
| Brett Cannon | b0fc490 | 2014-10-14 17:37:02 -0400 | [diff] [blame] | 286 | /*[clinic input] | 
 | 287 | cmath.asin = cmath.acos | 
| Guido van Rossum | c6e2290 | 1998-12-04 19:26:43 +0000 | [diff] [blame] | 288 |  | 
| Brett Cannon | b0fc490 | 2014-10-14 17:37:02 -0400 | [diff] [blame] | 289 | Return the arc sine of z. | 
 | 290 | [clinic start generated code]*/ | 
| Guido van Rossum | c6e2290 | 1998-12-04 19:26:43 +0000 | [diff] [blame] | 291 |  | 
| Tim Peters | 14e2640 | 2001-02-20 20:15:19 +0000 | [diff] [blame] | 292 | static Py_complex | 
| Serhiy Storchaka | 1a2b24f | 2016-07-07 17:35:15 +0300 | [diff] [blame] | 293 | cmath_asin_impl(PyObject *module, Py_complex z) | 
 | 294 | /*[clinic end generated code: output=3b264cd1b16bf4e1 input=be0bf0cfdd5239c5]*/ | 
| Guido van Rossum | 71aa32f | 1996-01-12 01:34:57 +0000 | [diff] [blame] | 295 | { | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 296 |     /* asin(z) = -i asinh(iz) */ | 
 | 297 |     Py_complex s, r; | 
 | 298 |     s.real = -z.imag; | 
 | 299 |     s.imag = z.real; | 
| Brett Cannon | b0fc490 | 2014-10-14 17:37:02 -0400 | [diff] [blame] | 300 |     s = cmath_asinh_impl(module, s); | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 301 |     r.real = s.imag; | 
 | 302 |     r.imag = -s.real; | 
 | 303 |     return r; | 
| Guido van Rossum | 71aa32f | 1996-01-12 01:34:57 +0000 | [diff] [blame] | 304 | } | 
 | 305 |  | 
| Guido van Rossum | c6e2290 | 1998-12-04 19:26:43 +0000 | [diff] [blame] | 306 |  | 
| Christian Heimes | a342c01 | 2008-04-20 21:01:16 +0000 | [diff] [blame] | 307 | static Py_complex asinh_special_values[7][7]; | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 308 |  | 
| Brett Cannon | b0fc490 | 2014-10-14 17:37:02 -0400 | [diff] [blame] | 309 | /*[clinic input] | 
 | 310 | cmath.asinh = cmath.acos | 
 | 311 |  | 
| Mark Dickinson | cc8617b | 2015-01-11 13:22:44 +0000 | [diff] [blame] | 312 | Return the inverse hyperbolic sine of z. | 
| Brett Cannon | b0fc490 | 2014-10-14 17:37:02 -0400 | [diff] [blame] | 313 | [clinic start generated code]*/ | 
 | 314 |  | 
| Tim Peters | 14e2640 | 2001-02-20 20:15:19 +0000 | [diff] [blame] | 315 | static Py_complex | 
| Serhiy Storchaka | 1a2b24f | 2016-07-07 17:35:15 +0300 | [diff] [blame] | 316 | cmath_asinh_impl(PyObject *module, Py_complex z) | 
 | 317 | /*[clinic end generated code: output=733d8107841a7599 input=5c09448fcfc89a79]*/ | 
| Guido van Rossum | 71aa32f | 1996-01-12 01:34:57 +0000 | [diff] [blame] | 318 | { | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 319 |     Py_complex s1, s2, r; | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 320 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 321 |     SPECIAL_VALUE(z, asinh_special_values); | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 322 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 323 |     if (fabs(z.real) > CM_LARGE_DOUBLE || fabs(z.imag) > CM_LARGE_DOUBLE) { | 
 | 324 |         if (z.imag >= 0.) { | 
 | 325 |             r.real = copysign(log(hypot(z.real/2., z.imag/2.)) + | 
 | 326 |                               M_LN2*2., z.real); | 
 | 327 |         } else { | 
 | 328 |             r.real = -copysign(log(hypot(z.real/2., z.imag/2.)) + | 
 | 329 |                                M_LN2*2., -z.real); | 
 | 330 |         } | 
 | 331 |         r.imag = atan2(z.imag, fabs(z.real)); | 
 | 332 |     } else { | 
 | 333 |         s1.real = 1.+z.imag; | 
 | 334 |         s1.imag = -z.real; | 
| Brett Cannon | b0fc490 | 2014-10-14 17:37:02 -0400 | [diff] [blame] | 335 |         s1 = cmath_sqrt_impl(module, s1); | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 336 |         s2.real = 1.-z.imag; | 
 | 337 |         s2.imag = z.real; | 
| Brett Cannon | b0fc490 | 2014-10-14 17:37:02 -0400 | [diff] [blame] | 338 |         s2 = cmath_sqrt_impl(module, s2); | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 339 |         r.real = m_asinh(s1.real*s2.imag-s2.real*s1.imag); | 
 | 340 |         r.imag = atan2(z.imag, s1.real*s2.real-s1.imag*s2.imag); | 
 | 341 |     } | 
 | 342 |     errno = 0; | 
 | 343 |     return r; | 
| Guido van Rossum | 71aa32f | 1996-01-12 01:34:57 +0000 | [diff] [blame] | 344 | } | 
 | 345 |  | 
| Guido van Rossum | c6e2290 | 1998-12-04 19:26:43 +0000 | [diff] [blame] | 346 |  | 
| Brett Cannon | b0fc490 | 2014-10-14 17:37:02 -0400 | [diff] [blame] | 347 | /*[clinic input] | 
 | 348 | cmath.atan = cmath.acos | 
 | 349 |  | 
 | 350 | Return the arc tangent of z. | 
 | 351 | [clinic start generated code]*/ | 
| Guido van Rossum | c6e2290 | 1998-12-04 19:26:43 +0000 | [diff] [blame] | 352 |  | 
| Tim Peters | 14e2640 | 2001-02-20 20:15:19 +0000 | [diff] [blame] | 353 | static Py_complex | 
| Serhiy Storchaka | 1a2b24f | 2016-07-07 17:35:15 +0300 | [diff] [blame] | 354 | cmath_atan_impl(PyObject *module, Py_complex z) | 
 | 355 | /*[clinic end generated code: output=b6bfc497058acba4 input=3b21ff7d5eac632a]*/ | 
| Guido van Rossum | 71aa32f | 1996-01-12 01:34:57 +0000 | [diff] [blame] | 356 | { | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 357 |     /* atan(z) = -i atanh(iz) */ | 
 | 358 |     Py_complex s, r; | 
 | 359 |     s.real = -z.imag; | 
 | 360 |     s.imag = z.real; | 
| Brett Cannon | b0fc490 | 2014-10-14 17:37:02 -0400 | [diff] [blame] | 361 |     s = cmath_atanh_impl(module, s); | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 362 |     r.real = s.imag; | 
 | 363 |     r.imag = -s.real; | 
 | 364 |     return r; | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 365 | } | 
 | 366 |  | 
| Christian Heimes | e57950f | 2008-04-21 13:08:03 +0000 | [diff] [blame] | 367 | /* Windows screws up atan2 for inf and nan, and alpha Tru64 5.1 doesn't follow | 
 | 368 |    C99 for atan2(0., 0.). */ | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 369 | static double | 
 | 370 | c_atan2(Py_complex z) | 
 | 371 | { | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 372 |     if (Py_IS_NAN(z.real) || Py_IS_NAN(z.imag)) | 
 | 373 |         return Py_NAN; | 
 | 374 |     if (Py_IS_INFINITY(z.imag)) { | 
 | 375 |         if (Py_IS_INFINITY(z.real)) { | 
 | 376 |             if (copysign(1., z.real) == 1.) | 
 | 377 |                 /* atan2(+-inf, +inf) == +-pi/4 */ | 
 | 378 |                 return copysign(0.25*Py_MATH_PI, z.imag); | 
 | 379 |             else | 
 | 380 |                 /* atan2(+-inf, -inf) == +-pi*3/4 */ | 
 | 381 |                 return copysign(0.75*Py_MATH_PI, z.imag); | 
 | 382 |         } | 
 | 383 |         /* atan2(+-inf, x) == +-pi/2 for finite x */ | 
 | 384 |         return copysign(0.5*Py_MATH_PI, z.imag); | 
 | 385 |     } | 
 | 386 |     if (Py_IS_INFINITY(z.real) || z.imag == 0.) { | 
 | 387 |         if (copysign(1., z.real) == 1.) | 
 | 388 |             /* atan2(+-y, +inf) = atan2(+-0, +x) = +-0. */ | 
 | 389 |             return copysign(0., z.imag); | 
 | 390 |         else | 
 | 391 |             /* atan2(+-y, -inf) = atan2(+-0., -x) = +-pi. */ | 
 | 392 |             return copysign(Py_MATH_PI, z.imag); | 
 | 393 |     } | 
 | 394 |     return atan2(z.imag, z.real); | 
| Guido van Rossum | 71aa32f | 1996-01-12 01:34:57 +0000 | [diff] [blame] | 395 | } | 
 | 396 |  | 
| Guido van Rossum | c6e2290 | 1998-12-04 19:26:43 +0000 | [diff] [blame] | 397 |  | 
| Christian Heimes | a342c01 | 2008-04-20 21:01:16 +0000 | [diff] [blame] | 398 | static Py_complex atanh_special_values[7][7]; | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 399 |  | 
| Brett Cannon | b0fc490 | 2014-10-14 17:37:02 -0400 | [diff] [blame] | 400 | /*[clinic input] | 
 | 401 | cmath.atanh = cmath.acos | 
 | 402 |  | 
| Mark Dickinson | cc8617b | 2015-01-11 13:22:44 +0000 | [diff] [blame] | 403 | Return the inverse hyperbolic tangent of z. | 
| Brett Cannon | b0fc490 | 2014-10-14 17:37:02 -0400 | [diff] [blame] | 404 | [clinic start generated code]*/ | 
 | 405 |  | 
| Tim Peters | 14e2640 | 2001-02-20 20:15:19 +0000 | [diff] [blame] | 406 | static Py_complex | 
| Serhiy Storchaka | 1a2b24f | 2016-07-07 17:35:15 +0300 | [diff] [blame] | 407 | cmath_atanh_impl(PyObject *module, Py_complex z) | 
 | 408 | /*[clinic end generated code: output=e83355f93a989c9e input=2b3fdb82fb34487b]*/ | 
| Guido van Rossum | 71aa32f | 1996-01-12 01:34:57 +0000 | [diff] [blame] | 409 | { | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 410 |     Py_complex r; | 
 | 411 |     double ay, h; | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 412 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 413 |     SPECIAL_VALUE(z, atanh_special_values); | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 414 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 415 |     /* Reduce to case where z.real >= 0., using atanh(z) = -atanh(-z). */ | 
 | 416 |     if (z.real < 0.) { | 
| Brett Cannon | b0fc490 | 2014-10-14 17:37:02 -0400 | [diff] [blame] | 417 |         return _Py_c_neg(cmath_atanh_impl(module, _Py_c_neg(z))); | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 418 |     } | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 419 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 420 |     ay = fabs(z.imag); | 
 | 421 |     if (z.real > CM_SQRT_LARGE_DOUBLE || ay > CM_SQRT_LARGE_DOUBLE) { | 
 | 422 |         /* | 
 | 423 |            if abs(z) is large then we use the approximation | 
 | 424 |            atanh(z) ~ 1/z +/- i*pi/2 (+/- depending on the sign | 
 | 425 |            of z.imag) | 
 | 426 |         */ | 
 | 427 |         h = hypot(z.real/2., z.imag/2.);  /* safe from overflow */ | 
 | 428 |         r.real = z.real/4./h/h; | 
 | 429 |         /* the two negations in the next line cancel each other out | 
 | 430 |            except when working with unsigned zeros: they're there to | 
 | 431 |            ensure that the branch cut has the correct continuity on | 
 | 432 |            systems that don't support signed zeros */ | 
 | 433 |         r.imag = -copysign(Py_MATH_PI/2., -z.imag); | 
 | 434 |         errno = 0; | 
 | 435 |     } else if (z.real == 1. && ay < CM_SQRT_DBL_MIN) { | 
 | 436 |         /* C99 standard says:  atanh(1+/-0.) should be inf +/- 0i */ | 
 | 437 |         if (ay == 0.) { | 
 | 438 |             r.real = INF; | 
 | 439 |             r.imag = z.imag; | 
 | 440 |             errno = EDOM; | 
 | 441 |         } else { | 
 | 442 |             r.real = -log(sqrt(ay)/sqrt(hypot(ay, 2.))); | 
 | 443 |             r.imag = copysign(atan2(2., -ay)/2, z.imag); | 
 | 444 |             errno = 0; | 
 | 445 |         } | 
 | 446 |     } else { | 
 | 447 |         r.real = m_log1p(4.*z.real/((1-z.real)*(1-z.real) + ay*ay))/4.; | 
 | 448 |         r.imag = -atan2(-2.*z.imag, (1-z.real)*(1+z.real) - ay*ay)/2.; | 
 | 449 |         errno = 0; | 
 | 450 |     } | 
 | 451 |     return r; | 
| Guido van Rossum | 71aa32f | 1996-01-12 01:34:57 +0000 | [diff] [blame] | 452 | } | 
 | 453 |  | 
| Guido van Rossum | c6e2290 | 1998-12-04 19:26:43 +0000 | [diff] [blame] | 454 |  | 
| Brett Cannon | b0fc490 | 2014-10-14 17:37:02 -0400 | [diff] [blame] | 455 | /*[clinic input] | 
 | 456 | cmath.cos = cmath.acos | 
 | 457 |  | 
 | 458 | Return the cosine of z. | 
 | 459 | [clinic start generated code]*/ | 
| Guido van Rossum | c6e2290 | 1998-12-04 19:26:43 +0000 | [diff] [blame] | 460 |  | 
| Tim Peters | 14e2640 | 2001-02-20 20:15:19 +0000 | [diff] [blame] | 461 | static Py_complex | 
| Serhiy Storchaka | 1a2b24f | 2016-07-07 17:35:15 +0300 | [diff] [blame] | 462 | cmath_cos_impl(PyObject *module, Py_complex z) | 
 | 463 | /*[clinic end generated code: output=fd64918d5b3186db input=6022e39b77127ac7]*/ | 
| Guido van Rossum | 71aa32f | 1996-01-12 01:34:57 +0000 | [diff] [blame] | 464 | { | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 465 |     /* cos(z) = cosh(iz) */ | 
 | 466 |     Py_complex r; | 
 | 467 |     r.real = -z.imag; | 
 | 468 |     r.imag = z.real; | 
| Brett Cannon | b0fc490 | 2014-10-14 17:37:02 -0400 | [diff] [blame] | 469 |     r = cmath_cosh_impl(module, r); | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 470 |     return r; | 
| Guido van Rossum | 71aa32f | 1996-01-12 01:34:57 +0000 | [diff] [blame] | 471 | } | 
 | 472 |  | 
| Guido van Rossum | c6e2290 | 1998-12-04 19:26:43 +0000 | [diff] [blame] | 473 |  | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 474 | /* cosh(infinity + i*y) needs to be dealt with specially */ | 
| Christian Heimes | a342c01 | 2008-04-20 21:01:16 +0000 | [diff] [blame] | 475 | static Py_complex cosh_special_values[7][7]; | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 476 |  | 
| Brett Cannon | b0fc490 | 2014-10-14 17:37:02 -0400 | [diff] [blame] | 477 | /*[clinic input] | 
 | 478 | cmath.cosh = cmath.acos | 
 | 479 |  | 
 | 480 | Return the hyperbolic cosine of z. | 
 | 481 | [clinic start generated code]*/ | 
 | 482 |  | 
| Tim Peters | 14e2640 | 2001-02-20 20:15:19 +0000 | [diff] [blame] | 483 | static Py_complex | 
| Serhiy Storchaka | 1a2b24f | 2016-07-07 17:35:15 +0300 | [diff] [blame] | 484 | cmath_cosh_impl(PyObject *module, Py_complex z) | 
 | 485 | /*[clinic end generated code: output=2e969047da601bdb input=d6b66339e9cc332b]*/ | 
| Guido van Rossum | 71aa32f | 1996-01-12 01:34:57 +0000 | [diff] [blame] | 486 | { | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 487 |     Py_complex r; | 
 | 488 |     double x_minus_one; | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 489 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 490 |     /* special treatment for cosh(+/-inf + iy) if y is not a NaN */ | 
 | 491 |     if (!Py_IS_FINITE(z.real) || !Py_IS_FINITE(z.imag)) { | 
 | 492 |         if (Py_IS_INFINITY(z.real) && Py_IS_FINITE(z.imag) && | 
 | 493 |             (z.imag != 0.)) { | 
 | 494 |             if (z.real > 0) { | 
 | 495 |                 r.real = copysign(INF, cos(z.imag)); | 
 | 496 |                 r.imag = copysign(INF, sin(z.imag)); | 
 | 497 |             } | 
 | 498 |             else { | 
 | 499 |                 r.real = copysign(INF, cos(z.imag)); | 
 | 500 |                 r.imag = -copysign(INF, sin(z.imag)); | 
 | 501 |             } | 
 | 502 |         } | 
 | 503 |         else { | 
 | 504 |             r = cosh_special_values[special_type(z.real)] | 
 | 505 |                                    [special_type(z.imag)]; | 
 | 506 |         } | 
 | 507 |         /* need to set errno = EDOM if y is +/- infinity and x is not | 
 | 508 |            a NaN */ | 
 | 509 |         if (Py_IS_INFINITY(z.imag) && !Py_IS_NAN(z.real)) | 
 | 510 |             errno = EDOM; | 
 | 511 |         else | 
 | 512 |             errno = 0; | 
 | 513 |         return r; | 
 | 514 |     } | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 515 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 516 |     if (fabs(z.real) > CM_LOG_LARGE_DOUBLE) { | 
 | 517 |         /* deal correctly with cases where cosh(z.real) overflows but | 
 | 518 |            cosh(z) does not. */ | 
 | 519 |         x_minus_one = z.real - copysign(1., z.real); | 
 | 520 |         r.real = cos(z.imag) * cosh(x_minus_one) * Py_MATH_E; | 
 | 521 |         r.imag = sin(z.imag) * sinh(x_minus_one) * Py_MATH_E; | 
 | 522 |     } else { | 
 | 523 |         r.real = cos(z.imag) * cosh(z.real); | 
 | 524 |         r.imag = sin(z.imag) * sinh(z.real); | 
 | 525 |     } | 
 | 526 |     /* detect overflow, and set errno accordingly */ | 
 | 527 |     if (Py_IS_INFINITY(r.real) || Py_IS_INFINITY(r.imag)) | 
 | 528 |         errno = ERANGE; | 
 | 529 |     else | 
 | 530 |         errno = 0; | 
 | 531 |     return r; | 
| Guido van Rossum | 71aa32f | 1996-01-12 01:34:57 +0000 | [diff] [blame] | 532 | } | 
 | 533 |  | 
| Guido van Rossum | c6e2290 | 1998-12-04 19:26:43 +0000 | [diff] [blame] | 534 |  | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 535 | /* exp(infinity + i*y) and exp(-infinity + i*y) need special treatment for | 
 | 536 |    finite y */ | 
| Christian Heimes | a342c01 | 2008-04-20 21:01:16 +0000 | [diff] [blame] | 537 | static Py_complex exp_special_values[7][7]; | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 538 |  | 
| Brett Cannon | b0fc490 | 2014-10-14 17:37:02 -0400 | [diff] [blame] | 539 | /*[clinic input] | 
 | 540 | cmath.exp = cmath.acos | 
 | 541 |  | 
 | 542 | Return the exponential value e**z. | 
 | 543 | [clinic start generated code]*/ | 
 | 544 |  | 
| Tim Peters | 14e2640 | 2001-02-20 20:15:19 +0000 | [diff] [blame] | 545 | static Py_complex | 
| Serhiy Storchaka | 1a2b24f | 2016-07-07 17:35:15 +0300 | [diff] [blame] | 546 | cmath_exp_impl(PyObject *module, Py_complex z) | 
 | 547 | /*[clinic end generated code: output=edcec61fb9dfda6c input=8b9e6cf8a92174c3]*/ | 
| Guido van Rossum | 71aa32f | 1996-01-12 01:34:57 +0000 | [diff] [blame] | 548 | { | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 549 |     Py_complex r; | 
 | 550 |     double l; | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 551 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 552 |     if (!Py_IS_FINITE(z.real) || !Py_IS_FINITE(z.imag)) { | 
 | 553 |         if (Py_IS_INFINITY(z.real) && Py_IS_FINITE(z.imag) | 
 | 554 |             && (z.imag != 0.)) { | 
 | 555 |             if (z.real > 0) { | 
 | 556 |                 r.real = copysign(INF, cos(z.imag)); | 
 | 557 |                 r.imag = copysign(INF, sin(z.imag)); | 
 | 558 |             } | 
 | 559 |             else { | 
 | 560 |                 r.real = copysign(0., cos(z.imag)); | 
 | 561 |                 r.imag = copysign(0., sin(z.imag)); | 
 | 562 |             } | 
 | 563 |         } | 
 | 564 |         else { | 
 | 565 |             r = exp_special_values[special_type(z.real)] | 
 | 566 |                                   [special_type(z.imag)]; | 
 | 567 |         } | 
 | 568 |         /* need to set errno = EDOM if y is +/- infinity and x is not | 
 | 569 |            a NaN and not -infinity */ | 
 | 570 |         if (Py_IS_INFINITY(z.imag) && | 
 | 571 |             (Py_IS_FINITE(z.real) || | 
 | 572 |              (Py_IS_INFINITY(z.real) && z.real > 0))) | 
 | 573 |             errno = EDOM; | 
 | 574 |         else | 
 | 575 |             errno = 0; | 
 | 576 |         return r; | 
 | 577 |     } | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 578 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 579 |     if (z.real > CM_LOG_LARGE_DOUBLE) { | 
 | 580 |         l = exp(z.real-1.); | 
 | 581 |         r.real = l*cos(z.imag)*Py_MATH_E; | 
 | 582 |         r.imag = l*sin(z.imag)*Py_MATH_E; | 
 | 583 |     } else { | 
 | 584 |         l = exp(z.real); | 
 | 585 |         r.real = l*cos(z.imag); | 
 | 586 |         r.imag = l*sin(z.imag); | 
 | 587 |     } | 
 | 588 |     /* detect overflow, and set errno accordingly */ | 
 | 589 |     if (Py_IS_INFINITY(r.real) || Py_IS_INFINITY(r.imag)) | 
 | 590 |         errno = ERANGE; | 
 | 591 |     else | 
 | 592 |         errno = 0; | 
 | 593 |     return r; | 
| Guido van Rossum | 71aa32f | 1996-01-12 01:34:57 +0000 | [diff] [blame] | 594 | } | 
 | 595 |  | 
| Christian Heimes | a342c01 | 2008-04-20 21:01:16 +0000 | [diff] [blame] | 596 | static Py_complex log_special_values[7][7]; | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 597 |  | 
| Tim Peters | 14e2640 | 2001-02-20 20:15:19 +0000 | [diff] [blame] | 598 | static Py_complex | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 599 | c_log(Py_complex z) | 
| Guido van Rossum | 71aa32f | 1996-01-12 01:34:57 +0000 | [diff] [blame] | 600 | { | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 601 |     /* | 
 | 602 |        The usual formula for the real part is log(hypot(z.real, z.imag)). | 
 | 603 |        There are four situations where this formula is potentially | 
 | 604 |        problematic: | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 605 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 606 |        (1) the absolute value of z is subnormal.  Then hypot is subnormal, | 
 | 607 |        so has fewer than the usual number of bits of accuracy, hence may | 
 | 608 |        have large relative error.  This then gives a large absolute error | 
 | 609 |        in the log.  This can be solved by rescaling z by a suitable power | 
 | 610 |        of 2. | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 611 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 612 |        (2) the absolute value of z is greater than DBL_MAX (e.g. when both | 
 | 613 |        z.real and z.imag are within a factor of 1/sqrt(2) of DBL_MAX) | 
 | 614 |        Again, rescaling solves this. | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 615 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 616 |        (3) the absolute value of z is close to 1.  In this case it's | 
 | 617 |        difficult to achieve good accuracy, at least in part because a | 
 | 618 |        change of 1ulp in the real or imaginary part of z can result in a | 
 | 619 |        change of billions of ulps in the correctly rounded answer. | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 620 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 621 |        (4) z = 0.  The simplest thing to do here is to call the | 
 | 622 |        floating-point log with an argument of 0, and let its behaviour | 
 | 623 |        (returning -infinity, signaling a floating-point exception, setting | 
 | 624 |        errno, or whatever) determine that of c_log.  So the usual formula | 
 | 625 |        is fine here. | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 626 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 627 |      */ | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 628 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 629 |     Py_complex r; | 
 | 630 |     double ax, ay, am, an, h; | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 631 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 632 |     SPECIAL_VALUE(z, log_special_values); | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 633 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 634 |     ax = fabs(z.real); | 
 | 635 |     ay = fabs(z.imag); | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 636 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 637 |     if (ax > CM_LARGE_DOUBLE || ay > CM_LARGE_DOUBLE) { | 
 | 638 |         r.real = log(hypot(ax/2., ay/2.)) + M_LN2; | 
 | 639 |     } else if (ax < DBL_MIN && ay < DBL_MIN) { | 
 | 640 |         if (ax > 0. || ay > 0.) { | 
 | 641 |             /* catch cases where hypot(ax, ay) is subnormal */ | 
 | 642 |             r.real = log(hypot(ldexp(ax, DBL_MANT_DIG), | 
 | 643 |                      ldexp(ay, DBL_MANT_DIG))) - DBL_MANT_DIG*M_LN2; | 
 | 644 |         } | 
 | 645 |         else { | 
 | 646 |             /* log(+/-0. +/- 0i) */ | 
 | 647 |             r.real = -INF; | 
 | 648 |             r.imag = atan2(z.imag, z.real); | 
 | 649 |             errno = EDOM; | 
 | 650 |             return r; | 
 | 651 |         } | 
 | 652 |     } else { | 
 | 653 |         h = hypot(ax, ay); | 
 | 654 |         if (0.71 <= h && h <= 1.73) { | 
 | 655 |             am = ax > ay ? ax : ay;  /* max(ax, ay) */ | 
 | 656 |             an = ax > ay ? ay : ax;  /* min(ax, ay) */ | 
 | 657 |             r.real = m_log1p((am-1)*(am+1)+an*an)/2.; | 
 | 658 |         } else { | 
 | 659 |             r.real = log(h); | 
 | 660 |         } | 
 | 661 |     } | 
 | 662 |     r.imag = atan2(z.imag, z.real); | 
 | 663 |     errno = 0; | 
 | 664 |     return r; | 
| Guido van Rossum | 71aa32f | 1996-01-12 01:34:57 +0000 | [diff] [blame] | 665 | } | 
 | 666 |  | 
| Guido van Rossum | c6e2290 | 1998-12-04 19:26:43 +0000 | [diff] [blame] | 667 |  | 
| Brett Cannon | b0fc490 | 2014-10-14 17:37:02 -0400 | [diff] [blame] | 668 | /*[clinic input] | 
 | 669 | cmath.log10 = cmath.acos | 
 | 670 |  | 
 | 671 | Return the base-10 logarithm of z. | 
 | 672 | [clinic start generated code]*/ | 
 | 673 |  | 
| Tim Peters | 14e2640 | 2001-02-20 20:15:19 +0000 | [diff] [blame] | 674 | static Py_complex | 
| Serhiy Storchaka | 1a2b24f | 2016-07-07 17:35:15 +0300 | [diff] [blame] | 675 | cmath_log10_impl(PyObject *module, Py_complex z) | 
 | 676 | /*[clinic end generated code: output=2922779a7c38cbe1 input=cff5644f73c1519c]*/ | 
| Guido van Rossum | 71aa32f | 1996-01-12 01:34:57 +0000 | [diff] [blame] | 677 | { | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 678 |     Py_complex r; | 
 | 679 |     int errno_save; | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 680 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 681 |     r = c_log(z); | 
 | 682 |     errno_save = errno; /* just in case the divisions affect errno */ | 
 | 683 |     r.real = r.real / M_LN10; | 
 | 684 |     r.imag = r.imag / M_LN10; | 
 | 685 |     errno = errno_save; | 
 | 686 |     return r; | 
| Guido van Rossum | 71aa32f | 1996-01-12 01:34:57 +0000 | [diff] [blame] | 687 | } | 
 | 688 |  | 
| Guido van Rossum | c6e2290 | 1998-12-04 19:26:43 +0000 | [diff] [blame] | 689 |  | 
| Brett Cannon | b0fc490 | 2014-10-14 17:37:02 -0400 | [diff] [blame] | 690 | /*[clinic input] | 
 | 691 | cmath.sin = cmath.acos | 
 | 692 |  | 
 | 693 | Return the sine of z. | 
 | 694 | [clinic start generated code]*/ | 
| Guido van Rossum | c6e2290 | 1998-12-04 19:26:43 +0000 | [diff] [blame] | 695 |  | 
| Tim Peters | 14e2640 | 2001-02-20 20:15:19 +0000 | [diff] [blame] | 696 | static Py_complex | 
| Serhiy Storchaka | 1a2b24f | 2016-07-07 17:35:15 +0300 | [diff] [blame] | 697 | cmath_sin_impl(PyObject *module, Py_complex z) | 
 | 698 | /*[clinic end generated code: output=980370d2ff0bb5aa input=2d3519842a8b4b85]*/ | 
| Guido van Rossum | 71aa32f | 1996-01-12 01:34:57 +0000 | [diff] [blame] | 699 | { | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 700 |     /* sin(z) = -i sin(iz) */ | 
 | 701 |     Py_complex s, r; | 
 | 702 |     s.real = -z.imag; | 
 | 703 |     s.imag = z.real; | 
| Brett Cannon | b0fc490 | 2014-10-14 17:37:02 -0400 | [diff] [blame] | 704 |     s = cmath_sinh_impl(module, s); | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 705 |     r.real = s.imag; | 
 | 706 |     r.imag = -s.real; | 
 | 707 |     return r; | 
| Guido van Rossum | 71aa32f | 1996-01-12 01:34:57 +0000 | [diff] [blame] | 708 | } | 
 | 709 |  | 
| Guido van Rossum | c6e2290 | 1998-12-04 19:26:43 +0000 | [diff] [blame] | 710 |  | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 711 | /* sinh(infinity + i*y) needs to be dealt with specially */ | 
| Christian Heimes | a342c01 | 2008-04-20 21:01:16 +0000 | [diff] [blame] | 712 | static Py_complex sinh_special_values[7][7]; | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 713 |  | 
| Brett Cannon | b0fc490 | 2014-10-14 17:37:02 -0400 | [diff] [blame] | 714 | /*[clinic input] | 
 | 715 | cmath.sinh = cmath.acos | 
 | 716 |  | 
 | 717 | Return the hyperbolic sine of z. | 
 | 718 | [clinic start generated code]*/ | 
 | 719 |  | 
| Tim Peters | 14e2640 | 2001-02-20 20:15:19 +0000 | [diff] [blame] | 720 | static Py_complex | 
| Serhiy Storchaka | 1a2b24f | 2016-07-07 17:35:15 +0300 | [diff] [blame] | 721 | cmath_sinh_impl(PyObject *module, Py_complex z) | 
 | 722 | /*[clinic end generated code: output=38b0a6cce26f3536 input=d2d3fc8c1ddfd2dd]*/ | 
| Guido van Rossum | 71aa32f | 1996-01-12 01:34:57 +0000 | [diff] [blame] | 723 | { | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 724 |     Py_complex r; | 
 | 725 |     double x_minus_one; | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 726 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 727 |     /* special treatment for sinh(+/-inf + iy) if y is finite and | 
 | 728 |        nonzero */ | 
 | 729 |     if (!Py_IS_FINITE(z.real) || !Py_IS_FINITE(z.imag)) { | 
 | 730 |         if (Py_IS_INFINITY(z.real) && Py_IS_FINITE(z.imag) | 
 | 731 |             && (z.imag != 0.)) { | 
 | 732 |             if (z.real > 0) { | 
 | 733 |                 r.real = copysign(INF, cos(z.imag)); | 
 | 734 |                 r.imag = copysign(INF, sin(z.imag)); | 
 | 735 |             } | 
 | 736 |             else { | 
 | 737 |                 r.real = -copysign(INF, cos(z.imag)); | 
 | 738 |                 r.imag = copysign(INF, sin(z.imag)); | 
 | 739 |             } | 
 | 740 |         } | 
 | 741 |         else { | 
 | 742 |             r = sinh_special_values[special_type(z.real)] | 
 | 743 |                                    [special_type(z.imag)]; | 
 | 744 |         } | 
 | 745 |         /* need to set errno = EDOM if y is +/- infinity and x is not | 
 | 746 |            a NaN */ | 
 | 747 |         if (Py_IS_INFINITY(z.imag) && !Py_IS_NAN(z.real)) | 
 | 748 |             errno = EDOM; | 
 | 749 |         else | 
 | 750 |             errno = 0; | 
 | 751 |         return r; | 
 | 752 |     } | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 753 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 754 |     if (fabs(z.real) > CM_LOG_LARGE_DOUBLE) { | 
 | 755 |         x_minus_one = z.real - copysign(1., z.real); | 
 | 756 |         r.real = cos(z.imag) * sinh(x_minus_one) * Py_MATH_E; | 
 | 757 |         r.imag = sin(z.imag) * cosh(x_minus_one) * Py_MATH_E; | 
 | 758 |     } else { | 
 | 759 |         r.real = cos(z.imag) * sinh(z.real); | 
 | 760 |         r.imag = sin(z.imag) * cosh(z.real); | 
 | 761 |     } | 
 | 762 |     /* detect overflow, and set errno accordingly */ | 
 | 763 |     if (Py_IS_INFINITY(r.real) || Py_IS_INFINITY(r.imag)) | 
 | 764 |         errno = ERANGE; | 
 | 765 |     else | 
 | 766 |         errno = 0; | 
 | 767 |     return r; | 
| Guido van Rossum | 71aa32f | 1996-01-12 01:34:57 +0000 | [diff] [blame] | 768 | } | 
 | 769 |  | 
| Guido van Rossum | c6e2290 | 1998-12-04 19:26:43 +0000 | [diff] [blame] | 770 |  | 
| Christian Heimes | a342c01 | 2008-04-20 21:01:16 +0000 | [diff] [blame] | 771 | static Py_complex sqrt_special_values[7][7]; | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 772 |  | 
| Brett Cannon | b0fc490 | 2014-10-14 17:37:02 -0400 | [diff] [blame] | 773 | /*[clinic input] | 
 | 774 | cmath.sqrt = cmath.acos | 
 | 775 |  | 
 | 776 | Return the square root of z. | 
 | 777 | [clinic start generated code]*/ | 
 | 778 |  | 
| Tim Peters | 14e2640 | 2001-02-20 20:15:19 +0000 | [diff] [blame] | 779 | static Py_complex | 
| Serhiy Storchaka | 1a2b24f | 2016-07-07 17:35:15 +0300 | [diff] [blame] | 780 | cmath_sqrt_impl(PyObject *module, Py_complex z) | 
 | 781 | /*[clinic end generated code: output=b6507b3029c339fc input=7088b166fc9a58c7]*/ | 
| Guido van Rossum | 71aa32f | 1996-01-12 01:34:57 +0000 | [diff] [blame] | 782 | { | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 783 |     /* | 
 | 784 |        Method: use symmetries to reduce to the case when x = z.real and y | 
 | 785 |        = z.imag are nonnegative.  Then the real part of the result is | 
 | 786 |        given by | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 787 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 788 |          s = sqrt((x + hypot(x, y))/2) | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 789 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 790 |        and the imaginary part is | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 791 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 792 |          d = (y/2)/s | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 793 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 794 |        If either x or y is very large then there's a risk of overflow in | 
 | 795 |        computation of the expression x + hypot(x, y).  We can avoid this | 
 | 796 |        by rewriting the formula for s as: | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 797 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 798 |          s = 2*sqrt(x/8 + hypot(x/8, y/8)) | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 799 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 800 |        This costs us two extra multiplications/divisions, but avoids the | 
 | 801 |        overhead of checking for x and y large. | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 802 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 803 |        If both x and y are subnormal then hypot(x, y) may also be | 
 | 804 |        subnormal, so will lack full precision.  We solve this by rescaling | 
 | 805 |        x and y by a sufficiently large power of 2 to ensure that x and y | 
 | 806 |        are normal. | 
 | 807 |     */ | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 808 |  | 
 | 809 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 810 |     Py_complex r; | 
 | 811 |     double s,d; | 
 | 812 |     double ax, ay; | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 813 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 814 |     SPECIAL_VALUE(z, sqrt_special_values); | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 815 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 816 |     if (z.real == 0. && z.imag == 0.) { | 
 | 817 |         r.real = 0.; | 
 | 818 |         r.imag = z.imag; | 
 | 819 |         return r; | 
 | 820 |     } | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 821 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 822 |     ax = fabs(z.real); | 
 | 823 |     ay = fabs(z.imag); | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 824 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 825 |     if (ax < DBL_MIN && ay < DBL_MIN && (ax > 0. || ay > 0.)) { | 
 | 826 |         /* here we catch cases where hypot(ax, ay) is subnormal */ | 
 | 827 |         ax = ldexp(ax, CM_SCALE_UP); | 
 | 828 |         s = ldexp(sqrt(ax + hypot(ax, ldexp(ay, CM_SCALE_UP))), | 
 | 829 |                   CM_SCALE_DOWN); | 
 | 830 |     } else { | 
 | 831 |         ax /= 8.; | 
 | 832 |         s = 2.*sqrt(ax + hypot(ax, ay/8.)); | 
 | 833 |     } | 
 | 834 |     d = ay/(2.*s); | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 835 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 836 |     if (z.real >= 0.) { | 
 | 837 |         r.real = s; | 
 | 838 |         r.imag = copysign(d, z.imag); | 
 | 839 |     } else { | 
 | 840 |         r.real = d; | 
 | 841 |         r.imag = copysign(s, z.imag); | 
 | 842 |     } | 
 | 843 |     errno = 0; | 
 | 844 |     return r; | 
| Guido van Rossum | 71aa32f | 1996-01-12 01:34:57 +0000 | [diff] [blame] | 845 | } | 
 | 846 |  | 
| Guido van Rossum | c6e2290 | 1998-12-04 19:26:43 +0000 | [diff] [blame] | 847 |  | 
| Brett Cannon | b0fc490 | 2014-10-14 17:37:02 -0400 | [diff] [blame] | 848 | /*[clinic input] | 
 | 849 | cmath.tan = cmath.acos | 
 | 850 |  | 
 | 851 | Return the tangent of z. | 
 | 852 | [clinic start generated code]*/ | 
| Guido van Rossum | c6e2290 | 1998-12-04 19:26:43 +0000 | [diff] [blame] | 853 |  | 
| Tim Peters | 14e2640 | 2001-02-20 20:15:19 +0000 | [diff] [blame] | 854 | static Py_complex | 
| Serhiy Storchaka | 1a2b24f | 2016-07-07 17:35:15 +0300 | [diff] [blame] | 855 | cmath_tan_impl(PyObject *module, Py_complex z) | 
 | 856 | /*[clinic end generated code: output=7c5f13158a72eb13 input=fc167e528767888e]*/ | 
| Guido van Rossum | 71aa32f | 1996-01-12 01:34:57 +0000 | [diff] [blame] | 857 | { | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 858 |     /* tan(z) = -i tanh(iz) */ | 
 | 859 |     Py_complex s, r; | 
 | 860 |     s.real = -z.imag; | 
 | 861 |     s.imag = z.real; | 
| Brett Cannon | b0fc490 | 2014-10-14 17:37:02 -0400 | [diff] [blame] | 862 |     s = cmath_tanh_impl(module, s); | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 863 |     r.real = s.imag; | 
 | 864 |     r.imag = -s.real; | 
 | 865 |     return r; | 
| Guido van Rossum | 71aa32f | 1996-01-12 01:34:57 +0000 | [diff] [blame] | 866 | } | 
 | 867 |  | 
| Guido van Rossum | c6e2290 | 1998-12-04 19:26:43 +0000 | [diff] [blame] | 868 |  | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 869 | /* tanh(infinity + i*y) needs to be dealt with specially */ | 
| Christian Heimes | a342c01 | 2008-04-20 21:01:16 +0000 | [diff] [blame] | 870 | static Py_complex tanh_special_values[7][7]; | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 871 |  | 
| Brett Cannon | b0fc490 | 2014-10-14 17:37:02 -0400 | [diff] [blame] | 872 | /*[clinic input] | 
 | 873 | cmath.tanh = cmath.acos | 
 | 874 |  | 
 | 875 | Return the hyperbolic tangent of z. | 
 | 876 | [clinic start generated code]*/ | 
 | 877 |  | 
| Tim Peters | 14e2640 | 2001-02-20 20:15:19 +0000 | [diff] [blame] | 878 | static Py_complex | 
| Serhiy Storchaka | 1a2b24f | 2016-07-07 17:35:15 +0300 | [diff] [blame] | 879 | cmath_tanh_impl(PyObject *module, Py_complex z) | 
 | 880 | /*[clinic end generated code: output=36d547ef7aca116c input=22f67f9dc6d29685]*/ | 
| Guido van Rossum | 71aa32f | 1996-01-12 01:34:57 +0000 | [diff] [blame] | 881 | { | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 882 |     /* Formula: | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 883 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 884 |        tanh(x+iy) = (tanh(x)(1+tan(y)^2) + i tan(y)(1-tanh(x))^2) / | 
 | 885 |        (1+tan(y)^2 tanh(x)^2) | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 886 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 887 |        To avoid excessive roundoff error, 1-tanh(x)^2 is better computed | 
 | 888 |        as 1/cosh(x)^2.  When abs(x) is large, we approximate 1-tanh(x)^2 | 
 | 889 |        by 4 exp(-2*x) instead, to avoid possible overflow in the | 
 | 890 |        computation of cosh(x). | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 891 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 892 |     */ | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 893 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 894 |     Py_complex r; | 
 | 895 |     double tx, ty, cx, txty, denom; | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 896 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 897 |     /* special treatment for tanh(+/-inf + iy) if y is finite and | 
 | 898 |        nonzero */ | 
 | 899 |     if (!Py_IS_FINITE(z.real) || !Py_IS_FINITE(z.imag)) { | 
 | 900 |         if (Py_IS_INFINITY(z.real) && Py_IS_FINITE(z.imag) | 
 | 901 |             && (z.imag != 0.)) { | 
 | 902 |             if (z.real > 0) { | 
 | 903 |                 r.real = 1.0; | 
 | 904 |                 r.imag = copysign(0., | 
 | 905 |                                   2.*sin(z.imag)*cos(z.imag)); | 
 | 906 |             } | 
 | 907 |             else { | 
 | 908 |                 r.real = -1.0; | 
 | 909 |                 r.imag = copysign(0., | 
 | 910 |                                   2.*sin(z.imag)*cos(z.imag)); | 
 | 911 |             } | 
 | 912 |         } | 
 | 913 |         else { | 
 | 914 |             r = tanh_special_values[special_type(z.real)] | 
 | 915 |                                    [special_type(z.imag)]; | 
 | 916 |         } | 
 | 917 |         /* need to set errno = EDOM if z.imag is +/-infinity and | 
 | 918 |            z.real is finite */ | 
 | 919 |         if (Py_IS_INFINITY(z.imag) && Py_IS_FINITE(z.real)) | 
 | 920 |             errno = EDOM; | 
 | 921 |         else | 
 | 922 |             errno = 0; | 
 | 923 |         return r; | 
 | 924 |     } | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 925 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 926 |     /* danger of overflow in 2.*z.imag !*/ | 
 | 927 |     if (fabs(z.real) > CM_LOG_LARGE_DOUBLE) { | 
 | 928 |         r.real = copysign(1., z.real); | 
 | 929 |         r.imag = 4.*sin(z.imag)*cos(z.imag)*exp(-2.*fabs(z.real)); | 
 | 930 |     } else { | 
 | 931 |         tx = tanh(z.real); | 
 | 932 |         ty = tan(z.imag); | 
 | 933 |         cx = 1./cosh(z.real); | 
 | 934 |         txty = tx*ty; | 
 | 935 |         denom = 1. + txty*txty; | 
 | 936 |         r.real = tx*(1.+ty*ty)/denom; | 
 | 937 |         r.imag = ((ty/denom)*cx)*cx; | 
 | 938 |     } | 
 | 939 |     errno = 0; | 
 | 940 |     return r; | 
| Guido van Rossum | 71aa32f | 1996-01-12 01:34:57 +0000 | [diff] [blame] | 941 | } | 
 | 942 |  | 
| Guido van Rossum | c6e2290 | 1998-12-04 19:26:43 +0000 | [diff] [blame] | 943 |  | 
| Brett Cannon | b0fc490 | 2014-10-14 17:37:02 -0400 | [diff] [blame] | 944 | /*[clinic input] | 
 | 945 | cmath.log | 
 | 946 |  | 
 | 947 |     x: Py_complex | 
 | 948 |     y_obj: object = NULL | 
 | 949 |     / | 
 | 950 |  | 
 | 951 | The logarithm of z to the given base. | 
 | 952 |  | 
 | 953 | If the base not specified, returns the natural logarithm (base e) of z. | 
 | 954 | [clinic start generated code]*/ | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 955 |  | 
| Raymond Hettinger | b67ad7e | 2004-06-14 07:40:10 +0000 | [diff] [blame] | 956 | static PyObject * | 
| Serhiy Storchaka | 1a2b24f | 2016-07-07 17:35:15 +0300 | [diff] [blame] | 957 | cmath_log_impl(PyObject *module, Py_complex x, PyObject *y_obj) | 
 | 958 | /*[clinic end generated code: output=4effdb7d258e0d94 input=ee0e823a7c6e68ea]*/ | 
| Raymond Hettinger | b67ad7e | 2004-06-14 07:40:10 +0000 | [diff] [blame] | 959 | { | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 960 |     Py_complex y; | 
| Raymond Hettinger | b67ad7e | 2004-06-14 07:40:10 +0000 | [diff] [blame] | 961 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 962 |     errno = 0; | 
 | 963 |     PyFPE_START_PROTECT("complex function", return 0) | 
 | 964 |     x = c_log(x); | 
| Brett Cannon | b0fc490 | 2014-10-14 17:37:02 -0400 | [diff] [blame] | 965 |     if (y_obj != NULL) { | 
 | 966 |         y = PyComplex_AsCComplex(y_obj); | 
 | 967 |         if (PyErr_Occurred()) { | 
 | 968 |             return NULL; | 
 | 969 |         } | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 970 |         y = c_log(y); | 
| Antoine Pitrou | de08cb6 | 2014-07-07 19:08:47 -0400 | [diff] [blame] | 971 |         x = _Py_c_quot(x, y); | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 972 |     } | 
 | 973 |     PyFPE_END_PROTECT(x) | 
 | 974 |     if (errno != 0) | 
 | 975 |         return math_error(); | 
 | 976 |     return PyComplex_FromCComplex(x); | 
| Raymond Hettinger | b67ad7e | 2004-06-14 07:40:10 +0000 | [diff] [blame] | 977 | } | 
 | 978 |  | 
| Guido van Rossum | 71aa32f | 1996-01-12 01:34:57 +0000 | [diff] [blame] | 979 |  | 
 | 980 | /* And now the glue to make them available from Python: */ | 
 | 981 |  | 
| Roger E. Masse | 24070ca | 1996-12-09 22:59:53 +0000 | [diff] [blame] | 982 | static PyObject * | 
| Thomas Wouters | f3f33dc | 2000-07-21 06:00:07 +0000 | [diff] [blame] | 983 | math_error(void) | 
| Guido van Rossum | 71aa32f | 1996-01-12 01:34:57 +0000 | [diff] [blame] | 984 | { | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 985 |     if (errno == EDOM) | 
 | 986 |         PyErr_SetString(PyExc_ValueError, "math domain error"); | 
 | 987 |     else if (errno == ERANGE) | 
 | 988 |         PyErr_SetString(PyExc_OverflowError, "math range error"); | 
 | 989 |     else    /* Unexpected math error */ | 
 | 990 |         PyErr_SetFromErrno(PyExc_ValueError); | 
 | 991 |     return NULL; | 
| Guido van Rossum | 71aa32f | 1996-01-12 01:34:57 +0000 | [diff] [blame] | 992 | } | 
 | 993 |  | 
| Guido van Rossum | 71aa32f | 1996-01-12 01:34:57 +0000 | [diff] [blame] | 994 |  | 
| Brett Cannon | b0fc490 | 2014-10-14 17:37:02 -0400 | [diff] [blame] | 995 | /*[clinic input] | 
 | 996 | cmath.phase | 
| Guido van Rossum | 71aa32f | 1996-01-12 01:34:57 +0000 | [diff] [blame] | 997 |  | 
| Brett Cannon | b0fc490 | 2014-10-14 17:37:02 -0400 | [diff] [blame] | 998 |     z: Py_complex | 
 | 999 |     / | 
 | 1000 |  | 
 | 1001 | Return argument, also known as the phase angle, of a complex. | 
 | 1002 | [clinic start generated code]*/ | 
| Guido van Rossum | 71aa32f | 1996-01-12 01:34:57 +0000 | [diff] [blame] | 1003 |  | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 1004 | static PyObject * | 
| Serhiy Storchaka | 1a2b24f | 2016-07-07 17:35:15 +0300 | [diff] [blame] | 1005 | cmath_phase_impl(PyObject *module, Py_complex z) | 
 | 1006 | /*[clinic end generated code: output=50725086a7bfd253 input=5cf75228ba94b69d]*/ | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 1007 | { | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1008 |     double phi; | 
| Brett Cannon | b0fc490 | 2014-10-14 17:37:02 -0400 | [diff] [blame] | 1009 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1010 |     errno = 0; | 
 | 1011 |     PyFPE_START_PROTECT("arg function", return 0) | 
 | 1012 |     phi = c_atan2(z); | 
 | 1013 |     PyFPE_END_PROTECT(phi) | 
 | 1014 |     if (errno != 0) | 
 | 1015 |         return math_error(); | 
 | 1016 |     else | 
 | 1017 |         return PyFloat_FromDouble(phi); | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 1018 | } | 
 | 1019 |  | 
| Brett Cannon | b0fc490 | 2014-10-14 17:37:02 -0400 | [diff] [blame] | 1020 | /*[clinic input] | 
 | 1021 | cmath.polar | 
 | 1022 |  | 
 | 1023 |     z: Py_complex | 
 | 1024 |     / | 
 | 1025 |  | 
 | 1026 | Convert a complex from rectangular coordinates to polar coordinates. | 
 | 1027 |  | 
 | 1028 | r is the distance from 0 and phi the phase angle. | 
 | 1029 | [clinic start generated code]*/ | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 1030 |  | 
 | 1031 | static PyObject * | 
| Serhiy Storchaka | 1a2b24f | 2016-07-07 17:35:15 +0300 | [diff] [blame] | 1032 | cmath_polar_impl(PyObject *module, Py_complex z) | 
 | 1033 | /*[clinic end generated code: output=d0a8147c41dbb654 input=26c353574fd1a861]*/ | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 1034 | { | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1035 |     double r, phi; | 
| Brett Cannon | b0fc490 | 2014-10-14 17:37:02 -0400 | [diff] [blame] | 1036 |  | 
| Antoine Pitrou | 6bc217d | 2015-06-23 14:31:11 +0200 | [diff] [blame] | 1037 |     errno = 0; | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1038 |     PyFPE_START_PROTECT("polar function", return 0) | 
 | 1039 |     phi = c_atan2(z); /* should not cause any exception */ | 
| Antoine Pitrou | a72f0cd | 2015-06-23 14:38:13 +0200 | [diff] [blame] | 1040 |     r = _Py_c_abs(z); /* sets errno to ERANGE on overflow */ | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1041 |     PyFPE_END_PROTECT(r) | 
 | 1042 |     if (errno != 0) | 
 | 1043 |         return math_error(); | 
 | 1044 |     else | 
 | 1045 |         return Py_BuildValue("dd", r, phi); | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 1046 | } | 
 | 1047 |  | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 1048 | /* | 
 | 1049 |   rect() isn't covered by the C99 standard, but it's not too hard to | 
 | 1050 |   figure out 'spirit of C99' rules for special value handing: | 
 | 1051 |  | 
 | 1052 |     rect(x, t) should behave like exp(log(x) + it) for positive-signed x | 
 | 1053 |     rect(x, t) should behave like -exp(log(-x) + it) for negative-signed x | 
 | 1054 |     rect(nan, t) should behave like exp(nan + it), except that rect(nan, 0) | 
 | 1055 |       gives nan +- i0 with the sign of the imaginary part unspecified. | 
 | 1056 |  | 
 | 1057 | */ | 
 | 1058 |  | 
| Christian Heimes | a342c01 | 2008-04-20 21:01:16 +0000 | [diff] [blame] | 1059 | static Py_complex rect_special_values[7][7]; | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 1060 |  | 
| Brett Cannon | b0fc490 | 2014-10-14 17:37:02 -0400 | [diff] [blame] | 1061 | /*[clinic input] | 
 | 1062 | cmath.rect | 
 | 1063 |  | 
 | 1064 |     r: double | 
 | 1065 |     phi: double | 
 | 1066 |     / | 
 | 1067 |  | 
 | 1068 | Convert from polar coordinates to rectangular coordinates. | 
 | 1069 | [clinic start generated code]*/ | 
 | 1070 |  | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 1071 | static PyObject * | 
| Serhiy Storchaka | 1a2b24f | 2016-07-07 17:35:15 +0300 | [diff] [blame] | 1072 | cmath_rect_impl(PyObject *module, double r, double phi) | 
 | 1073 | /*[clinic end generated code: output=385a0690925df2d5 input=24c5646d147efd69]*/ | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 1074 | { | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1075 |     Py_complex z; | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1076 |     errno = 0; | 
 | 1077 |     PyFPE_START_PROTECT("rect function", return 0) | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 1078 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1079 |     /* deal with special values */ | 
 | 1080 |     if (!Py_IS_FINITE(r) || !Py_IS_FINITE(phi)) { | 
 | 1081 |         /* if r is +/-infinity and phi is finite but nonzero then | 
 | 1082 |            result is (+-INF +-INF i), but we need to compute cos(phi) | 
 | 1083 |            and sin(phi) to figure out the signs. */ | 
 | 1084 |         if (Py_IS_INFINITY(r) && (Py_IS_FINITE(phi) | 
 | 1085 |                                   && (phi != 0.))) { | 
 | 1086 |             if (r > 0) { | 
 | 1087 |                 z.real = copysign(INF, cos(phi)); | 
 | 1088 |                 z.imag = copysign(INF, sin(phi)); | 
 | 1089 |             } | 
 | 1090 |             else { | 
 | 1091 |                 z.real = -copysign(INF, cos(phi)); | 
 | 1092 |                 z.imag = -copysign(INF, sin(phi)); | 
 | 1093 |             } | 
 | 1094 |         } | 
 | 1095 |         else { | 
 | 1096 |             z = rect_special_values[special_type(r)] | 
 | 1097 |                                    [special_type(phi)]; | 
 | 1098 |         } | 
 | 1099 |         /* need to set errno = EDOM if r is a nonzero number and phi | 
 | 1100 |            is infinite */ | 
 | 1101 |         if (r != 0. && !Py_IS_NAN(r) && Py_IS_INFINITY(phi)) | 
 | 1102 |             errno = EDOM; | 
 | 1103 |         else | 
 | 1104 |             errno = 0; | 
 | 1105 |     } | 
| Mark Dickinson | 58ceecf | 2013-07-20 17:59:13 +0100 | [diff] [blame] | 1106 |     else if (phi == 0.0) { | 
 | 1107 |         /* Workaround for buggy results with phi=-0.0 on OS X 10.8.  See | 
 | 1108 |            bugs.python.org/issue18513. */ | 
 | 1109 |         z.real = r; | 
 | 1110 |         z.imag = r * phi; | 
 | 1111 |         errno = 0; | 
 | 1112 |     } | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1113 |     else { | 
 | 1114 |         z.real = r * cos(phi); | 
 | 1115 |         z.imag = r * sin(phi); | 
 | 1116 |         errno = 0; | 
 | 1117 |     } | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 1118 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1119 |     PyFPE_END_PROTECT(z) | 
 | 1120 |     if (errno != 0) | 
 | 1121 |         return math_error(); | 
 | 1122 |     else | 
 | 1123 |         return PyComplex_FromCComplex(z); | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 1124 | } | 
 | 1125 |  | 
| Brett Cannon | b0fc490 | 2014-10-14 17:37:02 -0400 | [diff] [blame] | 1126 | /*[clinic input] | 
 | 1127 | cmath.isfinite = cmath.polar | 
 | 1128 |  | 
 | 1129 | Return True if both the real and imaginary parts of z are finite, else False. | 
 | 1130 | [clinic start generated code]*/ | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 1131 |  | 
 | 1132 | static PyObject * | 
| Serhiy Storchaka | 1a2b24f | 2016-07-07 17:35:15 +0300 | [diff] [blame] | 1133 | cmath_isfinite_impl(PyObject *module, Py_complex z) | 
 | 1134 | /*[clinic end generated code: output=ac76611e2c774a36 input=848e7ee701895815]*/ | 
| Mark Dickinson | 8e0c996 | 2010-07-11 17:38:24 +0000 | [diff] [blame] | 1135 | { | 
| Mark Dickinson | 8e0c996 | 2010-07-11 17:38:24 +0000 | [diff] [blame] | 1136 |     return PyBool_FromLong(Py_IS_FINITE(z.real) && Py_IS_FINITE(z.imag)); | 
 | 1137 | } | 
 | 1138 |  | 
| Brett Cannon | b0fc490 | 2014-10-14 17:37:02 -0400 | [diff] [blame] | 1139 | /*[clinic input] | 
 | 1140 | cmath.isnan = cmath.polar | 
 | 1141 |  | 
 | 1142 | Checks if the real or imaginary part of z not a number (NaN). | 
 | 1143 | [clinic start generated code]*/ | 
| Mark Dickinson | 8e0c996 | 2010-07-11 17:38:24 +0000 | [diff] [blame] | 1144 |  | 
 | 1145 | static PyObject * | 
| Serhiy Storchaka | 1a2b24f | 2016-07-07 17:35:15 +0300 | [diff] [blame] | 1146 | cmath_isnan_impl(PyObject *module, Py_complex z) | 
 | 1147 | /*[clinic end generated code: output=e7abf6e0b28beab7 input=71799f5d284c9baf]*/ | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 1148 | { | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1149 |     return PyBool_FromLong(Py_IS_NAN(z.real) || Py_IS_NAN(z.imag)); | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 1150 | } | 
 | 1151 |  | 
| Brett Cannon | b0fc490 | 2014-10-14 17:37:02 -0400 | [diff] [blame] | 1152 | /*[clinic input] | 
 | 1153 | cmath.isinf = cmath.polar | 
 | 1154 |  | 
 | 1155 | Checks if the real or imaginary part of z is infinite. | 
 | 1156 | [clinic start generated code]*/ | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 1157 |  | 
 | 1158 | static PyObject * | 
| Serhiy Storchaka | 1a2b24f | 2016-07-07 17:35:15 +0300 | [diff] [blame] | 1159 | cmath_isinf_impl(PyObject *module, Py_complex z) | 
 | 1160 | /*[clinic end generated code: output=502a75a79c773469 input=363df155c7181329]*/ | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 1161 | { | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1162 |     return PyBool_FromLong(Py_IS_INFINITY(z.real) || | 
 | 1163 |                            Py_IS_INFINITY(z.imag)); | 
| Christian Heimes | 53876d9 | 2008-04-19 00:31:39 +0000 | [diff] [blame] | 1164 | } | 
 | 1165 |  | 
| Tal Einat | d5519ed | 2015-05-31 22:05:00 +0300 | [diff] [blame] | 1166 | /*[clinic input] | 
 | 1167 | cmath.isclose -> bool | 
 | 1168 |  | 
 | 1169 |     a: Py_complex | 
 | 1170 |     b: Py_complex | 
 | 1171 |     * | 
 | 1172 |     rel_tol: double = 1e-09 | 
 | 1173 |         maximum difference for being considered "close", relative to the | 
 | 1174 |         magnitude of the input values | 
 | 1175 |     abs_tol: double = 0.0 | 
 | 1176 |         maximum difference for being considered "close", regardless of the | 
 | 1177 |         magnitude of the input values | 
 | 1178 |  | 
 | 1179 | Determine whether two complex numbers are close in value. | 
 | 1180 |  | 
 | 1181 | Return True if a is close in value to b, and False otherwise. | 
 | 1182 |  | 
 | 1183 | For the values to be considered close, the difference between them must be | 
 | 1184 | smaller than at least one of the tolerances. | 
 | 1185 |  | 
 | 1186 | -inf, inf and NaN behave similarly to the IEEE 754 Standard. That is, NaN is | 
 | 1187 | not close to anything, even itself. inf and -inf are only close to themselves. | 
 | 1188 | [clinic start generated code]*/ | 
 | 1189 |  | 
 | 1190 | static int | 
| Serhiy Storchaka | 1a2b24f | 2016-07-07 17:35:15 +0300 | [diff] [blame] | 1191 | cmath_isclose_impl(PyObject *module, Py_complex a, Py_complex b, | 
| Tal Einat | d5519ed | 2015-05-31 22:05:00 +0300 | [diff] [blame] | 1192 |                    double rel_tol, double abs_tol) | 
| Serhiy Storchaka | 1a2b24f | 2016-07-07 17:35:15 +0300 | [diff] [blame] | 1193 | /*[clinic end generated code: output=8a2486cc6e0014d1 input=df9636d7de1d4ac3]*/ | 
| Tal Einat | d5519ed | 2015-05-31 22:05:00 +0300 | [diff] [blame] | 1194 | { | 
 | 1195 |     double diff; | 
 | 1196 |  | 
 | 1197 |     /* sanity check on the inputs */ | 
 | 1198 |     if (rel_tol < 0.0 || abs_tol < 0.0 ) { | 
 | 1199 |         PyErr_SetString(PyExc_ValueError, | 
 | 1200 |                         "tolerances must be non-negative"); | 
 | 1201 |         return -1; | 
 | 1202 |     } | 
 | 1203 |  | 
 | 1204 |     if ( (a.real == b.real) && (a.imag == b.imag) ) { | 
 | 1205 |         /* short circuit exact equality -- needed to catch two infinities of | 
 | 1206 |            the same sign. And perhaps speeds things up a bit sometimes. | 
 | 1207 |         */ | 
 | 1208 |         return 1; | 
 | 1209 |     } | 
 | 1210 |  | 
 | 1211 |     /* This catches the case of two infinities of opposite sign, or | 
 | 1212 |        one infinity and one finite number. Two infinities of opposite | 
 | 1213 |        sign would otherwise have an infinite relative tolerance. | 
 | 1214 |        Two infinities of the same sign are caught by the equality check | 
 | 1215 |        above. | 
 | 1216 |     */ | 
 | 1217 |  | 
 | 1218 |     if (Py_IS_INFINITY(a.real) || Py_IS_INFINITY(a.imag) || | 
 | 1219 |         Py_IS_INFINITY(b.real) || Py_IS_INFINITY(b.imag)) { | 
 | 1220 |         return 0; | 
 | 1221 |     } | 
 | 1222 |  | 
 | 1223 |     /* now do the regular computation | 
 | 1224 |        this is essentially the "weak" test from the Boost library | 
 | 1225 |     */ | 
 | 1226 |  | 
 | 1227 |     diff = _Py_c_abs(_Py_c_diff(a, b)); | 
 | 1228 |  | 
 | 1229 |     return (((diff <= rel_tol * _Py_c_abs(b)) || | 
 | 1230 |              (diff <= rel_tol * _Py_c_abs(a))) || | 
 | 1231 |             (diff <= abs_tol)); | 
 | 1232 | } | 
| Guido van Rossum | 71aa32f | 1996-01-12 01:34:57 +0000 | [diff] [blame] | 1233 |  | 
| Martin v. Löwis | 14f8b4c | 2002-06-13 20:33:02 +0000 | [diff] [blame] | 1234 | PyDoc_STRVAR(module_doc, | 
| Tim Peters | 14e2640 | 2001-02-20 20:15:19 +0000 | [diff] [blame] | 1235 | "This module is always available. It provides access to mathematical\n" | 
| Martin v. Löwis | 14f8b4c | 2002-06-13 20:33:02 +0000 | [diff] [blame] | 1236 | "functions for complex numbers."); | 
| Guido van Rossum | c6e2290 | 1998-12-04 19:26:43 +0000 | [diff] [blame] | 1237 |  | 
| Roger E. Masse | 24070ca | 1996-12-09 22:59:53 +0000 | [diff] [blame] | 1238 | static PyMethodDef cmath_methods[] = { | 
| Brett Cannon | b0fc490 | 2014-10-14 17:37:02 -0400 | [diff] [blame] | 1239 |     CMATH_ACOS_METHODDEF | 
 | 1240 |     CMATH_ACOSH_METHODDEF | 
 | 1241 |     CMATH_ASIN_METHODDEF | 
 | 1242 |     CMATH_ASINH_METHODDEF | 
 | 1243 |     CMATH_ATAN_METHODDEF | 
 | 1244 |     CMATH_ATANH_METHODDEF | 
 | 1245 |     CMATH_COS_METHODDEF | 
 | 1246 |     CMATH_COSH_METHODDEF | 
 | 1247 |     CMATH_EXP_METHODDEF | 
| Tal Einat | d5519ed | 2015-05-31 22:05:00 +0300 | [diff] [blame] | 1248 |     CMATH_ISCLOSE_METHODDEF | 
| Brett Cannon | b0fc490 | 2014-10-14 17:37:02 -0400 | [diff] [blame] | 1249 |     CMATH_ISFINITE_METHODDEF | 
 | 1250 |     CMATH_ISINF_METHODDEF | 
 | 1251 |     CMATH_ISNAN_METHODDEF | 
 | 1252 |     CMATH_LOG_METHODDEF | 
 | 1253 |     CMATH_LOG10_METHODDEF | 
 | 1254 |     CMATH_PHASE_METHODDEF | 
 | 1255 |     CMATH_POLAR_METHODDEF | 
 | 1256 |     CMATH_RECT_METHODDEF | 
 | 1257 |     CMATH_SIN_METHODDEF | 
 | 1258 |     CMATH_SINH_METHODDEF | 
 | 1259 |     CMATH_SQRT_METHODDEF | 
 | 1260 |     CMATH_TAN_METHODDEF | 
 | 1261 |     CMATH_TANH_METHODDEF | 
 | 1262 |     {NULL, NULL}  /* sentinel */ | 
| Guido van Rossum | 71aa32f | 1996-01-12 01:34:57 +0000 | [diff] [blame] | 1263 | }; | 
 | 1264 |  | 
| Martin v. Löwis | 1a21451 | 2008-06-11 05:26:20 +0000 | [diff] [blame] | 1265 |  | 
 | 1266 | static struct PyModuleDef cmathmodule = { | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1267 |     PyModuleDef_HEAD_INIT, | 
 | 1268 |     "cmath", | 
 | 1269 |     module_doc, | 
 | 1270 |     -1, | 
 | 1271 |     cmath_methods, | 
 | 1272 |     NULL, | 
 | 1273 |     NULL, | 
 | 1274 |     NULL, | 
 | 1275 |     NULL | 
| Martin v. Löwis | 1a21451 | 2008-06-11 05:26:20 +0000 | [diff] [blame] | 1276 | }; | 
 | 1277 |  | 
| Mark Hammond | fe51c6d | 2002-08-02 02:27:13 +0000 | [diff] [blame] | 1278 | PyMODINIT_FUNC | 
| Martin v. Löwis | 1a21451 | 2008-06-11 05:26:20 +0000 | [diff] [blame] | 1279 | PyInit_cmath(void) | 
| Guido van Rossum | 71aa32f | 1996-01-12 01:34:57 +0000 | [diff] [blame] | 1280 | { | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1281 |     PyObject *m; | 
| Tim Peters | 14e2640 | 2001-02-20 20:15:19 +0000 | [diff] [blame] | 1282 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1283 |     m = PyModule_Create(&cmathmodule); | 
 | 1284 |     if (m == NULL) | 
 | 1285 |         return NULL; | 
| Fred Drake | f4e3484 | 2002-04-01 03:45:06 +0000 | [diff] [blame] | 1286 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1287 |     PyModule_AddObject(m, "pi", | 
 | 1288 |                        PyFloat_FromDouble(Py_MATH_PI)); | 
 | 1289 |     PyModule_AddObject(m, "e", PyFloat_FromDouble(Py_MATH_E)); | 
| Guido van Rossum | 0a891d7 | 2016-08-15 09:12:52 -0700 | [diff] [blame] | 1290 |     PyModule_AddObject(m, "tau", PyFloat_FromDouble(Py_MATH_TAU)); /* 2pi */ | 
| Mark Dickinson | 84e6311 | 2016-08-29 13:56:58 +0100 | [diff] [blame] | 1291 |     PyModule_AddObject(m, "inf", PyFloat_FromDouble(m_inf())); | 
 | 1292 |     PyModule_AddObject(m, "infj", PyComplex_FromCComplex(c_infj())); | 
 | 1293 | #if !defined(PY_NO_SHORT_FLOAT_REPR) || defined(Py_NAN) | 
 | 1294 |     PyModule_AddObject(m, "nan", PyFloat_FromDouble(m_nan())); | 
 | 1295 |     PyModule_AddObject(m, "nanj", PyComplex_FromCComplex(c_nanj())); | 
 | 1296 | #endif | 
| Christian Heimes | a342c01 | 2008-04-20 21:01:16 +0000 | [diff] [blame] | 1297 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1298 |     /* initialize special value tables */ | 
| Christian Heimes | a342c01 | 2008-04-20 21:01:16 +0000 | [diff] [blame] | 1299 |  | 
 | 1300 | #define INIT_SPECIAL_VALUES(NAME, BODY) { Py_complex* p = (Py_complex*)NAME; BODY } | 
 | 1301 | #define C(REAL, IMAG) p->real = REAL; p->imag = IMAG; ++p; | 
 | 1302 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1303 |     INIT_SPECIAL_VALUES(acos_special_values, { | 
 | 1304 |       C(P34,INF) C(P,INF)  C(P,INF)  C(P,-INF)  C(P,-INF)  C(P34,-INF) C(N,INF) | 
 | 1305 |       C(P12,INF) C(U,U)    C(U,U)    C(U,U)     C(U,U)     C(P12,-INF) C(N,N) | 
 | 1306 |       C(P12,INF) C(U,U)    C(P12,0.) C(P12,-0.) C(U,U)     C(P12,-INF) C(P12,N) | 
 | 1307 |       C(P12,INF) C(U,U)    C(P12,0.) C(P12,-0.) C(U,U)     C(P12,-INF) C(P12,N) | 
 | 1308 |       C(P12,INF) C(U,U)    C(U,U)    C(U,U)     C(U,U)     C(P12,-INF) C(N,N) | 
 | 1309 |       C(P14,INF) C(0.,INF) C(0.,INF) C(0.,-INF) C(0.,-INF) C(P14,-INF) C(N,INF) | 
 | 1310 |       C(N,INF)   C(N,N)    C(N,N)    C(N,N)     C(N,N)     C(N,-INF)   C(N,N) | 
 | 1311 |     }) | 
| Christian Heimes | a342c01 | 2008-04-20 21:01:16 +0000 | [diff] [blame] | 1312 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1313 |     INIT_SPECIAL_VALUES(acosh_special_values, { | 
 | 1314 |       C(INF,-P34) C(INF,-P)  C(INF,-P)  C(INF,P)  C(INF,P)  C(INF,P34) C(INF,N) | 
 | 1315 |       C(INF,-P12) C(U,U)     C(U,U)     C(U,U)    C(U,U)    C(INF,P12) C(N,N) | 
 | 1316 |       C(INF,-P12) C(U,U)     C(0.,-P12) C(0.,P12) C(U,U)    C(INF,P12) C(N,N) | 
 | 1317 |       C(INF,-P12) C(U,U)     C(0.,-P12) C(0.,P12) C(U,U)    C(INF,P12) C(N,N) | 
 | 1318 |       C(INF,-P12) C(U,U)     C(U,U)     C(U,U)    C(U,U)    C(INF,P12) C(N,N) | 
 | 1319 |       C(INF,-P14) C(INF,-0.) C(INF,-0.) C(INF,0.) C(INF,0.) C(INF,P14) C(INF,N) | 
 | 1320 |       C(INF,N)    C(N,N)     C(N,N)     C(N,N)    C(N,N)    C(INF,N)   C(N,N) | 
 | 1321 |     }) | 
| Christian Heimes | a342c01 | 2008-04-20 21:01:16 +0000 | [diff] [blame] | 1322 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1323 |     INIT_SPECIAL_VALUES(asinh_special_values, { | 
 | 1324 |       C(-INF,-P14) C(-INF,-0.) C(-INF,-0.) C(-INF,0.) C(-INF,0.) C(-INF,P14) C(-INF,N) | 
 | 1325 |       C(-INF,-P12) C(U,U)      C(U,U)      C(U,U)     C(U,U)     C(-INF,P12) C(N,N) | 
 | 1326 |       C(-INF,-P12) C(U,U)      C(-0.,-0.)  C(-0.,0.)  C(U,U)     C(-INF,P12) C(N,N) | 
 | 1327 |       C(INF,-P12)  C(U,U)      C(0.,-0.)   C(0.,0.)   C(U,U)     C(INF,P12)  C(N,N) | 
 | 1328 |       C(INF,-P12)  C(U,U)      C(U,U)      C(U,U)     C(U,U)     C(INF,P12)  C(N,N) | 
 | 1329 |       C(INF,-P14)  C(INF,-0.)  C(INF,-0.)  C(INF,0.)  C(INF,0.)  C(INF,P14)  C(INF,N) | 
 | 1330 |       C(INF,N)     C(N,N)      C(N,-0.)    C(N,0.)    C(N,N)     C(INF,N)    C(N,N) | 
 | 1331 |     }) | 
| Christian Heimes | a342c01 | 2008-04-20 21:01:16 +0000 | [diff] [blame] | 1332 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1333 |     INIT_SPECIAL_VALUES(atanh_special_values, { | 
 | 1334 |       C(-0.,-P12) C(-0.,-P12) C(-0.,-P12) C(-0.,P12) C(-0.,P12) C(-0.,P12) C(-0.,N) | 
 | 1335 |       C(-0.,-P12) C(U,U)      C(U,U)      C(U,U)     C(U,U)     C(-0.,P12) C(N,N) | 
 | 1336 |       C(-0.,-P12) C(U,U)      C(-0.,-0.)  C(-0.,0.)  C(U,U)     C(-0.,P12) C(-0.,N) | 
 | 1337 |       C(0.,-P12)  C(U,U)      C(0.,-0.)   C(0.,0.)   C(U,U)     C(0.,P12)  C(0.,N) | 
 | 1338 |       C(0.,-P12)  C(U,U)      C(U,U)      C(U,U)     C(U,U)     C(0.,P12)  C(N,N) | 
 | 1339 |       C(0.,-P12)  C(0.,-P12)  C(0.,-P12)  C(0.,P12)  C(0.,P12)  C(0.,P12)  C(0.,N) | 
 | 1340 |       C(0.,-P12)  C(N,N)      C(N,N)      C(N,N)     C(N,N)     C(0.,P12)  C(N,N) | 
 | 1341 |     }) | 
| Christian Heimes | a342c01 | 2008-04-20 21:01:16 +0000 | [diff] [blame] | 1342 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1343 |     INIT_SPECIAL_VALUES(cosh_special_values, { | 
 | 1344 |       C(INF,N) C(U,U) C(INF,0.)  C(INF,-0.) C(U,U) C(INF,N) C(INF,N) | 
 | 1345 |       C(N,N)   C(U,U) C(U,U)     C(U,U)     C(U,U) C(N,N)   C(N,N) | 
 | 1346 |       C(N,0.)  C(U,U) C(1.,0.)   C(1.,-0.)  C(U,U) C(N,0.)  C(N,0.) | 
 | 1347 |       C(N,0.)  C(U,U) C(1.,-0.)  C(1.,0.)   C(U,U) C(N,0.)  C(N,0.) | 
 | 1348 |       C(N,N)   C(U,U) C(U,U)     C(U,U)     C(U,U) C(N,N)   C(N,N) | 
 | 1349 |       C(INF,N) C(U,U) C(INF,-0.) C(INF,0.)  C(U,U) C(INF,N) C(INF,N) | 
 | 1350 |       C(N,N)   C(N,N) C(N,0.)    C(N,0.)    C(N,N) C(N,N)   C(N,N) | 
 | 1351 |     }) | 
| Christian Heimes | a342c01 | 2008-04-20 21:01:16 +0000 | [diff] [blame] | 1352 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1353 |     INIT_SPECIAL_VALUES(exp_special_values, { | 
 | 1354 |       C(0.,0.) C(U,U) C(0.,-0.)  C(0.,0.)  C(U,U) C(0.,0.) C(0.,0.) | 
 | 1355 |       C(N,N)   C(U,U) C(U,U)     C(U,U)    C(U,U) C(N,N)   C(N,N) | 
 | 1356 |       C(N,N)   C(U,U) C(1.,-0.)  C(1.,0.)  C(U,U) C(N,N)   C(N,N) | 
 | 1357 |       C(N,N)   C(U,U) C(1.,-0.)  C(1.,0.)  C(U,U) C(N,N)   C(N,N) | 
 | 1358 |       C(N,N)   C(U,U) C(U,U)     C(U,U)    C(U,U) C(N,N)   C(N,N) | 
 | 1359 |       C(INF,N) C(U,U) C(INF,-0.) C(INF,0.) C(U,U) C(INF,N) C(INF,N) | 
 | 1360 |       C(N,N)   C(N,N) C(N,-0.)   C(N,0.)   C(N,N) C(N,N)   C(N,N) | 
 | 1361 |     }) | 
| Christian Heimes | a342c01 | 2008-04-20 21:01:16 +0000 | [diff] [blame] | 1362 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1363 |     INIT_SPECIAL_VALUES(log_special_values, { | 
 | 1364 |       C(INF,-P34) C(INF,-P)  C(INF,-P)   C(INF,P)   C(INF,P)  C(INF,P34)  C(INF,N) | 
 | 1365 |       C(INF,-P12) C(U,U)     C(U,U)      C(U,U)     C(U,U)    C(INF,P12)  C(N,N) | 
 | 1366 |       C(INF,-P12) C(U,U)     C(-INF,-P)  C(-INF,P)  C(U,U)    C(INF,P12)  C(N,N) | 
 | 1367 |       C(INF,-P12) C(U,U)     C(-INF,-0.) C(-INF,0.) C(U,U)    C(INF,P12)  C(N,N) | 
 | 1368 |       C(INF,-P12) C(U,U)     C(U,U)      C(U,U)     C(U,U)    C(INF,P12)  C(N,N) | 
 | 1369 |       C(INF,-P14) C(INF,-0.) C(INF,-0.)  C(INF,0.)  C(INF,0.) C(INF,P14)  C(INF,N) | 
 | 1370 |       C(INF,N)    C(N,N)     C(N,N)      C(N,N)     C(N,N)    C(INF,N)    C(N,N) | 
 | 1371 |     }) | 
| Christian Heimes | a342c01 | 2008-04-20 21:01:16 +0000 | [diff] [blame] | 1372 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1373 |     INIT_SPECIAL_VALUES(sinh_special_values, { | 
 | 1374 |       C(INF,N) C(U,U) C(-INF,-0.) C(-INF,0.) C(U,U) C(INF,N) C(INF,N) | 
 | 1375 |       C(N,N)   C(U,U) C(U,U)      C(U,U)     C(U,U) C(N,N)   C(N,N) | 
 | 1376 |       C(0.,N)  C(U,U) C(-0.,-0.)  C(-0.,0.)  C(U,U) C(0.,N)  C(0.,N) | 
 | 1377 |       C(0.,N)  C(U,U) C(0.,-0.)   C(0.,0.)   C(U,U) C(0.,N)  C(0.,N) | 
 | 1378 |       C(N,N)   C(U,U) C(U,U)      C(U,U)     C(U,U) C(N,N)   C(N,N) | 
 | 1379 |       C(INF,N) C(U,U) C(INF,-0.)  C(INF,0.)  C(U,U) C(INF,N) C(INF,N) | 
 | 1380 |       C(N,N)   C(N,N) C(N,-0.)    C(N,0.)    C(N,N) C(N,N)   C(N,N) | 
 | 1381 |     }) | 
| Christian Heimes | a342c01 | 2008-04-20 21:01:16 +0000 | [diff] [blame] | 1382 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1383 |     INIT_SPECIAL_VALUES(sqrt_special_values, { | 
 | 1384 |       C(INF,-INF) C(0.,-INF) C(0.,-INF) C(0.,INF) C(0.,INF) C(INF,INF) C(N,INF) | 
 | 1385 |       C(INF,-INF) C(U,U)     C(U,U)     C(U,U)    C(U,U)    C(INF,INF) C(N,N) | 
 | 1386 |       C(INF,-INF) C(U,U)     C(0.,-0.)  C(0.,0.)  C(U,U)    C(INF,INF) C(N,N) | 
 | 1387 |       C(INF,-INF) C(U,U)     C(0.,-0.)  C(0.,0.)  C(U,U)    C(INF,INF) C(N,N) | 
 | 1388 |       C(INF,-INF) C(U,U)     C(U,U)     C(U,U)    C(U,U)    C(INF,INF) C(N,N) | 
 | 1389 |       C(INF,-INF) C(INF,-0.) C(INF,-0.) C(INF,0.) C(INF,0.) C(INF,INF) C(INF,N) | 
 | 1390 |       C(INF,-INF) C(N,N)     C(N,N)     C(N,N)    C(N,N)    C(INF,INF) C(N,N) | 
 | 1391 |     }) | 
| Christian Heimes | a342c01 | 2008-04-20 21:01:16 +0000 | [diff] [blame] | 1392 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1393 |     INIT_SPECIAL_VALUES(tanh_special_values, { | 
 | 1394 |       C(-1.,0.) C(U,U) C(-1.,-0.) C(-1.,0.) C(U,U) C(-1.,0.) C(-1.,0.) | 
 | 1395 |       C(N,N)    C(U,U) C(U,U)     C(U,U)    C(U,U) C(N,N)    C(N,N) | 
 | 1396 |       C(N,N)    C(U,U) C(-0.,-0.) C(-0.,0.) C(U,U) C(N,N)    C(N,N) | 
 | 1397 |       C(N,N)    C(U,U) C(0.,-0.)  C(0.,0.)  C(U,U) C(N,N)    C(N,N) | 
 | 1398 |       C(N,N)    C(U,U) C(U,U)     C(U,U)    C(U,U) C(N,N)    C(N,N) | 
 | 1399 |       C(1.,0.)  C(U,U) C(1.,-0.)  C(1.,0.)  C(U,U) C(1.,0.)  C(1.,0.) | 
 | 1400 |       C(N,N)    C(N,N) C(N,-0.)   C(N,0.)   C(N,N) C(N,N)    C(N,N) | 
 | 1401 |     }) | 
| Christian Heimes | a342c01 | 2008-04-20 21:01:16 +0000 | [diff] [blame] | 1402 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1403 |     INIT_SPECIAL_VALUES(rect_special_values, { | 
 | 1404 |       C(INF,N) C(U,U) C(-INF,0.) C(-INF,-0.) C(U,U) C(INF,N) C(INF,N) | 
 | 1405 |       C(N,N)   C(U,U) C(U,U)     C(U,U)      C(U,U) C(N,N)   C(N,N) | 
 | 1406 |       C(0.,0.) C(U,U) C(-0.,0.)  C(-0.,-0.)  C(U,U) C(0.,0.) C(0.,0.) | 
 | 1407 |       C(0.,0.) C(U,U) C(0.,-0.)  C(0.,0.)    C(U,U) C(0.,0.) C(0.,0.) | 
 | 1408 |       C(N,N)   C(U,U) C(U,U)     C(U,U)      C(U,U) C(N,N)   C(N,N) | 
 | 1409 |       C(INF,N) C(U,U) C(INF,-0.) C(INF,0.)   C(U,U) C(INF,N) C(INF,N) | 
 | 1410 |       C(N,N)   C(N,N) C(N,0.)    C(N,0.)     C(N,N) C(N,N)   C(N,N) | 
 | 1411 |     }) | 
 | 1412 |     return m; | 
| Guido van Rossum | 71aa32f | 1996-01-12 01:34:57 +0000 | [diff] [blame] | 1413 | } |