@@ -2180,74 +2180,154 @@ def test_special(self, z, wref):
2180
2180
w = np .log1p (z )
2181
2181
assert_equal (w , wref )
2182
2182
2183
- # Test w = log1p(z) for complex z (np.complex128).
2183
+ # Test w = log1p(z) for complex double z (np.complex128).
2184
2184
# Reference values were computed with mpmath, e.g.
2185
2185
# from mpmath import mp
2186
2186
# mp.dps = 200
2187
2187
# wref = complex(mp.log1p(z))
2188
2188
@pytest .mark .parametrize (
2189
2189
'z, wref' ,
2190
- [(1e-280 + 0j , 1e-280 + 0j ),
2190
+ [
2191
+ # Near 0+0j:
2192
+ (0.0 , 0.0 + 0.0j ),
2193
+ (3.4259e-13 + 6.71894e-08j ,
2194
+ 3.448472077361198e-13 + 6.718939999997688e-08j ),
2195
+ (1e-280 + 0j , 1e-280 + 0j ),
2191
2196
(1e-18 + 0j , 1e-18 + 0j ),
2192
2197
(1e-18 + 1e-12j , 1.0000005e-18 + 1e-12j ),
2193
- (1e-18 + 0.1j , 0.0049751654265840425 + 0.09966865249116204j ),
2194
2198
(- 1e-15 + 3e-8j , - 5.5e-16 + 3.000000000000002e-08j ),
2195
2199
(1e-15 + 3e-8j , 1.4499999999999983e-15 + 2.999999999999996e-08j ),
2196
2200
(1e-50 + 1e-200j , 1e-50 + 1e-200j ),
2197
2201
(1e-200 - 1e-200j , 1e-200 - 1e-200j ),
2198
2202
(1e-18j , 5.0000000000000005e-37 + 1e-18j ),
2203
+ (- 1.25e-8 + 5e-12j , - 1.2500000078124988e-08 + 5.0000000625e-12j ),
2204
+ (- 8e-8 - 0.0004j , 3.200000005993663e-15 - 0.0004000000106666662j ),
2205
+ # Close to or on the unit circle |z+1| = 1:
2199
2206
(- 4.999958e-05 - 0.009999833j ,
2200
2207
- 7.0554155328678184e-15 - 0.009999999665816696j ),
2201
- (3.4259e-13 + 6.71894e-08j ,
2202
- 3.448472077361198e-13 + 6.718939999997688e-08j ),
2203
- (0.1 + 1e-18j , 0.09531017980432487 + 9.090909090909091e-19j ),
2204
2208
(- 0.57113 - 0.90337j , 3.4168883248419116e-06 - 1.1275564209486122j ),
2205
- (0.2 + 0.3j , 0.21263386770217205 + 0.24497866312686414j ),
2209
+ (- 0.011228922063957758 + 0.14943813247359922j ,
2210
+ - 4.499779370610757e-17 + 0.15j ),
2211
+ (- 1.9999999995065196 - 3.141592653092555e-05j ,
2212
+ - 1.4766035946815242e-16 - 3.1415612376632573j ),
2213
+ (1e-18 + 0.1j , 0.0049751654265840425 + 0.09966865249116204j ),
2214
+ (0.1 + 1e-18j , 0.09531017980432487 + 9.090909090909091e-19j ),
2215
+ (- 1.25e-05 + 0.005j , 7.812499999381789e-11 + 0.005000020833177082j ),
2216
+ (- 0.01524813 - 0.173952j , - 2.228118716056777e-06 - 0.1748418364650139j ),
2217
+ # Very large real or imaginary part:
2206
2218
(1e200 + 1e200j , 460.8635921890891 + 0.7853981633974483j ),
2207
2219
(- 1 + 1e250j , 575.6462732485114 + 1.5707963267948966j ),
2208
2220
(1e250 + 1j , 575.6462732485114 + 1e-250j ),
2209
2221
(1e275 + 1e-225j , 633.2109005733626 + 0j ),
2210
- (- 0.75 + 0j , - 1.3862943611198906 + 0j )],
2222
+ # Other:
2223
+ (1.0 , 0.6931471805599453 + 0j ),
2224
+ (- 0.75 + 0j , - 1.3862943611198906 + 0j ),
2225
+ (0.2 + 0.3j , 0.21263386770217205 + 0.24497866312686414j ),
2226
+ (- 0.978249978133276 - 0.015379941691430407j ,
2227
+ - 3.6254002951579887 - 0.6154905511361795j ),
2228
+ ]
2211
2229
)
2212
2230
def test_complex_double (self , z , wref ):
2213
2231
w = np .log1p (z )
2214
- assert_allclose (w , wref , rtol = 1e-15 )
2232
+ assert_allclose (w .real , wref .real , rtol = 1e-15 )
2233
+ assert_allclose (w .imag , wref .imag , rtol = 1e-15 )
2215
2234
2216
- # Tes
67ED
t w = log1p(z) for complex z (np.complex64).
2235
+ # Test w = log1p(z) for complex float z (np.complex64).
2217
2236
# Reference values were computed with mpmath, e.g.
2218
2237
# from mpmath import mp
2219
2238
# mp.dps = 200
2220
2239
# wref = np.complex64(mp.log1p(z))
2221
2240
@pytest .mark .parametrize (
2222
2241
'z, wref' ,
2223
- [(np .complex64 (1e-10 + 3e-6j ), np .complex64 (1.045e-10 + 3e-06j )),
2242
+ [(np .complex64 (0.0 ), np .complex64 (0.0 )),
2243
+ (np .complex64 (1e-10 + 3e-6j ), np .complex64 (1.045e-10 + 3e-06j )),
2224
2244
(np .complex64 (- 1e-8 - 2e-5j ), np .complex64 (- 9.8e-09 - 2e-05j )),
2225
2245
(np .complex64 (- 2e-32 + 3e-32j ), np .complex64 (- 2e-32 + 3e-32j )),
2226
2246
(np .complex64 (- 0.57113 - 0.90337j ),
2227
2247
np .complex64 (3.4470238e-06 - 1.1275564j )),
2248
+ (np .complex64 (- 0.5 + 0.866025j ),
2249
+ np .complex64 (- 3.7479518e-07 + 1.0471973j )),
2250
+ (np .complex64 (- 3 - 0.5j ), np .complex64 (0.7234595 - 2.896614j )),
2251
+ (np .complex64 (2.0 - 0.5j ), np .complex64 (1.1123117 - 0.16514868j )),
2228
2252
(np .complex64 (3e31 - 4e31j ), np .complex64 (72.98958 - 0.9272952j ))]
2229
2253
)
2230
2254
def test_complex_single (self , z , wref ):
2231
2255
w = np .log1p (z )
2232
- assert_allclose (w , wref , rtol = 1e-6 )
2256
+ rtol = 5 * np .finfo (np .float32 ).eps
2257
+ assert_allclose (w .real , wref .real , rtol = rtol )
2258
+ assert_allclose (w .imag , wref .imag , rtol = rtol )
2259
+
2260
+ @pytest .mark .skipif (np .finfo (np .longdouble ).machep != - 63 ,
2261
+ reason = 'reference values are for 80 bit '
2262
+ 'extended precision' )
2263
+ def test_longdouble_is_80_bit_extended (self ):
2264
+ # Passing strings to np.longdouble() here is essential for
2265
+ # this test.
2266
+ z = np .longdouble ('-0.2' ) + np .longdouble ('0.6' )* 1j
2267
+ w = np .log1p (z )
2268
+ wref = (np .longdouble ('1.084202172485504434e-20' ) +
2269
+ np .longdouble ('0.6435011087932843868' )
F438
* 1j )
2270
+ rtol = 5 * np .finfo (np .longdouble ).eps
2271
+ assert_allclose (w .real , wref .real , rtol = rtol )
2272
+ assert_allclose (w .imag , wref .imag , rtol = rtol )
2273
+
2274
+ # The reference values for the IEEE float128 test were computed
2275
+ # with mpmath, e.g.:
2276
+ #
2277
+ # from mpmath import mp
2278
+ # mp.prec = 1024 # bits of precision
2279
+ # with mp.workprec(113): # Emulate IEEE float128 input
2280
+ # z = mp.mpc('-0.2', '0.6')
2281
+ # w = mp.log1p(z) # Compute with high precision.
2282
+ # with mp.workprec(113):
2283
+ # print(w.real)
2284
+ # print(w.imag)
2285
+ #
2286
+ @pytest .mark .skipif (np .finfo (np .longdouble ).machep != - 112 ,
2287
+ reason = 'reference values are for IEEE float128' )
2288
+ @pytest .mark .skipif (sys .platform == 'emscripten' ,
2289
+ reason = "emscripten's math library does not support "
2290
+ "IEEE float128" )
2291
+ @pytest .mark .parametrize (
2292
+ 'z, wref' ,
2293
+ [(np .longdouble ('-0.2' ) + np .longdouble ('0.6' )* 1j ,
2294
+ np .longdouble ('-1.92592994438723585305597794258493e-35' ) +
2295
+ np .longdouble ('0.643501108793284386802809228717323' )* 1j ),
2296
+ (np .longdouble ('3e-23' ) + np .longdouble ('-5e-22' )* 1j ,
2297
+ np .longdouble ('3.000000000000000000012455e-23' ) +
2298
+ np .longdouble ('-4.99999999999999999999985e-22' )* 1j ),
2299
+ (np .longdouble ('-1.3' ) + np .longdouble ('1.9' )* 1j ,
2300
+ np .longdouble ('0.654166409825089380175052108173541' ) +
2301
+ np .longdouble ('1.72739820377691197435359801635447' )* 1j )]
2302
+ )
2303
+ def test_longdouble_is_ieee_float128 (self , z , wref ):
2304
+ w = np .log1p (z )
2305
+ rtol = 5 * np .finfo (np .longdouble ).eps
2306
+ assert_allclose (w .real , wref .real , rtol = rtol )
2307
+ assert_allclose (w .imag , wref .imag , rtol = rtol )
2233
2308
2234
- def test_branch_cut (self ):
2309
+ @pytest .mark .parametrize ('typ' , [np .complex64 , np .complex128 ])
2310
+ def test_branch_cut (self , typ ):
2235
2311
x = - 1.5
2236
- zpos = complex (x , 0.0 )
2312
+ zpos = typ (x , 0.0 )
2237
2313
wpos = np .log1p (zpos )
2238
- assert wpos .imag == np .pi
2239
- zneg = complex (x , - 0.0 )
2314
+ realtype = zpos .real .dtype .type
2315
+ eps = np .finfo (realtype ).eps
2316
+ # On some platforms, atan2(0.0, -0.5) is not exactly equal to np.pi.
2317
+ assert_allclose (wpos .imag , realtype (np .pi ), rtol = 2 * eps )
2318
+ zneg = typ (x , - 0.0 )
2240
2319
wneg = np .log1p (zneg )
2241
- assert wneg .imag == - np .pi
2320
+ assert_allclose ( wneg .imag , realtype ( - np .pi ), rtol = 2 * eps )
2242
2321
assert wpos .real == wneg .real
2243
2322
2244
2323
@pytest .mark .parametrize ('x' , [- 0.5 , - 1e-12 , - 1e-18 , 0.0 , 1e-18 , 1e-12 ])
2245
- def test_imag_zero (self , x ):
2324
+ @pytest .mark .parametrize ('typ' , [np .complex64 , np .complex128 ])
2325
+ def test_imag_zero (self , x , typ ):
2246
2326
# Test real inputs with x > -1 and the imaginary part +/- 0.0.
2247
- zpos = complex (x , 0.0 )
2327
+ zpos = typ (x , 0.0 )
2248
2328
wpos = np .log1p (zpos )
2249
2329
assert_equal (wpos .imag , 0.0 )
2250
- zneg = complex (x , - 0.0 )
2330
+ zneg = typ (x , - 0.0 )
2251
2331
wneg = np .log1p (zneg )
2252
2332
assert_equal (wneg .imag , - 0.0 )
2253
2333
assert wpos .real == wneg .real
0 commit comments