diff options
Diffstat (limited to 'silx/math/test')
-rw-r--r-- | silx/math/test/benchmark_combo.py | 4 | ||||
-rw-r--r-- | silx/math/test/test_HistogramndLut_nominal.py | 15 | ||||
-rw-r--r-- | silx/math/test/test_combo.py | 141 | ||||
-rw-r--r-- | silx/math/test/test_histogramnd_error.py | 25 | ||||
-rw-r--r-- | silx/math/test/test_histogramnd_nominal.py | 21 |
5 files changed, 152 insertions, 54 deletions
diff --git a/silx/math/test/benchmark_combo.py b/silx/math/test/benchmark_combo.py index 4acc26b..ad5ae41 100644 --- a/silx/math/test/benchmark_combo.py +++ b/silx/math/test/benchmark_combo.py @@ -27,7 +27,7 @@ from __future__ import division __authors__ = ["T. Vincent"] __license__ = "MIT" -__date__ = "27/03/2017" +__date__ = "15/05/2017" import logging @@ -41,8 +41,6 @@ from silx.test.utils import ParametricTestCase, temp_dir from silx.math import combo - -logging.basicConfig() _logger = logging.getLogger(__name__) _logger.setLevel(logging.DEBUG) diff --git a/silx/math/test/test_HistogramndLut_nominal.py b/silx/math/test/test_HistogramndLut_nominal.py index 9c356bd..9450326 100644 --- a/silx/math/test/test_HistogramndLut_nominal.py +++ b/silx/math/test/test_HistogramndLut_nominal.py @@ -536,6 +536,21 @@ class _TestHistogramndLut_nominal(unittest.TestCase): self.assertTrue(np.array_equal(histo, expected_h)) self.assertTrue(np.array_equal(w_histo, expected_c)) + def testNoneNativeTypes(self): + type = self.sample.dtype.newbyteorder("B") + sampleB = self.sample.astype(type) + + type = self.sample.dtype.newbyteorder("L") + sampleL = self.sample.astype(type) + + histo_inst = HistogramndLut(sampleB, + self.histo_range, + self.n_bins) + + histo_inst = HistogramndLut(sampleL, + self.histo_range, + self.n_bins) + class TestHistogramndLut_nominal_1d(_TestHistogramndLut_nominal): ndims = 1 diff --git a/silx/math/test/test_combo.py b/silx/math/test/test_combo.py index 92eb8b4..b985cbd 100644 --- a/silx/math/test/test_combo.py +++ b/silx/math/test/test_combo.py @@ -1,6 +1,6 @@ # coding: utf-8 # /*########################################################################## -# Copyright (C) 2016 European Synchrotron Radiation Facility +# Copyright (C) 2016-2017 European Synchrotron Radiation Facility # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -47,46 +47,76 @@ class TestMinMax(ParametricTestCase): UNSIGNED_INT_DTYPES = 'uint8', 'uint16', 'uint32', 'uint64' DTYPES = FLOATING_DTYPES + SIGNED_INT_DTYPES + UNSIGNED_INT_DTYPES - def _test_min_max(self, data, min_positive): - """Compare min_max with numpy for the given dataset + def _numpy_min_max(self, data, min_positive=False, finite=False): + """Reference numpy implementation of min_max :param numpy.ndarray data: Data set to use for test :param bool min_positive: True to test with positive min + :param bool finite: True to only test finite values """ - result = min_max(data, min_positive) + data = numpy.array(data, copy=False) + if data.size == 0: + raise ValueError('Zero-sized array') + + minimum = None + argmin = None + maximum = None + argmax = None + min_pos = None + argmin_pos = None + + if finite: + filtered_data = data[numpy.isfinite(data)] + else: + filtered_data = data - minimum = numpy.nanmin(data) - if numpy.isnan(minimum): # All NaNs - self.assertTrue(numpy.isnan(result.minimum)) - self.assertEqual(result.argmin, 0) + if filtered_data.size > 0: + minimum = numpy.nanmin(filtered_data) + if numpy.isnan(minimum): + argmin = 0 + else: + # nanargmin equivalent + argmin = numpy.where(data == minimum)[0][0] - else: - self.assertEqual(result.minimum, minimum) + maximum = numpy.nanmax(filtered_data) + if numpy.isnan(maximum): + argmax = 0 + else: + # nanargmax equivalent + argmax = numpy.where(data == maximum)[0][0] - argmin = numpy.where(data == minimum)[0][0] - self.assertEqual(result.argmin, argmin) + if min_positive: + pos_data = filtered_data[filtered_data > 0] + if pos_data.size > 0: + min_pos = numpy.min(pos_data) + argmin_pos = numpy.where(data == min_pos)[0][0] - maximum = numpy.nanmax(data) - if numpy.isnan(maximum): # All NaNs - self.assertTrue(numpy.isnan(result.maximum)) - self.assertEqual(result.argmax, 0) + return minimum, min_pos, maximum, argmin, argmin_pos, argmax - else: - self.assertEqual(result.maximum, maximum) + def _test_min_max(self, data, min_positive, finite=False): + """Compare min_max with numpy for the given dataset - argmax = numpy.where(data == maximum)[0][0] - self.assertEqual(result.argmax, argmax) + :param numpy.ndarray data: Data set to use for test + :param bool min_positive: True to test with positive min + :param bool finite: True to only test finite values + """ + minimum, min_pos, maximum, argmin, argmin_pos, argmax = \ + self._numpy_min_max(data, min_positive, finite) - if min_positive: - pos_data = data[data > 0] - if len(pos_data) > 0: - min_pos = numpy.min(pos_data) - argmin_pos = numpy.where(data == min_pos)[0][0] - else: - min_pos = None - argmin_pos = None - self.assertEqual(result.min_positive, min_pos) - self.assertEqual(result.argmin_positive, argmin_pos) + result = min_max(data, min_positive, finite) + + self.assertSimilar(minimum, result.minimum) + self.assertSimilar(min_pos, result.min_positive) + self.assertSimilar(maximum, result.maximum) + self.assertSimilar(argmin, result.argmin) + self.assertSimilar(argmin_pos, result.argmin_positive) + self.assertSimilar(argmax, result.argmax) + + def assertSimilar(self, a, b): + """Assert that a and b are both None or NaN or that a == b.""" + self.assertTrue((a is None and b is None) or + (numpy.isnan(a) and numpy.isnan(b)) or + a == b) def test_different_datasets(self): """Test min_max with different numpy.arange datasets.""" @@ -122,39 +152,56 @@ class TestMinMax(ParametricTestCase): with self.assertRaises(ValueError): min_max(data) + NAN_TEST_DATA = [ + (float('nan'), float('nan')), # All NaNs + (float('nan'), 1.0), # NaN first and positive + (float('nan'), -1.0), # NaN first and negative + (1.0, 2.0, float('nan')), # NaN last and positive + (-1.0, -2.0, float('nan')), # NaN last and negative + (1.0, float('nan'), -1.0), # Some NaN + ] + def test_nandata(self): """Test min_max with NaN in data""" - tests = [ - (float('nan'), float('nan')), # All NaNs - (float('nan'), 1.0), # NaN first and positive - (float('nan'), -1.0), # NaN first and negative - (1.0, 2.0, float('nan')), # NaN last and positive - (-1.0, -2.0, float('nan')), # NaN last and negative - (1.0, float('nan'), -1.0), # Some NaN - ] - for dtype in self.FLOATING_DTYPES: - for data in tests: + for data in self.NAN_TEST_DATA: with self.subTest(dtype=dtype, data=data): data = numpy.array(data, dtype=dtype) self._test_min_max(data, min_positive=True) + INF_TEST_DATA = [ + [float('inf')] * 3, # All +inf + [float('-inf')] * 3, # All -inf + (float('inf'), float('-inf')), # + and - inf + (float('inf'), float('-inf'), float('nan')), # +/-inf, nan last + (float('nan'), float('-inf'), float('inf')), # +/-inf, nan first + (float('inf'), float('nan'), float('-inf')), # +/-inf, nan center + ] + def test_infdata(self): """Test min_max with inf.""" + for dtype in self.FLOATING_DTYPES: + for data in self.INF_TEST_DATA: + with self.subTest(dtype=dtype, data=data): + data = numpy.array(data, dtype=dtype) + self._test_min_max(data, min_positive=True) + + def test_finite(self): + """Test min_max with finite=True""" tests = [ - [float('inf')] * 3, # All +inf - [float('inf')] * 3, # All -inf - (float('inf'), float('-inf')), # + and - inf - (float('inf'), float('-inf'), float('nan')), # +/-inf, nan last - (float('nan'), float('-inf'), float('inf')), # +/-inf, nan first - (float('inf'), float('nan'), float('-inf')), # +/-inf, nan center + (-1., 2., 0.), # Basic test + (float('nan'), float('inf'), float('-inf')), # NaN + Inf + (float('nan'), float('inf'), -2, float('-inf')), # NaN + Inf + 1 value + (float('inf'), -3, -2), # values + inf ] + tests += self.INF_TEST_DATA + tests += self.NAN_TEST_DATA for dtype in self.FLOATING_DTYPES: for data in tests: with self.subTest(dtype=dtype, data=data): data = numpy.array(data, dtype=dtype) - self._test_min_max(data, min_positive=True) + self._test_min_max(data, min_positive=True, finite=True) def suite(): diff --git a/silx/math/test/test_histogramnd_error.py b/silx/math/test/test_histogramnd_error.py index 575eaf0..a8c66a0 100644 --- a/silx/math/test/test_histogramnd_error.py +++ b/silx/math/test/test_histogramnd_error.py @@ -426,6 +426,28 @@ class Test_chistogramnd_1D_errors(_Test_chistogramnd_errors): (np.uint16, np.double), (np.uint16, np.uint16)) +class Test_chistogramnd_ND_range(unittest.TestCase): + """ + + """ + + def test_invalid_histo_range(self): + data = np.random.random((60, 60)) + nbins = 10 + + with self.assertRaises(ValueError): + histo_range = data.min(), np.inf + + Histogramnd(sample=data.ravel(), + histo_range=histo_range, + n_bins=nbins) + + histo_range = data.min(), np.nan + + Histogramnd(sample=data.ravel(), + histo_range=histo_range, + n_bins=nbins) + class Test_chistogramnd_ND_errors(_Test_chistogramnd_errors): """ @@ -497,7 +519,8 @@ class Test_chistogramnd_ND_errors(_Test_chistogramnd_errors): test_cases = (Test_chistogramnd_1D_errors, - Test_chistogramnd_ND_errors,) + Test_chistogramnd_ND_errors, + Test_chistogramnd_ND_range) def suite(): diff --git a/silx/math/test/test_histogramnd_nominal.py b/silx/math/test/test_histogramnd_nominal.py index f4550e4..9f97521 100644 --- a/silx/math/test/test_histogramnd_nominal.py +++ b/silx/math/test/test_histogramnd_nominal.py @@ -666,8 +666,6 @@ class _Test_Histogramnd_nominal(unittest.TestCase): self.assertTrue(np.array_equal(histo, expected_h)) self.assertTrue(cumul is None) - - def test_nominal_last_bin_closed(self): """ """ @@ -842,7 +840,6 @@ class _Test_Histogramnd_nominal(unittest.TestCase): self.assertTrue(np.array_equal(histo, expected_h)) self.assertTrue(np.allclose(cumul, expected_c, rtol=10e-15)) - def test_accumulate_no_weights_at_init(self): """ """ @@ -883,6 +880,24 @@ class _Test_Histogramnd_nominal(unittest.TestCase): self.assertTrue(np.array_equal(histo, expected_h)) self.assertTrue(np.array_equal(cumul, expected_c)) + def testNoneNativeTypes(self): + type = self.sample.dtype.newbyteorder("B") + sampleB = self.sample.astype(type) + + type = self.sample.dtype.newbyteorder("L") + sampleL = self.sample.astype(type) + + histo_inst = Histogramnd(sampleB, + self.histo_range, + self.n_bins, + weights=self.weights) + + histo_inst = Histogramnd(sampleL, + self.histo_range, + self.n_bins, + weights=self.weights) + + class Test_chistogram_nominal_1d(_Test_chistogramnd_nominal): ndims = 1 |