comparison DEPENDENCIES/mingw32/Python27/Lib/site-packages/numpy/testing/utils.py @ 87:2a2c65a20a8b

Add Python libs and headers
author Chris Cannam
date Wed, 25 Feb 2015 14:05:22 +0000
parents
children
comparison
equal deleted inserted replaced
86:413a9d26189e 87:2a2c65a20a8b
1 """
2 Utility function to facilitate testing.
3
4 """
5 from __future__ import division, absolute_import, print_function
6
7 import os
8 import sys
9 import re
10 import operator
11 import warnings
12 from functools import partial
13 import shutil
14 import contextlib
15 from tempfile import mkdtemp
16 from .nosetester import import_nose
17 from numpy.core import float32, empty, arange, array_repr, ndarray
18
19 if sys.version_info[0] >= 3:
20 from io import StringIO
21 else:
22 from StringIO import StringIO
23
24 __all__ = ['assert_equal', 'assert_almost_equal', 'assert_approx_equal',
25 'assert_array_equal', 'assert_array_less', 'assert_string_equal',
26 'assert_array_almost_equal', 'assert_raises', 'build_err_msg',
27 'decorate_methods', 'jiffies', 'memusage', 'print_assert_equal',
28 'raises', 'rand', 'rundocs', 'runstring', 'verbose', 'measure',
29 'assert_', 'assert_array_almost_equal_nulp', 'assert_raises_regex',
30 'assert_array_max_ulp', 'assert_warns', 'assert_no_warnings',
31 'assert_allclose', 'IgnoreException']
32
33
34 verbose = 0
35
36
37 def assert_(val, msg='') :
38 """
39 Assert that works in release mode.
40 Accepts callable msg to allow deferring evaluation until failure.
41
42 The Python built-in ``assert`` does not work when executing code in
43 optimized mode (the ``-O`` flag) - no byte-code is generated for it.
44
45 For documentation on usage, refer to the Python documentation.
46
47 """
48 if not val :
49 try:
50 smsg = msg()
51 except TypeError:
52 smsg = msg
53 raise AssertionError(smsg)
54
55 def gisnan(x):
56 """like isnan, but always raise an error if type not supported instead of
57 returning a TypeError object.
58
59 Notes
60 -----
61 isnan and other ufunc sometimes return a NotImplementedType object instead
62 of raising any exception. This function is a wrapper to make sure an
63 exception is always raised.
64
65 This should be removed once this problem is solved at the Ufunc level."""
66 from numpy.core import isnan
67 st = isnan(x)
68 if isinstance(st, type(NotImplemented)):
69 raise TypeError("isnan not supported for this type")
70 return st
71
72 def gisfinite(x):
73 """like isfinite, but always raise an error if type not supported instead of
74 returning a TypeError object.
75
76 Notes
77 -----
78 isfinite and other ufunc sometimes return a NotImplementedType object instead
79 of raising any exception. This function is a wrapper to make sure an
80 exception is always raised.
81
82 This should be removed once this problem is solved at the Ufunc level."""
83 from numpy.core import isfinite, errstate
84 with errstate(invalid='ignore'):
85 st = isfinite(x)
86 if isinstance(st, type(NotImplemented)):
87 raise TypeError("isfinite not supported for this type")
88 return st
89
90 def gisinf(x):
91 """like isinf, but always raise an error if type not supported instead of
92 returning a TypeError object.
93
94 Notes
95 -----
96 isinf and other ufunc sometimes return a NotImplementedType object instead
97 of raising any exception. This function is a wrapper to make sure an
98 exception is always raised.
99
100 This should be removed once this problem is solved at the Ufunc level."""
101 from numpy.core import isinf, errstate
102 with errstate(invalid='ignore'):
103 st = isinf(x)
104 if isinstance(st, type(NotImplemented)):
105 raise TypeError("isinf not supported for this type")
106 return st
107
108 def rand(*args):
109 """Returns an array of random numbers with the given shape.
110
111 This only uses the standard library, so it is useful for testing purposes.
112 """
113 import random
114 from numpy.core import zeros, float64
115 results = zeros(args, float64)
116 f = results.flat
117 for i in range(len(f)):
118 f[i] = random.random()
119 return results
120
121 if sys.platform[:5]=='linux':
122 def jiffies(_proc_pid_stat = '/proc/%s/stat'%(os.getpid()),
123 _load_time=[]):
124 """ Return number of jiffies (1/100ths of a second) that this
125 process has been scheduled in user mode. See man 5 proc. """
126 import time
127 if not _load_time:
128 _load_time.append(time.time())
129 try:
130 f=open(_proc_pid_stat, 'r')
131 l = f.readline().split(' ')
132 f.close()
133 return int(l[13])
134 except:
135 return int(100*(time.time()-_load_time[0]))
136
137 def memusage(_proc_pid_stat = '/proc/%s/stat'%(os.getpid())):
138 """ Return virtual memory size in bytes of the running python.
139 """
140 try:
141 f=open(_proc_pid_stat, 'r')
142 l = f.readline().split(' ')
143 f.close()
144 return int(l[22])
145 except:
146 return
147 else:
148 # os.getpid is not in all platforms available.
149 # Using time is safe but inaccurate, especially when process
150 # was suspended or sleeping.
151 def jiffies(_load_time=[]):
152 """ Return number of jiffies (1/100ths of a second) that this
153 process has been scheduled in user mode. [Emulation with time.time]. """
154 import time
155 if not _load_time:
156 _load_time.append(time.time())
157 return int(100*(time.time()-_load_time[0]))
158 def memusage():
159 """ Return memory usage of running python. [Not implemented]"""
160 raise NotImplementedError
161
162 if os.name=='nt' and sys.version[:3] > '2.3':
163 # Code "stolen" from enthought/debug/memusage.py
164 def GetPerformanceAttributes(object, counter, instance = None,
165 inum=-1, format = None, machine=None):
166 # NOTE: Many counters require 2 samples to give accurate results,
167 # including "% Processor Time" (as by definition, at any instant, a
168 # thread's CPU usage is either 0 or 100). To read counters like this,
169 # you should copy this function, but keep the counter open, and call
170 # CollectQueryData() each time you need to know.
171 # See http://msdn.microsoft.com/library/en-us/dnperfmo/html/perfmonpt2.asp
172 # My older explanation for this was that the "AddCounter" process forced
173 # the CPU to 100%, but the above makes more sense :)
174 import win32pdh
175 if format is None: format = win32pdh.PDH_FMT_LONG
176 path = win32pdh.MakeCounterPath( (machine, object, instance, None, inum, counter) )
177 hq = win32pdh.OpenQuery()
178 try:
179 hc = win32pdh.AddCounter(hq, path)
180 try:
181 win32pdh.CollectQueryData(hq)
182 type, val = win32pdh.GetFormattedCounterValue(hc, format)
183 return val
184 finally:
185 win32pdh.RemoveCounter(hc)
186 finally:
187 win32pdh.CloseQuery(hq)
188
189 def memusage(processName="python", instance=0):
190 # from win32pdhutil, part of the win32all package
191 import win32pdh
192 return GetPerformanceAttributes("Process", "Virtual Bytes",
193 processName, instance,
194 win32pdh.PDH_FMT_LONG, None)
195
196 def build_err_msg(arrays, err_msg, header='Items are not equal:',
197 verbose=True, names=('ACTUAL', 'DESIRED'), precision=8):
198 msg = ['\n' + header]
199 if err_msg:
200 if err_msg.find('\n') == -1 and len(err_msg) < 79-len(header):
201 msg = [msg[0] + ' ' + err_msg]
202 else:
203 msg.append(err_msg)
204 if verbose:
205 for i, a in enumerate(arrays):
206
207 if isinstance(a, ndarray):
208 # precision argument is only needed if the objects are ndarrays
209 r_func = partial(array_repr, precision=precision)
210 else:
211 r_func = repr
212
213 try:
214 r = r_func(a)
215 except:
216 r = '[repr failed]'
217 if r.count('\n') > 3:
218 r = '\n'.join(r.splitlines()[:3])
219 r += '...'
220 msg.append(' %s: %s' % (names[i], r))
221 return '\n'.join(msg)
222
223 def assert_equal(actual,desired,err_msg='',verbose=True):
224 """
225 Raises an AssertionError if two objects are not equal.
226
227 Given two objects (scalars, lists, tuples, dictionaries or numpy arrays),
228 check that all elements of these objects are equal. An exception is raised
229 at the first conflicting values.
230
231 Parameters
232 ----------
233 actual : array_like
234 The object to check.
235 desired : array_like
236 The expected object.
237 err_msg : str, optional
238 The error message to be printed in case of failure.
239 verbose : bool, optional
240 If True, the conflicting values are appended to the error message.
241
242 Raises
243 ------
244 AssertionError
245 If actual and desired are not equal.
246
247 Examples
248 --------
249 >>> np.testing.assert_equal([4,5], [4,6])
250 ...
251 <type 'exceptions.AssertionError'>:
252 Items are not equal:
253 item=1
254 ACTUAL: 5
255 DESIRED: 6
256
257 """
258 if isinstance(desired, dict):
259 if not isinstance(actual, dict) :
260 raise AssertionError(repr(type(actual)))
261 assert_equal(len(actual), len(desired), err_msg, verbose)
262 for k, i in desired.items():
263 if k not in actual :
264 raise AssertionError(repr(k))
265 assert_equal(actual[k], desired[k], 'key=%r\n%s' % (k, err_msg), verbose)
266 return
267 if isinstance(desired, (list, tuple)) and isinstance(actual, (list, tuple)):
268 assert_equal(len(actual), len(desired), err_msg, verbose)
269 for k in range(len(desired)):
270 assert_equal(actual[k], desired[k], 'item=%r\n%s' % (k, err_msg), verbose)
271 return
272 from numpy.core import ndarray, isscalar, signbit
273 from numpy.lib import iscomplexobj, real, imag
274 if isinstance(actual, ndarray) or isinstance(desired, ndarray):
275 return assert_array_equal(actual, desired, err_msg, verbose)
276 msg = build_err_msg([actual, desired], err_msg, verbose=verbose)
277
278 # Handle complex numbers: separate into real/imag to handle
279 # nan/inf/negative zero correctly
280 # XXX: catch ValueError for subclasses of ndarray where iscomplex fail
281 try:
282 usecomplex = iscomplexobj(actual) or iscomplexobj(desired)
283 except ValueError:
284 usecomplex = False
285
286 if usecomplex:
287 if iscomplexobj(actual):
288 actualr = real(actual)
289 actuali = imag(actual)
290 else:
291 actualr = actual
292 actuali = 0
293 if iscomplexobj(desired):
294 desiredr = real(desired)
295 desiredi = imag(desired)
296 else:
297 desiredr = desired
298 desiredi = 0
299 try:
300 assert_equal(actualr, desiredr)
301 assert_equal(actuali, desiredi)
302 except AssertionError:
303 raise AssertionError(msg)
304
305 # Inf/nan/negative zero handling
306 try:
307 # isscalar test to check cases such as [np.nan] != np.nan
308 if isscalar(desired) != isscalar(actual):
309 raise AssertionError(msg)
310
311 # If one of desired/actual is not finite, handle it specially here:
312 # check that both are nan if any is a nan, and test for equality
313 # otherwise
314 if not (gisfinite(desired) and gisfinite(actual)):
315 isdesnan = gisnan(desired)
316 isactnan = gisnan(actual)
317 if isdesnan or isactnan:
318 if not (isdesnan and isactnan):
319 raise AssertionError(msg)
320 else:
321 if not desired == actual:
322 raise AssertionError(msg)
323 return
324 elif desired == 0 and actual == 0:
325 if not signbit(desired) == signbit(actual):
326 raise AssertionError(msg)
327 # If TypeError or ValueError raised while using isnan and co, just handle
328 # as before
329 except (TypeError, ValueError, NotImplementedError):
330 pass
331
332 # Explicitly use __eq__ for comparison, ticket #2552
333 if not (desired == actual):
334 raise AssertionError(msg)
335
336 def print_assert_equal(test_string, actual, desired):
337 """
338 Test if two objects are equal, and print an error message if test fails.
339
340 The test is performed with ``actual == desired``.
341
342 Parameters
343 ----------
344 test_string : str
345 The message supplied to AssertionError.
346 actual : object
347 The object to test for equality against `desired`.
348 desired : object
349 The expected result.
350
351 Examples
352 --------
353 >>> np.testing.print_assert_equal('Test XYZ of func xyz', [0, 1], [0, 1])
354 >>> np.testing.print_assert_equal('Test XYZ of func xyz', [0, 1], [0, 2])
355 Traceback (most recent call last):
356 ...
357 AssertionError: Test XYZ of func xyz failed
358 ACTUAL:
359 [0, 1]
360 DESIRED:
361 [0, 2]
362
363 """
364 import pprint
365
366 if not (actual == desired):
367 msg = StringIO()
368 msg.write(test_string)
369 msg.write(' failed\nACTUAL: \n')
370 pprint.pprint(actual, msg)
371 msg.write('DESIRED: \n')
372 pprint.pprint(desired, msg)
373 raise AssertionError(msg.getvalue())
374
375 def assert_almost_equal(actual,desired,decimal=7,err_msg='',verbose=True):
376 """
377 Raises an AssertionError if two items are not equal up to desired
378 precision.
379
380 .. note:: It is recommended to use one of `assert_allclose`,
381 `assert_array_almost_equal_nulp` or `assert_array_max_ulp`
382 instead of this function for more consistent floating point
383 comparisons.
384
385 The test is equivalent to ``abs(desired-actual) < 0.5 * 10**(-decimal)``.
386
387 Given two objects (numbers or ndarrays), check that all elements of these
388 objects are almost equal. An exception is raised at conflicting values.
389 For ndarrays this delegates to assert_array_almost_equal
390
391 Parameters
392 ----------
393 actual : array_like
394 The object to check.
395 desired : array_like
396 The expected object.
397 decimal : int, optional
398 Desired precision, default is 7.
399 err_msg : str, optional
400 The error message to be printed in case of failure.
401 verbose : bool, optional
402 If True, the conflicting values are appended to the error message.
403
404 Raises
405 ------
406 AssertionError
407 If actual and desired are not equal up to specified precision.
408
409 See Also
410 --------
411 assert_allclose: Compare two array_like objects for equality with desired
412 relative and/or absolute precision.
413 assert_array_almost_equal_nulp, assert_array_max_ulp, assert_equal
414
415 Examples
416 --------
417 >>> import numpy.testing as npt
418 >>> npt.assert_almost_equal(2.3333333333333, 2.33333334)
419 >>> npt.assert_almost_equal(2.3333333333333, 2.33333334, decimal=10)
420 ...
421 <type 'exceptions.AssertionError'>:
422 Items are not equal:
423 ACTUAL: 2.3333333333333002
424 DESIRED: 2.3333333399999998
425
426 >>> npt.assert_almost_equal(np.array([1.0,2.3333333333333]),
427 ... np.array([1.0,2.33333334]), decimal=9)
428 ...
429 <type 'exceptions.AssertionError'>:
430 Arrays are not almost equal
431 <BLANKLINE>
432 (mismatch 50.0%)
433 x: array([ 1. , 2.33333333])
434 y: array([ 1. , 2.33333334])
435
436 """
437 from numpy.core import ndarray
438 from numpy.lib import iscomplexobj, real, imag
439
440 # Handle complex numbers: separate into real/imag to handle
441 # nan/inf/negative zero correctly
442 # XXX: catch ValueError for subclasses of ndarray where iscomplex fail
443 try:
444 usecomplex = iscomplexobj(actual) or iscomplexobj(desired)
445 except ValueError:
446 usecomplex = False
447
448 def _build_err_msg():
449 header = ('Arrays are not almost equal to %d decimals' % decimal)
450 return build_err_msg([actual, desired], err_msg, verbose=verbose,
451 header=header)
452
453 if usecomplex:
454 if iscomplexobj(actual):
455 actualr = real(actual)
456 actuali = imag(actual)
457 else:
458 actualr = actual
459 actuali = 0
460 if iscomplexobj(desired):
461 desiredr = real(desired)
462 desiredi = imag(desired)
463 else:
464 desiredr = desired
465 desiredi = 0
466 try:
467 assert_almost_equal(actualr, desiredr, decimal=decimal)
468 assert_almost_equal(actuali, desiredi, decimal=decimal)
469 except AssertionError:
470 raise AssertionError(_build_err_msg())
471
472 if isinstance(actual, (ndarray, tuple, list)) \
473 or isinstance(desired, (ndarray, tuple, list)):
474 return assert_array_almost_equal(actual, desired, decimal, err_msg)
475 try:
476 # If one of desired/actual is not finite, handle it specially here:
477 # check that both are nan if any is a nan, and test for equality
478 # otherwise
479 if not (gisfinite(desired) and gisfinite(actual)):
480 if gisnan(desired) or gisnan(actual):
481 if not (gisnan(desired) and gisnan(actual)):
482 raise AssertionError(_build_err_msg())
483 else:
484 if not desired == actual:
485 raise AssertionError(_build_err_msg())
486 return
487 except (NotImplementedError, TypeError):
488 pass
489 if round(abs(desired - actual), decimal) != 0 :
490 raise AssertionError(_build_err_msg())
491
492
493 def assert_approx_equal(actual,desired,significant=7,err_msg='',verbose=True):
494 """
495 Raises an AssertionError if two items are not equal up to significant
496 digits.
497
498 .. note:: It is recommended to use one of `assert_allclose`,
499 `assert_array_almost_equal_nulp` or `assert_array_max_ulp`
500 instead of this function for more consistent floating point
501 comparisons.
502
503 Given two numbers, check that they are approximately equal.
504 Approximately equal is defined as the number of significant digits
505 that agree.
506
507 Parameters
508 ----------
509 actual : scalar
510 The object to check.
511 desired : scalar
512 The expected object.
513 significant : int, optional
514 Desired precision, default is 7.
515 err_msg : str, optional
516 The error message to be printed in case of failure.
517 verbose : bool, optional
518 If True, the conflicting values are appended to the error message.
519
520 Raises
521 ------
522 AssertionError
523 If actual and desired are not equal up to specified precision.
524
525 See Also
526 --------
527 assert_allclose: Compare two array_like objects for equality with desired
528 relative and/or absolute precision.
529 assert_array_almost_equal_nulp, assert_array_max_ulp, assert_equal
530
531 Examples
532 --------
533 >>> np.testing.assert_approx_equal(0.12345677777777e-20, 0.1234567e-20)
534 >>> np.testing.assert_approx_equal(0.12345670e-20, 0.12345671e-20,
535 significant=8)
536 >>> np.testing.assert_approx_equal(0.12345670e-20, 0.12345672e-20,
537 significant=8)
538 ...
539 <type 'exceptions.AssertionError'>:
540 Items are not equal to 8 significant digits:
541 ACTUAL: 1.234567e-021
542 DESIRED: 1.2345672000000001e-021
543
544 the evaluated condition that raises the exception is
545
546 >>> abs(0.12345670e-20/1e-21 - 0.12345672e-20/1e-21) >= 10**-(8-1)
547 True
548
549 """
550 import numpy as np
551
552 (actual, desired) = map(float, (actual, desired))
553 if desired==actual:
554 return
555 # Normalized the numbers to be in range (-10.0,10.0)
556 # scale = float(pow(10,math.floor(math.log10(0.5*(abs(desired)+abs(actual))))))
557 with np.errstate(invalid='ignore'):
558 scale = 0.5*(np.abs(desired) + np.abs(actual))
559 scale = np.power(10, np.floor(np.log10(scale)))
560 try:
561 sc_desired = desired/scale
562 except ZeroDivisionError:
563 sc_desired = 0.0
564 try:
565 sc_actual = actual/scale
566 except ZeroDivisionError:
567 sc_actual = 0.0
568 msg = build_err_msg([actual, desired], err_msg,
569 header='Items are not equal to %d significant digits:' %
570 significant,
571 verbose=verbose)
572 try:
573 # If one of desired/actual is not finite, handle it specially here:
574 # check that both are nan if any is a nan, and test for equality
575 # otherwise
576 if not (gisfinite(desired) and gisfinite(actual)):
577 if gisnan(desired) or gisnan(actual):
578 if not (gisnan(desired) and gisnan(actual)):
579 raise AssertionError(msg)
580 else:
581 if not desired == actual:
582 raise AssertionError(msg)
583 return
584 except (TypeError, NotImplementedError):
585 pass
586 if np.abs(sc_desired - sc_actual) >= np.power(10., -(significant-1)) :
587 raise AssertionError(msg)
588
589 def assert_array_compare(comparison, x, y, err_msg='', verbose=True,
590 header='', precision=6):
591 from numpy.core import array, isnan, isinf, any, all, inf
592 x = array(x, copy=False, subok=True)
593 y = array(y, copy=False, subok=True)
594
595 def isnumber(x):
596 return x.dtype.char in '?bhilqpBHILQPefdgFDG'
597
598 def chk_same_position(x_id, y_id, hasval='nan'):
599 """Handling nan/inf: check that x and y have the nan/inf at the same
600 locations."""
601 try:
602 assert_array_equal(x_id, y_id)
603 except AssertionError:
604 msg = build_err_msg([x, y],
605 err_msg + '\nx and y %s location mismatch:' \
606 % (hasval), verbose=verbose, header=header,
607 names=('x', 'y'), precision=precision)
608 raise AssertionError(msg)
609
610 try:
611 cond = (x.shape==() or y.shape==()) or x.shape == y.shape
612 if not cond:
613 msg = build_err_msg([x, y],
614 err_msg
615 + '\n(shapes %s, %s mismatch)' % (x.shape,
616 y.shape),
617 verbose=verbose, header=header,
618 names=('x', 'y'), precision=precision)
619 if not cond :
620 raise AssertionError(msg)
621
622 if isnumber(x) and isnumber(y):
623 x_isnan, y_isnan = isnan(x), isnan(y)
624 x_isinf, y_isinf = isinf(x), isinf(y)
625
626 # Validate that the special values are in the same place
627 if any(x_isnan) or any(y_isnan):
628 chk_same_position(x_isnan, y_isnan, hasval='nan')
629 if any(x_isinf) or any(y_isinf):
630 # Check +inf and -inf separately, since they are different
631 chk_same_position(x == +inf, y == +inf, hasval='+inf')
632 chk_same_position(x == -inf, y == -inf, hasval='-inf')
633
634 # Combine all the special values
635 x_id, y_id = x_isnan, y_isnan
636 x_id |= x_isinf
637 y_id |= y_isinf
638
639 # Only do the comparison if actual values are left
640 if all(x_id):
641 return
642
643 if any(x_id):
644 val = comparison(x[~x_id], y[~y_id])
645 else:
646 val = comparison(x, y)
647 else:
648 val = comparison(x, y)
649
650 if isinstance(val, bool):
651 cond = val
652 reduced = [0]
653 else:
654 reduced = val.ravel()
655 cond = reduced.all()
656 reduced = reduced.tolist()
657 if not cond:
658 match = 100-100.0*reduced.count(1)/len(reduced)
659 msg = build_err_msg([x, y],
660 err_msg
661 + '\n(mismatch %s%%)' % (match,),
662 verbose=verbose, header=header,
663 names=('x', 'y'), precision=precision)
664 if not cond :
665 raise AssertionError(msg)
666 except ValueError as e:
667 import traceback
668 efmt = traceback.format_exc()
669 header = 'error during assertion:\n\n%s\n\n%s' % (efmt, header)
670
671 msg = build_err_msg([x, y], err_msg, verbose=verbose, header=header,
672 names=('x', 'y'), precision=precision)
673 raise ValueError(msg)
674
675 def assert_array_equal(x, y, err_msg='', verbose=True):
676 """
677 Raises an AssertionError if two array_like objects are not equal.
678
679 Given two array_like objects, check that the shape is equal and all
680 elements of these objects are equal. An exception is raised at
681 shape mismatch or conflicting values. In contrast to the standard usage
682 in numpy, NaNs are compared like numbers, no assertion is raised if
683 both objects have NaNs in the same positions.
684
685 The usual caution for verifying equality with floating point numbers is
686 advised.
687
688 Parameters
689 ----------
690 x : array_like
691 The actual object to check.
692 y : array_like
693 The desired, expected object.
694 err_msg : str, optional
695 The error message to be printed in case of failure.
696 verbose : bool, optional
697 If True, the conflicting values are appended to the error message.
698
699 Raises
700 ------
701 AssertionError
702 If actual and desired objects are not equal.
703
704 See Also
705 --------
706 assert_allclose: Compare two array_like objects for equality with desired
707 relative and/or absolute precision.
708 assert_array_almost_equal_nulp, assert_array_max_ulp, assert_equal
709
710 Examples
711 --------
712 The first assert does not raise an exception:
713
714 >>> np.testing.assert_array_equal([1.0,2.33333,np.nan],
715 ... [np.exp(0),2.33333, np.nan])
716
717 Assert fails with numerical inprecision with floats:
718
719 >>> np.testing.assert_array_equal([1.0,np.pi,np.nan],
720 ... [1, np.sqrt(np.pi)**2, np.nan])
721 ...
722 <type 'exceptions.ValueError'>:
723 AssertionError:
724 Arrays are not equal
725 <BLANKLINE>
726 (mismatch 50.0%)
727 x: array([ 1. , 3.14159265, NaN])
728 y: array([ 1. , 3.14159265, NaN])
729
730 Use `assert_allclose` or one of the nulp (number of floating point values)
731 functions for these cases instead:
732
733 >>> np.testing.assert_allclose([1.0,np.pi,np.nan],
734 ... [1, np.sqrt(np.pi)**2, np.nan],
735 ... rtol=1e-10, atol=0)
736
737 """
738 assert_array_compare(operator.__eq__, x, y, err_msg=err_msg,
739 verbose=verbose, header='Arrays are not equal')
740
741 def assert_array_almost_equal(x, y, decimal=6, err_msg='', verbose=True):
742 """
743 Raises an AssertionError if two objects are not equal up to desired
744 precision.
745
746 .. note:: It is recommended to use one of `assert_allclose`,
747 `assert_array_almost_equal_nulp` or `assert_array_max_ulp`
748 instead of this function for more consistent floating point
749 comparisons.
750
751 The test verifies identical shapes and verifies values with
752 ``abs(desired-actual) < 0.5 * 10**(-decimal)``.
753
754 Given two array_like objects, check that the shape is equal and all
755 elements of these objects are almost equal. An exception is raised at
756 shape mismatch or conflicting values. In contrast to the standard usage
757 in numpy, NaNs are compared like numbers, no assertion is raised if
758 both objects have NaNs in the same positions.
759
760 Parameters
761 ----------
762 x : array_like
763 The actual object to check.
764 y : array_like
765 The desired, expected object.
766 decimal : int, optional
767 Desired precision, default is 6.
768 err_msg : str, optional
769 The error message to be printed in case of failure.
770 verbose : bool, optional
771 If True, the conflicting values are appended to the error message.
772
773 Raises
774 ------
775 AssertionError
776 If actual and desired are not equal up to specified precision.
777
778 See Also
779 --------
780 assert_allclose: Compare two array_like objects for equality with desired
781 relative and/or absolute precision.
782 assert_array_almost_equal_nulp, assert_array_max_ulp, assert_equal
783
784 Examples
785 --------
786 the first assert does not raise an exception
787
788 >>> np.testing.assert_array_almost_equal([1.0,2.333,np.nan],
789 [1.0,2.333,np.nan])
790
791 >>> np.testing.assert_array_almost_equal([1.0,2.33333,np.nan],
792 ... [1.0,2.33339,np.nan], decimal=5)
793 ...
794 <type 'exceptions.AssertionError'>:
795 AssertionError:
796 Arrays are not almost equal
797 <BLANKLINE>
798 (mismatch 50.0%)
799 x: array([ 1. , 2.33333, NaN])
800 y: array([ 1. , 2.33339, NaN])
801
802 >>> np.testing.assert_array_almost_equal([1.0,2.33333,np.nan],
803 ... [1.0,2.33333, 5], decimal=5)
804 <type 'exceptions.ValueError'>:
805 ValueError:
806 Arrays are not almost equal
807 x: array([ 1. , 2.33333, NaN])
808 y: array([ 1. , 2.33333, 5. ])
809
810 """
811 from numpy.core import around, number, float_, result_type, array
812 from numpy.core.numerictypes import issubdtype
813 from numpy.core.fromnumeric import any as npany
814 def compare(x, y):
815 try:
816 if npany(gisinf(x)) or npany( gisinf(y)):
817 xinfid = gisinf(x)
818 yinfid = gisinf(y)
819 if not xinfid == yinfid:
820 return False
821 # if one item, x and y is +- inf
822 if x.size == y.size == 1:
823 return x == y
824 x = x[~xinfid]
825 y = y[~yinfid]
826 except (TypeError, NotImplementedError):
827 pass
828
829 # make sure y is an inexact type to avoid abs(MIN_INT); will cause
830 # casting of x later.
831 dtype = result_type(y, 1.)
832 y = array(y, dtype=dtype, copy=False, subok=True)
833 z = abs(x-y)
834
835 if not issubdtype(z.dtype, number):
836 z = z.astype(float_) # handle object arrays
837
838 return around(z, decimal) <= 10.0**(-decimal)
839
840 assert_array_compare(compare, x, y, err_msg=err_msg, verbose=verbose,
841 header=('Arrays are not almost equal to %d decimals' % decimal),
842 precision=decimal)
843
844
845 def assert_array_less(x, y, err_msg='', verbose=True):
846 """
847 Raises an AssertionError if two array_like objects are not ordered by less
848 than.
849
850 Given two array_like objects, check that the shape is equal and all
851 elements of the first object are strictly smaller than those of the
852 second object. An exception is raised at shape mismatch or incorrectly
853 ordered values. Shape mismatch does not raise if an object has zero
854 dimension. In contrast to the standard usage in numpy, NaNs are
855 compared, no assertion is raised if both objects have NaNs in the same
856 positions.
857
858
859
860 Parameters
861 ----------
862 x : array_like
863 The smaller object to check.
864 y : array_like
865 The larger object to compare.
866 err_msg : string
867 The error message to be printed in case of failure.
868 verbose : bool
869 If True, the conflicting values are appended to the error message.
870
871 Raises
872 ------
873 AssertionError
874 If actual and desired objects are not equal.
875
876 See Also
877 --------
878 assert_array_equal: tests objects for equality
879 assert_array_almost_equal: test objects for equality up to precision
880
881
882
883 Examples
884 --------
885 >>> np.testing.assert_array_less([1.0, 1.0, np.nan], [1.1, 2.0, np.nan])
886 >>> np.testing.assert_array_less([1.0, 1.0, np.nan], [1, 2.0, np.nan])
887 ...
888 <type 'exceptions.ValueError'>:
889 Arrays are not less-ordered
890 (mismatch 50.0%)
891 x: array([ 1., 1., NaN])
892 y: array([ 1., 2., NaN])
893
894 >>> np.testing.assert_array_less([1.0, 4.0], 3)
895 ...
896 <type 'exceptions.ValueError'>:
897 Arrays are not less-ordered
898 (mismatch 50.0%)
899 x: array([ 1., 4.])
900 y: array(3)
901
902 >>> np.testing.assert_array_less([1.0, 2.0, 3.0], [4])
903 ...
904 <type 'exceptions.ValueError'>:
905 Arrays are not less-ordered
906 (shapes (3,), (1,) mismatch)
907 x: array([ 1., 2., 3.])
908 y: array([4])
909
910 """
911 assert_array_compare(operator.__lt__, x, y, err_msg=err_msg,
912 verbose=verbose,
913 header='Arrays are not less-ordered')
914
915 def runstring(astr, dict):
916 exec(astr, dict)
917
918 def assert_string_equal(actual, desired):
919 """
920 Test if two strings are equal.
921
922 If the given strings are equal, `assert_string_equal` does nothing.
923 If they are not equal, an AssertionError is raised, and the diff
924 between the strings is shown.
925
926 Parameters
927 ----------
928 actual : str
929 The string to test for equality against the expected string.
930 desired : str
931 The expected string.
932
933 Examples
934 --------
935 >>> np.testing.assert_string_equal('abc', 'abc')
936 >>> np.testing.assert_string_equal('abc', 'abcd')
937 Traceback (most recent call last):
938 File "<stdin>", line 1, in <module>
939 ...
940 AssertionError: Differences in strings:
941 - abc+ abcd? +
942
943 """
944 # delay import of difflib to reduce startup time
945 import difflib
946
947 if not isinstance(actual, str) :
948 raise AssertionError(repr(type(actual)))
949 if not isinstance(desired, str):
950 raise AssertionError(repr(type(desired)))
951 if re.match(r'\A'+desired+r'\Z', actual, re.M):
952 return
953
954 diff = list(difflib.Differ().compare(actual.splitlines(1), desired.splitlines(1)))
955 diff_list = []
956 while diff:
957 d1 = diff.pop(0)
958 if d1.startswith(' '):
959 continue
960 if d1.startswith('- '):
961 l = [d1]
962 d2 = diff.pop(0)
963 if d2.startswith('? '):
964 l.append(d2)
965 d2 = diff.pop(0)
966 if not d2.startswith('+ ') :
967 raise AssertionError(repr(d2))
968 l.append(d2)
969 d3 = diff.pop(0)
970 if d3.startswith('? '):
971 l.append(d3)
972 else:
973 diff.insert(0, d3)
974 if re.match(r'\A'+d2[2:]+r'\Z', d1[2:]):
975 continue
976 diff_list.extend(l)
977 continue
978 raise AssertionError(repr(d1))
979 if not diff_list:
980 return
981 msg = 'Differences in strings:\n%s' % (''.join(diff_list)).rstrip()
982 if actual != desired :
983 raise AssertionError(msg)
984
985
986 def rundocs(filename=None, raise_on_error=True):
987 """
988 Run doctests found in the given file.
989
990 By default `rundocs` raises an AssertionError on failure.
991
992 Parameters
993 ----------
994 filename : str
995 The path to the file for which the doctests are run.
996 raise_on_error : bool
997 Whether to raise an AssertionError when a doctest fails. Default is
998 True.
999
1000 Notes
1001 -----
1002 The doctests can be run by the user/developer by adding the ``doctests``
1003 argument to the ``test()`` call. For example, to run all tests (including
1004 doctests) for `numpy.lib`:
1005
1006 >>> np.lib.test(doctests=True) #doctest: +SKIP
1007 """
1008 import doctest, imp
1009 if filename is None:
1010 f = sys._getframe(1)
1011 filename = f.f_globals['__file__']
1012 name = os.path.splitext(os.path.basename(filename))[0]
1013 path = [os.path.dirname(filename)]
1014 file, pathname, description = imp.find_module(name, path)
1015 try:
1016 m = imp.load_module(name, file, pathname, description)
1017 finally:
1018 file.close()
1019
1020 tests = doctest.DocTestFinder().find(m)
1021 runner = doctest.DocTestRunner(verbose=False)
1022
1023 msg = []
1024 if raise_on_error:
1025 out = lambda s: msg.append(s)
1026 else:
1027 out = None
1028
1029 for test in tests:
1030 runner.run(test, out=out)
1031
1032 if runner.failures > 0 and raise_on_error:
1033 raise AssertionError("Some doctests failed:\n%s" % "\n".join(msg))
1034
1035
1036 def raises(*args,**kwargs):
1037 nose = import_nose()
1038 return nose.tools.raises(*args,**kwargs)
1039
1040
1041 def assert_raises(*args,**kwargs):
1042 """
1043 assert_raises(exception_class, callable, *args, **kwargs)
1044
1045 Fail unless an exception of class exception_class is thrown
1046 by callable when invoked with arguments args and keyword
1047 arguments kwargs. If a different type of exception is
1048 thrown, it will not be caught, and the test case will be
1049 deemed to have suffered an error, exactly as for an
1050 unexpected exception.
1051
1052 """
1053 nose = import_nose()
1054 return nose.tools.assert_raises(*args,**kwargs)
1055
1056
1057 assert_raises_regex_impl = None
1058
1059
1060 def assert_raises_regex(exception_class, expected_regexp,
1061 callable_obj=None, *args, **kwargs):
1062 """
1063 Fail unless an exception of class exception_class and with message that
1064 matches expected_regexp is thrown by callable when invoked with arguments
1065 args and keyword arguments kwargs.
1066
1067 Name of this function adheres to Python 3.2+ reference, but should work in
1068 all versions down to 2.6.
1069
1070 """
1071 nose = import_nose()
1072
1073 global assert_raises_regex_impl
1074 if assert_raises_regex_impl is None:
1075 try:
1076 # Python 3.2+
1077 assert_raises_regex_impl = nose.tools.assert_raises_regex
1078 except AttributeError:
1079 try:
1080 # 2.7+
1081 assert_raises_regex_impl = nose.tools.assert_raises_regexp
1082 except AttributeError:
1083 # 2.6
1084
1085 # This class is copied from Python2.7 stdlib almost verbatim
1086 class _AssertRaisesContext(object):
1087 """A context manager used to implement TestCase.assertRaises* methods."""
1088
1089 def __init__(self, expected, expected_regexp=None):
1090 self.expected = expected
1091 self.expected_regexp = expected_regexp
1092
1093 def failureException(self, msg):
1094 return AssertionError(msg)
1095
1096 def __enter__(self):
1097 return self
1098
1099 def __exit__(self, exc_type, exc_value, tb):
1100 if exc_type is None:
1101 try:
1102 exc_name = self.expected.__name__
1103 except AttributeError:
1104 exc_name = str(self.expected)
1105 raise self.failureException(
1106 "{0} not raised".format(exc_name))
1107 if not issubclass(exc_type, self.expected):
1108 # let unexpected exceptions pass through
1109 return False
1110 self.exception = exc_value # store for later retrieval
1111 if self.expected_regexp is None:
1112 return True
1113
1114 expected_regexp = self.expected_regexp
1115 if isinstance(expected_regexp, basestring):
1116 expected_regexp = re.compile(expected_regexp)
1117 if not expected_regexp.search(str(exc_value)):
1118 raise self.failureException(
1119 '"%s" does not match "%s"' %
1120 (expected_regexp.pattern, str(exc_value)))
1121 return True
1122
1123 def impl(cls, regex, callable_obj, *a, **kw):
1124 mgr = _AssertRaisesContext(cls, regex)
1125 if callable_obj is None:
1126 return mgr
1127 with mgr:
1128 callable_obj(*a, **kw)
1129 assert_raises_regex_impl = impl
1130
1131 return assert_raises_regex_impl(exception_class, expected_regexp,
1132 callable_obj, *args, **kwargs)
1133
1134
1135 def decorate_methods(cls, decorator, testmatch=None):
1136 """
1137 Apply a decorator to all methods in a class matching a regular expression.
1138
1139 The given decorator is applied to all public methods of `cls` that are
1140 matched by the regular expression `testmatch`
1141 (``testmatch.search(methodname)``). Methods that are private, i.e. start
1142 with an underscore, are ignored.
1143
1144 Parameters
1145 ----------
1146 cls : class
1147 Class whose methods to decorate.
1148 decorator : function
1149 Decorator to apply to methods
1150 testmatch : compiled regexp or str, optional
1151 The regular expression. Default value is None, in which case the
1152 nose default (``re.compile(r'(?:^|[\\b_\\.%s-])[Tt]est' % os.sep)``)
1153 is used.
1154 If `testmatch` is a string, it is compiled to a regular expression
1155 first.
1156
1157 """
1158 if testmatch is None:
1159 testmatch = re.compile(r'(?:^|[\\b_\\.%s-])[Tt]est' % os.sep)
1160 else:
1161 testmatch = re.compile(testmatch)
1162 cls_attr = cls.__dict__
1163
1164 # delayed import to reduce startup time
1165 from inspect import isfunction
1166
1167 methods = [_m for _m in cls_attr.values() if isfunction(_m)]
1168 for function in methods:
1169 try:
1170 if hasattr(function, 'compat_func_name'):
1171 funcname = function.compat_func_name
1172 else:
1173 funcname = function.__name__
1174 except AttributeError:
1175 # not a function
1176 continue
1177 if testmatch.search(funcname) and not funcname.startswith('_'):
1178 setattr(cls, funcname, decorator(function))
1179 return
1180
1181
1182 def measure(code_str,times=1,label=None):
1183 """
1184 Return elapsed time for executing code in the namespace of the caller.
1185
1186 The supplied code string is compiled with the Python builtin ``compile``.
1187 The precision of the timing is 10 milli-seconds. If the code will execute
1188 fast on this timescale, it can be executed many times to get reasonable
1189 timing accuracy.
1190
1191 Parameters
1192 ----------
1193 code_str : str
1194 The code to be timed.
1195 times : int, optional
1196 The number of times the code is executed. Default is 1. The code is
1197 only compiled once.
1198 label : str, optional
1199 A label to identify `code_str` with. This is passed into ``compile``
1200 as the second argument (for run-time error messages).
1201
1202 Returns
1203 -------
1204 elapsed : float
1205 Total elapsed time in seconds for executing `code_str` `times` times.
1206
1207 Examples
1208 --------
1209 >>> etime = np.testing.measure('for i in range(1000): np.sqrt(i**2)',
1210 ... times=times)
1211 >>> print "Time for a single execution : ", etime / times, "s"
1212 Time for a single execution : 0.005 s
1213
1214 """
1215 frame = sys._getframe(1)
1216 locs, globs = frame.f_locals, frame.f_globals
1217
1218 code = compile(code_str,
1219 'Test name: %s ' % label,
1220 'exec')
1221 i = 0
1222 elapsed = jiffies()
1223 while i < times:
1224 i += 1
1225 exec(code, globs, locs)
1226 elapsed = jiffies() - elapsed
1227 return 0.01*elapsed
1228
1229 def _assert_valid_refcount(op):
1230 """
1231 Check that ufuncs don't mishandle refcount of object `1`.
1232 Used in a few regression tests.
1233 """
1234 import numpy as np
1235 a = np.arange(100 * 100)
1236 b = np.arange(100*100).reshape(100, 100)
1237 c = b
1238
1239 i = 1
1240
1241 rc = sys.getrefcount(i)
1242 for j in range(15):
1243 d = op(b, c)
1244
1245 assert_(sys.getrefcount(i) >= rc)
1246
1247 def assert_allclose(actual, desired, rtol=1e-7, atol=0,
1248 err_msg='', verbose=True):
1249 """
1250 Raises an AssertionError if two objects are not equal up to desired
1251 tolerance.
1252
1253 The test is equivalent to ``allclose(actual, desired, rtol, atol)``.
1254 It compares the difference between `actual` and `desired` to
1255 ``atol + rtol * abs(desired)``.
1256
1257 .. versionadded:: 1.5.0
1258
1259 Parameters
1260 ----------
1261 actual : array_like
1262 Array obtained.
1263 desired : array_like
1264 Array desired.
1265 rtol : float, optional
1266 Relative tolerance.
1267 atol : float, optional
1268 Absolute tolerance.
1269 err_msg : str, optional
1270 The error message to be printed in case of failure.
1271 verbose : bool, optional
1272 If True, the conflicting values are appended to the error message.
1273
1274 Raises
1275 ------
1276 AssertionError
1277 If actual and desired are not equal up to specified precision.
1278
1279 See Also
1280 --------
1281 assert_array_almost_equal_nulp, assert_array_max_ulp
1282
1283 Examples
1284 --------
1285 >>> x = [1e-5, 1e-3, 1e-1]
1286 >>> y = np.arccos(np.cos(x))
1287 >>> assert_allclose(x, y, rtol=1e-5, atol=0)
1288
1289 """
1290 import numpy as np
1291 def compare(x, y):
1292 return np.allclose(x, y, rtol=rtol, atol=atol)
1293
1294 actual, desired = np.asanyarray(actual), np.asanyarray(desired)
1295 header = 'Not equal to tolerance rtol=%g, atol=%g' % (rtol, atol)
1296 assert_array_compare(compare, actual, desired, err_msg=str(err_msg),
1297 verbose=verbose, header=header)
1298
1299 def assert_array_almost_equal_nulp(x, y, nulp=1):
1300 """
1301 Compare two arrays relatively to their spacing.
1302
1303 This is a relatively robust method to compare two arrays whose amplitude
1304 is variable.
1305
1306 Parameters
1307 ----------
1308 x, y : array_like
1309 Input arrays.
1310 nulp : int, optional
1311 The maximum number of unit in the last place for tolerance (see Notes).
1312 Default is 1.
1313
1314 Returns
1315 -------
1316 None
1317
1318 Raises
1319 ------
1320 AssertionError
1321 If the spacing between `x` and `y` for one or more elements is larger
1322 than `nulp`.
1323
1324 See Also
1325 --------
1326 assert_array_max_ulp : Check that all items of arrays differ in at most
1327 N Units in the Last Place.
1328 spacing : Return the distance between x and the nearest adjacent number.
1329
1330 Notes
1331 -----
1332 An assertion is raised if the following condition is not met::
1333
1334 abs(x - y) <= nulps * spacing(max(abs(x), abs(y)))
1335
1336 Examples
1337 --------
1338 >>> x = np.array([1., 1e-10, 1e-20])
1339 >>> eps = np.finfo(x.dtype).eps
1340 >>> np.testing.assert_array_almost_equal_nulp(x, x*eps/2 + x)
1341
1342 >>> np.testing.assert_array_almost_equal_nulp(x, x*eps + x)
1343 Traceback (most recent call last):
1344 ...
1345 AssertionError: X and Y are not equal to 1 ULP (max is 2)
1346
1347 """
1348 import numpy as np
1349 ax = np.abs(x)
1350 ay = np.abs(y)
1351 ref = nulp * np.spacing(np.where(ax > ay, ax, ay))
1352 if not np.all(np.abs(x-y) <= ref):
1353 if np.iscomplexobj(x) or np.iscomplexobj(y):
1354 msg = "X and Y are not equal to %d ULP" % nulp
1355 else:
1356 max_nulp = np.max(nulp_diff(x, y))
1357 msg = "X and Y are not equal to %d ULP (max is %g)" % (nulp, max_nulp)
1358 raise AssertionError(msg)
1359
1360 def assert_array_max_ulp(a, b, maxulp=1, dtype=None):
1361 """
1362 Check that all items of arrays differ in at most N Units in the Last Place.
1363
1364 Parameters
1365 ----------
1366 a, b : array_like
1367 Input arrays to be compared.
1368 maxulp : int, optional
1369 The maximum number of units in the last place that elements of `a` and
1370 `b` can differ. Default is 1.
1371 dtype : dtype, optional
1372 Data-type to convert `a` and `b` to if given. Default is None.
1373
1374 Returns
1375 -------
1376 ret : ndarray
1377 Array containing number of representable floating point numbers between
1378 items in `a` and `b`.
1379
1380 Raises
1381 ------
1382 AssertionError
1383 If one or more elements differ by more than `maxulp`.
1384
1385 See Also
1386 --------
1387 assert_array_almost_equal_nulp : Compare two arrays relatively to their
1388 spacing.
1389
1390 Examples
1391 --------
1392 >>> a = np.linspace(0., 1., 100)
1393 >>> res = np.testing.assert_array_max_ulp(a, np.arcsin(np.sin(a)))
1394
1395 """
1396 import numpy as np
1397 ret = nulp_diff(a, b, dtype)
1398 if not np.all(ret <= maxulp):
1399 raise AssertionError("Arrays are not almost equal up to %g ULP" % \
1400 maxulp)
1401 return ret
1402
1403 def nulp_diff(x, y, dtype=None):
1404 """For each item in x and y, return the number of representable floating
1405 points between them.
1406
1407 Parameters
1408 ----------
1409 x : array_like
1410 first input array
1411 y : array_like
1412 second input array
1413
1414 Returns
1415 -------
1416 nulp : array_like
1417 number of representable floating point numbers between each item in x
1418 and y.
1419
1420 Examples
1421 --------
1422 # By definition, epsilon is the smallest number such as 1 + eps != 1, so
1423 # there should be exactly one ULP between 1 and 1 + eps
1424 >>> nulp_diff(1, 1 + np.finfo(x.dtype).eps)
1425 1.0
1426 """
1427 import numpy as np
1428 if dtype:
1429 x = np.array(x, dtype=dtype)
1430 y = np.array(y, dtype=dtype)
1431 else:
1432 x = np.array(x)
1433 y = np.array(y)
1434
1435 t = np.common_type(x, y)
1436 if np.iscomplexobj(x) or np.iscomplexobj(y):
1437 raise NotImplementedError("_nulp not implemented for complex array")
1438
1439 x = np.array(x, dtype=t)
1440 y = np.array(y, dtype=t)
1441
1442 if not x.shape == y.shape:
1443 raise ValueError("x and y do not have the same shape: %s - %s" % \
1444 (x.shape, y.shape))
1445
1446 def _diff(rx, ry, vdt):
1447 diff = np.array(rx-ry, dtype=vdt)
1448 return np.abs(diff)
1449
1450 rx = integer_repr(x)
1451 ry = integer_repr(y)
1452 return _diff(rx, ry, t)
1453
1454 def _integer_repr(x, vdt, comp):
1455 # Reinterpret binary representation of the float as sign-magnitude:
1456 # take into account two-complement representation
1457 # See also
1458 # http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
1459 rx = x.view(vdt)
1460 if not (rx.size == 1):
1461 rx[rx < 0] = comp - rx[rx<0]
1462 else:
1463 if rx < 0:
1464 rx = comp - rx
1465
1466 return rx
1467
1468 def integer_repr(x):
1469 """Return the signed-magnitude interpretation of the binary representation of
1470 x."""
1471 import numpy as np
1472 if x.dtype == np.float32:
1473 return _integer_repr(x, np.int32, np.int32(-2**31))
1474 elif x.dtype == np.float64:
1475 return _integer_repr(x, np.int64, np.int64(-2**63))
1476 else:
1477 raise ValueError("Unsupported dtype %s" % x.dtype)
1478
1479 # The following two classes are copied from python 2.6 warnings module (context
1480 # manager)
1481 class WarningMessage(object):
1482
1483 """
1484 Holds the result of a single showwarning() call.
1485
1486 Deprecated in 1.8.0
1487
1488 Notes
1489 -----
1490 `WarningMessage` is copied from the Python 2.6 warnings module,
1491 so it can be used in NumPy with older Python versions.
1492
1493 """
1494
1495 _WARNING_DETAILS = ("message", "category", "filename", "lineno", "file",
1496 "line")
1497
1498 def __init__(self, message, category, filename, lineno, file=None,
1499 line=None):
1500 local_values = locals()
1501 for attr in self._WARNING_DETAILS:
1502 setattr(self, attr, local_values[attr])
1503 if category:
1504 self._category_name = category.__name__
1505 else:
1506 self._category_name = None
1507
1508 def __str__(self):
1509 return ("{message : %r, category : %r, filename : %r, lineno : %s, "
1510 "line : %r}" % (self.message, self._category_name,
1511 self.filename, self.lineno, self.line))
1512
1513 class WarningManager(object):
1514 """
1515 A context manager that copies and restores the warnings filter upon
1516 exiting the context.
1517
1518 The 'record' argument specifies whether warnings should be captured by a
1519 custom implementation of ``warnings.showwarning()`` and be appended to a
1520 list returned by the context manager. Otherwise None is returned by the
1521 context manager. The objects appended to the list are arguments whose
1522 attributes mirror the arguments to ``showwarning()``.
1523
1524 The 'module' argument is to specify an alternative module to the module
1525 named 'warnings' and imported under that name. This argument is only useful
1526 when testing the warnings module itself.
1527
1528 Deprecated in 1.8.0
1529
1530 Notes
1531 -----
1532 `WarningManager` is a copy of the ``catch_warnings`` context manager
1533 from the Python 2.6 warnings module, with slight modifications.
1534 It is copied so it can be used in NumPy with older Python versions.
1535
1536 """
1537 def __init__(self, record=False, module=None):
1538 self._record = record
1539 if module is None:
1540 self._module = sys.modules['warnings']
1541 else:
1542 self._module = module
1543 self._entered = False
1544
1545 def __enter__(self):
1546 if self._entered:
1547 raise RuntimeError("Cannot enter %r twice" % self)
1548 self._entered = True
1549 self._filters = self._module.filters
1550 self._module.filters = self._filters[:]
1551 self._showwarning = self._module.showwarning
1552 if self._record:
1553 log = []
1554 def showwarning(*args, **kwargs):
1555 log.append(WarningMessage(*args, **kwargs))
1556 self._module.showwarning = showwarning
1557 return log
1558 else:
1559 return None
1560
1561 def __exit__(self):
1562 if not self._entered:
1563 raise RuntimeError("Cannot exit %r without entering first" % self)
1564 self._module.filters = self._filters
1565 self._module.showwarning = self._showwarning
1566
1567
1568 def assert_warns(warning_class, func, *args, **kw):
1569 """
1570 Fail unless the given callable throws the specified warning.
1571
1572 A warning of class warning_class should be thrown by the callable when
1573 invoked with arguments args and keyword arguments kwargs.
1574 If a different type of warning is thrown, it will not be caught, and the
1575 test case will be deemed to have suffered an error.
1576
1577 .. versionadded:: 1.4.0
1578
1579 Parameters
1580 ----------
1581 warning_class : class
1582 The class defining the warning that `func` is expected to throw.
1583 func : callable
1584 The callable to test.
1585 \\*args : Arguments
1586 Arguments passed to `func`.
1587 \\*\\*kwargs : Kwargs
1588 Keyword arguments passed to `func`.
1589
1590 Returns
1591 -------
1592 The value returned by `func`.
1593
1594 """
1595 with warnings.catch_warnings(record=True) as l:
1596 warnings.simplefilter('always')
1597 result = func(*args, **kw)
1598 if not len(l) > 0:
1599 raise AssertionError("No warning raised when calling %s"
1600 % func.__name__)
1601 if not l[0].category is warning_class:
1602 raise AssertionError("First warning for %s is not a " \
1603 "%s( is %s)" % (func.__name__, warning_class, l[0]))
1604 return result
1605
1606 def assert_no_warnings(func, *args, **kw):
1607 """
1608 Fail if the given callable produces any warnings.
1609
1610 .. versionadded:: 1.7.0
1611
1612 Parameters
1613 ----------
1614 func : callable
1615 The callable to test.
1616 \\*args : Arguments
1617 Arguments passed to `func`.
1618 \\*\\*kwargs : Kwargs
1619 Keyword arguments passed to `func`.
1620
1621 Returns
1622 -------
1623 The value returned by `func`.
1624
1625 """
1626 with warnings.catch_warnings(record=True) as l:
1627 warnings.simplefilter('always')
1628 result = func(*args, **kw)
1629 if len(l) > 0:
1630 raise AssertionError("Got warnings when calling %s: %s"
1631 % (func.__name__, l))
1632 return result
1633
1634
1635 def _gen_alignment_data(dtype=float32, type='binary', max_size=24):
1636 """
1637 generator producing data with different alignment and offsets
1638 to test simd vectorization
1639
1640 Parameters
1641 ----------
1642 dtype : dtype
1643 data type to produce
1644 type : string
1645 'unary': create data for unary operations, creates one input
1646 and output array
1647 'binary': create data for unary operations, creates two input
1648 and output array
1649 max_size : integer
1650 maximum size of data to produce
1651
1652 Returns
1653 -------
1654 if type is 'unary' yields one output, one input array and a message
1655 containing information on the data
1656 if type is 'binary' yields one output array, two input array and a message
1657 containing information on the data
1658
1659 """
1660 ufmt = 'unary offset=(%d, %d), size=%d, dtype=%r, %s'
1661 bfmt = 'binary offset=(%d, %d, %d), size=%d, dtype=%r, %s'
1662 for o in range(3):
1663 for s in range(o + 2, max(o + 3, max_size)):
1664 if type == 'unary':
1665 inp = lambda : arange(s, dtype=dtype)[o:]
1666 out = empty((s,), dtype=dtype)[o:]
1667 yield out, inp(), ufmt % (o, o, s, dtype, 'out of place')
1668 yield inp(), inp(), ufmt % (o, o, s, dtype, 'in place')
1669 yield out[1:], inp()[:-1], ufmt % \
1670 (o + 1, o, s - 1, dtype, 'out of place')
1671 yield out[:-1], inp()[1:], ufmt % \
1672 (o, o + 1, s - 1, dtype, 'out of place')
1673 yield inp()[:-1], inp()[1:], ufmt % \
1674 (o, o + 1, s - 1, dtype, 'aliased')
1675 yield inp()[1:], inp()[:-1], ufmt % \
1676 (o + 1, o, s - 1, dtype, 'aliased')
1677 if type == 'binary':
1678 inp1 = lambda :arange(s, dtype=dtype)[o:]
1679 inp2 = lambda :arange(s, dtype=dtype)[o:]
1680 out = empty((s,), dtype=dtype)[o:]
1681 yield out, inp1(), inp2(), bfmt % \
1682 (o, o, o, s, dtype, 'out of place')
1683 yield inp1(), inp1(), inp2(), bfmt % \
1684 (o, o, o, s, dtype, 'in place1')
1685 yield inp2(), inp1(), inp2(), bfmt % \
1686 (o, o, o, s, dtype, 'in place2')
1687 yield out[1:], inp1()[:-1], inp2()[:-1], bfmt % \
1688 (o + 1, o, o, s - 1, dtype, 'out of place')
1689 yield out[:-1], inp1()[1:], inp2()[:-1], bfmt % \
1690 (o, o + 1, o, s - 1, dtype, 'out of place')
1691 yield out[:-1], inp1()[:-1], inp2()[1:], bfmt % \
1692 (o, o, o + 1, s - 1, dtype, 'out of place')
1693 yield inp1()[1:], inp1()[:-1], inp2()[:-1], bfmt % \
1694 (o + 1, o, o, s - 1, dtype, 'aliased')
1695 yield inp1()[:-1], inp1()[1:], inp2()[:-1], bfmt % \
1696 (o, o + 1, o, s - 1, dtype, 'aliased')
1697 yield inp1()[:-1], inp1()[:-1], inp2()[1:], bfmt % \
1698 (o, o, o + 1, s - 1, dtype, 'aliased')
1699
1700
1701 class IgnoreException(Exception):
1702 "Ignoring this exception due to disabled feature"
1703
1704
1705 @contextlib.contextmanager
1706 def tempdir(*args, **kwargs):
1707 """Context manager to provide a temporary test folder.
1708
1709 All arguments are passed as this to the underlying tempfile.mkdtemp
1710 function.
1711
1712 """
1713 tmpdir = mkdtemp(*args, **kwargs)
1714 yield tmpdir
1715 shutil.rmtree(tmpdir)