diff --git a/CHANGES.txt b/CHANGES.txt index 73e05ed..86730c8 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -9,6 +9,8 @@ Unreleased - Correct the pond force unit to 0.00980665 N (one gram-force); it was previously 1000 times too large (`#44 `_). +- Convert quantity-valued `ediff1d` boundary differences to the input units. + ------ 0.16.4 ------ diff --git a/quantities/tests/test_umath.py b/quantities/tests/test_umath.py index 52383f7..f67c62e 100644 --- a/quantities/tests/test_umath.py +++ b/quantities/tests/test_umath.py @@ -105,6 +105,33 @@ def test_diff(self): def test_ediff1d(self): self.assertQuantityEqual(np.diff(self.q, 1), [1, 1, 1] * pq.J) + def test_ediff1d_boundary_units(self): + from ..quantity import Quantity + from ..umath import ediff1d + + values = [[1., 3.], [6., 10.]] * pq.m + for begin, end in ((100 * pq.cm, [200, 300] * pq.cm), + (1 * pq.m, [2, 3] * pq.m), + (1, [2, 3])): + with self.subTest(begin=begin, end=end): + self.assertQuantityEqual( + ediff1d(values, to_begin=begin, to_end=end), + [1., 2., 3., 4., 2., 3.] * pq.m, + ) + self.assertQuantityEqual(ediff1d(values, to_begin=100 * pq.cm), + [1., 2., 3., 4.] * pq.m) + self.assertQuantityEqual(ediff1d(values, to_end=200 * pq.cm), + [2., 3., 4., 2.] * pq.m) + self.assertRaises(ValueError, ediff1d, values, to_begin=1 * pq.s) + self.assertRaises(ValueError, ediff1d, values, to_end=1 * pq.s) + integer_values = Quantity([1, 3, 6], pq.m, dtype=int) + self.assertQuantityEqual(ediff1d(integer_values, to_begin=1), + [1, 2, 3] * pq.m) + # Converted fractional boundaries must obey NumPy's casting rules. + self.assertRaises(TypeError, ediff1d, integer_values, + to_begin=1 * pq.cm) + self.assertQuantityEqual(values, [[1., 3.], [6., 10.]] * pq.m) + def test_linspace(self): self.assertQuantityEqual(np.linspace(self.q[0], self.q[-1], 4), self.q) diff --git a/quantities/umath.py b/quantities/umath.py index 260b5cc..97700be 100644 --- a/quantities/umath.py +++ b/quantities/umath.py @@ -73,6 +73,11 @@ def ediff1d(ary, to_end=None, to_begin=None): if not isinstance(ary, Quantity): return np.ediff1d(ary, to_end, to_begin) + if isinstance(to_end, Quantity): + to_end = to_end.rescale(ary.dimensionality).magnitude + if isinstance(to_begin, Quantity): + to_begin = to_begin.rescale(ary.dimensionality).magnitude + return Quantity( np.ediff1d(ary.magnitude, to_end, to_begin), ary.dimensionality,