Skip to content

Commit 98fad81

Browse files
committed
* roll back rounding changes, they were too strict.
* allow magnitude of a quantity to be changed by passing a scalar to fill or __setitem__ * clean up tests
1 parent 2d3a388 commit 98fad81

File tree

7 files changed

+37
-86
lines changed

7 files changed

+37
-86
lines changed

CHANGES.txt

Lines changed: 5 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,31 +6,12 @@ CHANGES
66
0.8.0
77
-----
88

9-
In the interest of reproducing the same physical result regardless of
10-
the units used, several numpy ufuncs now require dimensionless
11-
operands:
9+
The fill method, and __setitem__ methods will now accept scalar
10+
values in addition to quantities. If a scalar is passed, an
11+
assumption is made that the change should only be applied to the
12+
quantity's magnitude. The fill method will also accept a quantity
13+
with incompatible units, and will overwrite the previous units.
1214

13-
* np.ceil
14-
* np.floor
15-
* np.fix
16-
* np.rint
17-
18-
This change is commensurate with the behavior of np.mod, np.fmod,
19-
and np.floor_division, which require the dimensionalities of the
20-
operands to be equal (both quantities can be expressed with the same
21-
units). The motivation for this behavior and the changes listed above
22-
is that the operations on quantities should yield the same physical
23-
result regardless of the units used at any point in the process. For
24-
example, before quantities-0.8.0::
25-
26-
foo = floor(3.3*pq.m)
27-
# foo = 3.0*pq.m
28-
bar = floor(3300.0*pq.mm)
29-
# bar = 3300.0*pq.mm
30-
fubar = foo != bar
31-
32-
This example indicates that floor (and friends) should only be defined
33-
for pure numbers and dimensionless quantities.
3415

3516
Bugs fixed
3617
**********

quantities/dimensionality.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,10 @@ def _d_copy(q1, out=None):
303303
p_dict[np.conjugate] = _d_copy
304304
p_dict[np.negative] = _d_copy
305305
p_dict[np.ones_like] = _d_copy
306+
p_dict[np.rint] = _d_copy
307+
p_dict[np.floor] = _d_copy
308+
p_dict[np.fix] = _d_copy
309+
p_dict[np.ceil] = _d_copy
306310

307311
def _d_sqrt(q1, out=None):
308312
return q1._dimensionality**0.5
@@ -334,7 +338,3 @@ def _d_dimensionless(q1, out=None):
334338
return Dimensionality()
335339
p_dict[np.log] = _d_dimensionless
336340
p_dict[np.exp] = _d_dimensionless
337-
p_dict[np.rint] = _d_dimensionless
338-
p_dict[np.floor] = _d_dimensionless
339-
p_dict[np.fix] = _d_dimensionless
340-
p_dict[np.ceil] = _d_dimensionless

quantities/quantity.py

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -325,11 +325,10 @@ def __getitem__(self, key):
325325

326326
@with_doc(np.ndarray.__setitem__)
327327
def __setitem__(self, key, value):
328-
if not isinstance(value, Quantity):
329-
value = Quantity(value)
330-
331-
# TODO: do we want this kind of magic?
332-
self.magnitude[key] = value.rescale(self._dimensionality).magnitude
328+
if isinstance(value, Quantity):
329+
if self._dimensionality != value._dimensionality:
330+
value = value.rescale(self._dimensionality)
331+
self.magnitude[key] = value
333332

334333
@with_doc(np.ndarray.__lt__)
335334
@wrap_comparison
@@ -401,14 +400,12 @@ def sum(self, axis=None, dtype=None, out=None):
401400
)
402401

403402
@with_doc(np.ndarray.fill)
404-
def fill(self, scalar):
405-
if not isinstance (scalar, Quantity):
406-
scalar = Quantity(scalar, copy=False)
407-
408-
if scalar._dimensionality == self._dimensionality:
409-
self.magnitude.fill(scalar.magnitude)
410-
else:
411-
raise ValueError("scalar must have the same units as self")
403+
def fill(self, value):
404+
self.magnitude.fill(value)
405+
try:
406+
self._dimensionality = value.dimensionality
407+
except AttributeError:
408+
pass
412409

413410
@with_doc(np.ndarray.put)
414411
def put(self, indicies, values, mode='raise'):

quantities/tests/test_25_quantity_arithmetic.py

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -158,30 +158,10 @@ def test_imod():
158158
def test_fmod():
159159
assert_quantity_almost_equal(np.fmod(10*pq.m, (3*pq.m)), 1*pq.m)
160160
assert_raises(ValueError, np.fmod, 10*pq.J, 3*pq.m)
161-
@skip_if(
162-
True,
163-
'known failure, needs __input_prepare__ in numpy'
164-
)
165-
def test_fmod_future():
166-
# requires __input_prepare__ in numpy:
167-
assert_quantity_almost_equal(
168-
np.fmod(10*pq.m, (3*pq.m).rescale('ft')),
169-
10*pq.m % (3*pq.m)
170-
)
171161

172162
def test_remainder():
173163
assert_quantity_almost_equal(np.remainder(10*pq.m, (3*pq.m)), 1*pq.m)
174164
assert_raises(ValueError, np.remainder, 10*pq.J, 3*pq.m)
175-
@skip_if(
176-
True,
177-
'known failure, needs __input_prepare__ in numpy'
178-
)
179-
def test_remainder_future():
180-
# requires __input_prepare__ in numpy:
181-
assert_quantity_almost_equal(
182-
np.remainder(10*pq.m, (3*pq.m).rescale('ft')),
183-
10*pq.m % (3*pq.m)
184-
)
185165

186166
def test_negative():
187167
assert_quantity_equal(

quantities/tests/test_30_quantity_conversion.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -208,9 +208,6 @@ def test(value):
208208
test(2 *pq.lb)
209209

210210
self.assertRaises(ValueError, test, 60 * pq.inch * pq.J)
211-
# even in the case when the quantity has no units
212-
# (maybe this could go away)
213-
self.assertRaises(ValueError, test, 60)
214211

215212
#test set item using slicing
216213
tempArray2 = [100, .2, -1, -5, -6] * pq.mA

quantities/tests/test_40_quantity_methods.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,8 @@ def test_numpy_functions(self):
6262

6363
# fill
6464
u = [[-100, 5, 6], [1, 2, 3]] * pq.m
65-
u.fill(6 * pq.m)
66-
self.numAssertEqual(u,[[6, 6, 6], [6, 6, 6]] * pq.m)
67-
# incompatible units:
68-
self.assertRaises(ValueError, u.fill, [[-100, 5, 6], [1, 2, 3]])
65+
u.fill(6 * pq.ft)
66+
self.numAssertEqual(u,[[6, 6, 6], [6, 6, 6]] * pq.ft)
6967

7068
# reshape
7169
y = [[1, 3, 4, 5], [1, 2, 3, 6]] * pq.inch

quantities/tests/test_50_umath.py

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from nose.tools import *
66
from numpy.testing import *
77
from numpy.testing.utils import *
8+
from numpy.testing.decorators import skipif as skip_if
89

910
import numpy as np
1011
import quantities as pq
@@ -157,37 +158,34 @@ def test_rounding():
157158
)
158159

159160
#test rint
160-
a = [-4.1, -3.6, -2.5, 0.1, 2.5, 3.1, 3.9] * pq.dimensionless
161+
a = [-4.1, -3.6, -2.5, 0.1, 2.5, 3.1, 3.9] * pq.m
161162
assert_array_almost_equal(
162163
np.rint(a),
163-
[-4., -4., -2., 0., 2., 3., 4.]
164+
[-4., -4., -2., 0., 2., 3., 4.]*pq.m
164165
)
165-
assert_raises(ValueError, np.rint, 3.3*pq.m)
166-
167-
# test fix
168-
# TODO: uncomment once np.fix behaves itself
169-
# assert_array_equal(np.fix(3.14 * pq.degF), 3.0 * pq.degF)
170-
# assert_array_equal(np.fix(3.0 * pq.degF), 3.0 * pq.degF)
171-
# assert_array_equal(
172-
# np.fix([2.1, 2.9, -2.1, -2.9] * pq.degF),
173-
# [2., 2., -2., -2.] * pq.degF
174-
# )
175166

176167
# test floor
177-
a = [-1.7, -1.5, -0.2, 0.2, 1.5, 1.7, 2.0] * pq.dimensionless
168+
a = [-1.7, -1.5, -0.2, 0.2, 1.5, 1.7, 2.0] * pq.m
178169
assert_array_almost_equal(
179170
np.floor(a),
180-
[-2., -2., -1., 0., 1., 1., 2.] * pq.dimensionless
171+
[-2., -2., -1., 0., 1., 1., 2.] * pq.m
181172
)
182-
assert_raises(ValueError, np.floor, 3.3*pq.m)
183173

184174
# test ceil
185-
a = [-1.7, -1.5, -0.2, 0.2, 1.5, 1.7, 2.0] * pq.dimensionless
175+
a = [-1.7, -1.5, -0.2, 0.2, 1.5, 1.7, 2.0] * pq.m
186176
assert_array_almost_equal(
187177
np.ceil(a),
188-
[-1., -1., -0., 1., 2., 2., 2.] * pq.dimensionless
178+
[-1., -1., -0., 1., 2., 2., 2.] * pq.m
179+
)
180+
181+
@skip_if(np.__version__[:3] < '1.4')
182+
def test_fix():
183+
assert_array_equal(np.fix(3.14 * pq.degF), 3.0 * pq.degF)
184+
assert_array_equal(np.fix(3.0 * pq.degF), 3.0 * pq.degF)
185+
assert_array_equal(
186+
np.fix([2.1, 2.9, -2.1, -2.9] * pq.degF),
187+
[2., 2., -2., -2.] * pq.degF
189188
)
190-
assert_raises(ValueError, np.ceil, 3.3*pq.m)
191189

192190

193191
def test_exponents_and_logarithms():

0 commit comments

Comments
 (0)