[yt-svn] commit/yt: 6 new changesets
commits-noreply at bitbucket.org
commits-noreply at bitbucket.org
Thu May 29 09:47:19 PDT 2014
6 new commits in yt:
https://bitbucket.org/yt_analysis/yt/commits/e3c68ccf0a9f/
Changeset: e3c68ccf0a9f
Branch: yt-3.0
User: ngoldbaum
Date: 2014-05-27 07:59:30
Summary: Improved compatibility for binary YTArray operations that include lists.
Affected #: 3 files
diff -r 4702092b7f7dd94137bc5efda428a62eb0532f04 -r e3c68ccf0a9f6f5ac630acef4d0f76d0d432fad3 yt/units/tests/test_ytarray.py
--- a/yt/units/tests/test_ytarray.py
+++ b/yt/units/tests/test_ytarray.py
@@ -36,7 +36,8 @@
YTUnitOperationError, YTUfuncUnitError
from yt.testing import fake_random_pf, requires_module
from yt.funcs import fix_length
-
+from yt.units.unit_symbols import \
+ cm, m, g
def operate_and_compare(a, b, op, answer):
# Test generator for YTArrays tests
@@ -56,32 +57,46 @@
# Same units
a1 = YTArray([1, 2, 3], 'cm')
a2 = YTArray([4, 5, 6], 'cm')
+ a3 = [4*cm, 5*cm, 6*cm]
answer = YTArray([5, 7, 9], 'cm')
yield operate_and_compare, a1, a2, operator.add, answer
yield operate_and_compare, a2, a1, operator.add, answer
+ yield operate_and_compare, a1, a3, operator.add, answer
+ yield operate_and_compare, a3, a1, operator.add, answer
+ yield operate_and_compare, a2, a1, np.add, answer
yield operate_and_compare, a1, a2, np.add, answer
- yield operate_and_compare, a2, a1, np.add, answer
+ yield operate_and_compare, a1, a3, np.add, answer
+ yield operate_and_compare, a3, a1, np.add, answer
# different units
a1 = YTArray([1, 2, 3], 'cm')
a2 = YTArray([4, 5, 6], 'm')
+ a3 = [4*m, 5*m, 6*m]
answer1 = YTArray([401, 502, 603], 'cm')
answer2 = YTArray([4.01, 5.02, 6.03], 'm')
yield operate_and_compare, a1, a2, operator.add, answer1
yield operate_and_compare, a2, a1, operator.add, answer2
+ yield operate_and_compare, a1, a3, operator.add, answer1
+ yield operate_and_compare, a3, a1, operator.add, answer1
yield assert_raises, YTUfuncUnitError, np.add, a1, a2
+ yield assert_raises, YTUfuncUnitError, np.add, a1, a3
# Test dimensionless quantities
a1 = YTArray([1, 2, 3])
a2 = array([4, 5, 6])
+ a3 = [4, 5, 6]
answer = YTArray([5, 7, 9])
yield operate_and_compare, a1, a2, operator.add, answer
yield operate_and_compare, a2, a1, operator.add, answer
+ yield operate_and_compare, a1, a3, operator.add, answer
+ yield operate_and_compare, a3, a1, operator.add, answer
yield operate_and_compare, a1, a2, np.add, answer
yield operate_and_compare, a2, a1, np.add, answer
+ yield operate_and_compare, a1, a3, np.add, answer
+ yield operate_and_compare, a3, a1, np.add, answer
# Catch the different dimensions error
a1 = YTArray([1, 2, 3], 'm')
@@ -100,34 +115,49 @@
# Same units
a1 = YTArray([1, 2, 3], 'cm')
a2 = YTArray([4, 5, 6], 'cm')
+ a3 = [4*cm, 5*cm, 6*cm]
answer1 = YTArray([-3, -3, -3], 'cm')
answer2 = YTArray([3, 3, 3], 'cm')
yield operate_and_compare, a1, a2, operator.sub, answer1
yield operate_and_compare, a2, a1, operator.sub, answer2
+ yield operate_and_compare, a1, a3, operator.sub, answer1
+ yield operate_and_compare, a3, a1, operator.sub, answer2
yield operate_and_compare, a1, a2, np.subtract, answer1
yield operate_and_compare, a2, a1, np.subtract, answer2
+ yield operate_and_compare, a1, a3, np.subtract, answer1
+ yield operate_and_compare, a3, a1, np.subtract, answer2
# different units
a1 = YTArray([1, 2, 3], 'cm')
a2 = YTArray([4, 5, 6], 'm')
+ a3 = [4*m, 5*m, 6*m]
answer1 = YTArray([-399, -498, -597], 'cm')
answer2 = YTArray([3.99, 4.98, 5.97], 'm')
+ answer3 = YTArray([399, 498, 597], 'cm')
yield operate_and_compare, a1, a2, operator.sub, answer1
yield operate_and_compare, a2, a1, operator.sub, answer2
+ yield operate_and_compare, a1, a3, operator.sub, answer1
+ yield operate_and_compare, a3, a1, operator.sub, answer3
yield assert_raises, YTUfuncUnitError, np.subtract, a1, a2
+ yield assert_raises, YTUfuncUnitError, np.subtract, a1, a3
# Test dimensionless quantities
a1 = YTArray([1, 2, 3])
a2 = array([4, 5, 6])
+ a3 = [4, 5, 6]
answer1 = YTArray([-3, -3, -3])
answer2 = YTArray([3, 3, 3])
yield operate_and_compare, a1, a2, operator.sub, answer1
yield operate_and_compare, a2, a1, operator.sub, answer2
+ yield operate_and_compare, a1, a3, operator.sub, answer1
+ yield operate_and_compare, a3, a1, operator.sub, answer2
yield operate_and_compare, a1, a2, np.subtract, answer1
yield operate_and_compare, a2, a1, np.subtract, answer2
+ yield operate_and_compare, a1, a3, np.subtract, answer1
+ yield operate_and_compare, a3, a1, np.subtract, answer2
# Catch the different dimensions error
a1 = YTArray([1, 2, 3], 'm')
@@ -146,54 +176,79 @@
# Same units
a1 = YTArray([1, 2, 3], 'cm')
a2 = YTArray([4, 5, 6], 'cm')
+ a3 = [4*cm, 5*cm, 6*cm]
answer = YTArray([4, 10, 18], 'cm**2')
yield operate_and_compare, a1, a2, operator.mul, answer
yield operate_and_compare, a2, a1, operator.mul, answer
+ yield operate_and_compare, a1, a3, operator.mul, answer
+ yield operate_and_compare, a3, a1, operator.mul, answer
yield operate_and_compare, a1, a2, np.multiply, answer
yield operate_and_compare, a2, a1, np.multiply, answer
+ yield operate_and_compare, a1, a3, np.multiply, answer
+ yield operate_and_compare, a3, a1, np.multiply, answer
# different units, same dimension
a1 = YTArray([1, 2, 3], 'cm')
a2 = YTArray([4, 5, 6], 'm')
+ a3 = [4*m, 5*m, 6*m]
answer1 = YTArray([400, 1000, 1800], 'cm**2')
answer2 = YTArray([.04, .10, .18], 'm**2')
answer3 = YTArray([4, 10, 18], 'cm*m')
yield operate_and_compare, a1, a2, operator.mul, answer1
yield operate_and_compare, a2, a1, operator.mul, answer2
+ yield operate_and_compare, a1, a3, operator.mul, answer1
+ yield operate_and_compare, a3, a1, operator.mul, answer2
yield operate_and_compare, a1, a2, np.multiply, answer3
yield operate_and_compare, a2, a1, np.multiply, answer3
+ yield operate_and_compare, a1, a3, np.multiply, answer3
+ yield operate_and_compare, a3, a1, np.multiply, answer3
# different dimensions
a1 = YTArray([1, 2, 3], 'cm')
a2 = YTArray([4, 5, 6], 'g')
+ a3 = [4*g, 5*g, 6*g]
answer = YTArray([4, 10, 18], 'cm*g')
yield operate_and_compare, a1, a2, operator.mul, answer
yield operate_and_compare, a2, a1, operator.mul, answer
+ yield operate_and_compare, a1, a3, operator.mul, answer
+ yield operate_and_compare, a3, a1, operator.mul, answer
yield operate_and_compare, a1, a2, np.multiply, answer
yield operate_and_compare, a2, a1, np.multiply, answer
+ yield operate_and_compare, a1, a3, np.multiply, answer
+ yield operate_and_compare, a3, a1, np.multiply, answer
# One dimensionless, one unitful
a1 = YTArray([1, 2, 3], 'cm')
a2 = array([4, 5, 6])
+ a3 = [4, 5, 6]
answer = YTArray([4, 10, 18], 'cm')
yield operate_and_compare, a1, a2, operator.mul, answer
yield operate_and_compare, a2, a1, operator.mul, answer
+ yield operate_and_compare, a1, a3, operator.mul, answer
+ yield operate_and_compare, a3, a1, operator.mul, answer
yield operate_and_compare, a1, a2, np.multiply, answer
yield operate_and_compare, a2, a1, np.multiply, answer
+ yield operate_and_compare, a1, a3, np.multiply, answer
+ yield operate_and_compare, a3, a1, np.multiply, answer
# Both dimensionless quantities
a1 = YTArray([1, 2, 3])
a2 = array([4, 5, 6])
+ a3 = [4, 5, 6]
answer = YTArray([4, 10, 18])
yield operate_and_compare, a1, a2, operator.mul, answer
yield operate_and_compare, a2, a1, operator.mul, answer
+ yield operate_and_compare, a1, a3, operator.mul, answer
+ yield operate_and_compare, a3, a1, operator.mul, answer
yield operate_and_compare, a1, a2, np.multiply, answer
yield operate_and_compare, a2, a1, np.multiply, answer
+ yield operate_and_compare, a1, a3, np.multiply, answer
+ yield operate_and_compare, a3, a1, np.multiply, answer
def test_division():
@@ -205,17 +260,23 @@
# Same units
a1 = YTArray([1., 2., 3.], 'cm')
a2 = YTArray([4., 5., 6.], 'cm')
+ a3 = [4*cm, 5*cm, 6*cm]
answer1 = YTArray([0.25, 0.4, 0.5])
answer2 = YTArray([4, 2.5, 2])
yield operate_and_compare, a1, a2, operator.div, answer1
yield operate_and_compare, a2, a1, operator.div, answer2
+ yield operate_and_compare, a1, a3, operator.div, answer1
+ yield operate_and_compare, a3, a1, operator.div, answer2
yield operate_and_compare, a1, a2, np.divide, answer1
yield operate_and_compare, a2, a1, np.divide, answer2
+ yield operate_and_compare, a1, a3, np.divide, answer1
+ yield operate_and_compare, a3, a1, np.divide, answer2
# different units, same dimension
a1 = YTArray([1., 2., 3.], 'cm')
a2 = YTArray([4., 5., 6.], 'm')
+ a3 = [4*m, 5*m, 6*m]
answer1 = YTArray([.0025, .004, .005])
answer2 = YTArray([400, 250, 200])
answer3 = YTArray([0.25, 0.4, 0.5], 'cm/m')
@@ -223,41 +284,60 @@
yield operate_and_compare, a1, a2, operator.div, answer1
yield operate_and_compare, a2, a1, operator.div, answer2
+ yield operate_and_compare, a1, a3, operator.div, answer1
+ yield operate_and_compare, a3, a1, operator.div, answer2
yield operate_and_compare, a1, a2, np.divide, answer3
yield operate_and_compare, a2, a1, np.divide, answer4
+ yield operate_and_compare, a1, a3, np.divide, answer3
+ yield operate_and_compare, a3, a1, np.divide, answer4
# different dimensions
a1 = YTArray([1., 2., 3.], 'cm')
a2 = YTArray([4., 5., 6.], 'g')
+ a3 = [4*g, 5*g, 6*g]
answer1 = YTArray([0.25, 0.4, 0.5], 'cm/g')
answer2 = YTArray([4, 2.5, 2], 'g/cm')
yield operate_and_compare, a1, a2, operator.div, answer1
yield operate_and_compare, a2, a1, operator.div, answer2
+ yield operate_and_compare, a1, a3, operator.div, answer1
+ yield operate_and_compare, a3, a1, operator.div, answer2
yield operate_and_compare, a1, a2, np.divide, answer1
yield operate_and_compare, a2, a1, np.divide, answer2
+ yield operate_and_compare, a1, a3, np.divide, answer1
+ yield operate_and_compare, a3, a1, np.divide, answer2
# One dimensionless, one unitful
a1 = YTArray([1., 2., 3.], 'cm')
a2 = array([4., 5., 6.])
+ a3 = [4, 5, 6]
answer1 = YTArray([0.25, 0.4, 0.5], 'cm')
answer2 = YTArray([4, 2.5, 2], '1/cm')
yield operate_and_compare, a1, a2, operator.div, answer1
yield operate_and_compare, a2, a1, operator.div, answer2
+ yield operate_and_compare, a1, a3, operator.div, answer1
+ yield operate_and_compare, a3, a1, operator.div, answer2
yield operate_and_compare, a1, a2, np.divide, answer1
yield operate_and_compare, a2, a1, np.divide, answer2
+ yield operate_and_compare, a1, a3, np.divide, answer1
+ yield operate_and_compare, a3, a1, np.divide, answer2
# Both dimensionless quantities
a1 = YTArray([1., 2., 3.])
a2 = array([4., 5., 6.])
+ a3 = [4, 5, 6]
answer1 = YTArray([0.25, 0.4, 0.5])
answer2 = YTArray([4, 2.5, 2])
yield operate_and_compare, a1, a2, operator.div, answer1
yield operate_and_compare, a2, a1, operator.div, answer2
- yield operate_and_compare, a1, a2, np.divide, answer1
- yield operate_and_compare, a2, a1, np.divide, answer2
+ yield operate_and_compare, a1, a3, operator.div, answer1
+ yield operate_and_compare, a3, a1, operator.div, answer2
+ yield operate_and_compare, a1, a3, np.divide, answer1
+ yield operate_and_compare, a3, a1, np.divide, answer2
+ yield operate_and_compare, a1, a3, np.divide, answer1
+ yield operate_and_compare, a3, a1, np.divide, answer2
def test_power():
@@ -662,7 +742,7 @@
yt_arr2 = YTArray.from_astropy(ap_arr)
ap_quan = 10.*_astropy.units.Msun**0.5/(_astropy.units.kpc**3)
- yt_quan = YTQuantity(10.,"sqrt(Msun)/kpc**3")
+ yt_quan = YTQuantity(10., "sqrt(Msun)/kpc**3")
yt_quan2 = YTQuantity.from_astropy(ap_quan)
yield assert_array_equal, ap_arr, yt_arr.to_astropy()
@@ -687,6 +767,7 @@
nu = YTASubclass([10, 11, 12], '')
nda = np.array([3, 4, 5])
yta = YTArray([6, 7, 8], 'mg')
+ loq = [YTQuantity(6, 'mg'), YTQuantity(7, 'mg'), YTQuantity(8, 'mg')]
ytq = YTQuantity(4, 'cm')
ndf = np.float64(3)
@@ -695,7 +776,7 @@
assert_isinstance(op(inst2, inst1), compare_class)
for op in (operator.mul, operator.div, operator.truediv):
- for inst in (b, ytq, ndf, yta, nda):
+ for inst in (b, ytq, ndf, yta, nda, loq):
yield op_comparison, op, a, inst, YTASubclass
yield op_comparison, op, ytq, nda, YTArray
@@ -705,6 +786,7 @@
yield op_comparison, op, nu, nda, YTASubclass
yield op_comparison, op, a, b, YTASubclass
yield op_comparison, op, a, yta, YTASubclass
+ yield op_comparison, op, a, loq, YTASubclass
yield assert_isinstance, a[0], YTQuantity
yield assert_isinstance, a[:], YTASubclass
diff -r 4702092b7f7dd94137bc5efda428a62eb0532f04 -r e3c68ccf0a9f6f5ac630acef4d0f76d0d432fad3 yt/units/yt_array.py
--- a/yt/units/yt_array.py
+++ b/yt/units/yt_array.py
@@ -33,7 +33,7 @@
from yt.units.dimensions import dimensionless
from yt.utilities.exceptions import \
YTUnitOperationError, YTUnitConversionError, \
- YTUfuncUnitError
+ YTUfuncUnitError, YTIterableUnitCoercionError
from numbers import Number as numeric_type
from yt.utilities.on_demand_imports import _astropy
from sympy import Rational
@@ -118,31 +118,45 @@
def comparison_unit(unit1, unit2):
return None
+def coerce_iterable_units(input_object):
+ if isinstance(input_object, YTArray):
+ return input_object
+ if iterable(input_object):
+ if any([not isinstance(o, (YTQuantity, numeric_type))
+ for o in input_object]):
+ ff = input_object[0].units
+ if any([not ff.same_dimensions_as(getattr(_, 'units', Unit()))
+ for _ in input_object]):
+ raise YTIterableUnitCoercionError(input_object)
+ return YTArray(input_object)
+ else:
+ return input_object
+
def sanitize_units_mul(this_object, other_object):
- ret = other_object
+ inp = coerce_iterable_units(this_object)
+ ret = coerce_iterable_units(other_object)
# If the other object is a YTArray and has the same dimensions as the object
# under consideration, convert so we don't mix units with the same
# dimensions.
- if isinstance(other_object, YTArray):
- if this_object.units.same_dimensions_as(other_object.units):
- ret = other_object.in_units(this_object.units)
+ if isinstance(ret, YTArray):
+ if inp.units.same_dimensions_as(ret.units):
+ ret.convert_to_units(inp.units)
return ret
def sanitize_units_add(this_object, other_object, op_string):
+ inp = coerce_iterable_units(this_object)
+ ret = coerce_iterable_units(other_object)
# Make sure the other object is a YTArray before we use the `units`
# attribute.
- if isinstance(other_object, YTArray):
- if not this_object.units.same_dimensions_as(other_object.units):
- raise YTUnitOperationError(op_string, this_object.units,
- other_object.units)
- ret = other_object.in_units(this_object.units)
+ if isinstance(ret, YTArray):
+ if not inp.units.same_dimensions_as(ret.units):
+ raise YTUnitOperationError(op_string, inp.units, ret.units)
+ ret = ret.in_units(inp.units)
# If the other object is not a YTArray, the only valid case is adding
# dimensionless things.
else:
- if not this_object.units.is_dimensionless:
- raise YTUnitOperationError(op_string, this_object.units,
- dimensionless)
- ret = other_object
+ if not inp.units.is_dimensionless:
+ raise YTUnitOperationError(op_string, inp.units, dimensionless)
return ret
unary_operators = (
@@ -903,17 +917,19 @@
raise YTUnitOperationError(context[0], u)
ret_class = type(self)
elif context[0] in binary_operators:
- unit1 = getattr(context[1][0], 'units', None)
- unit2 = getattr(context[1][1], 'units', None)
- cls1 = type(context[1][0])
- cls2 = type(context[1][1])
+ oper1 = coerce_iterable_units(context[1][0])
+ oper2 = coerce_iterable_units(context[1][1])
+ cls1 = type(oper1)
+ cls2 = type(oper2)
+ unit1 = getattr(oper1, 'units', None)
+ unit2 = getattr(oper2, 'units', None)
ret_class = get_binary_op_return_class(cls1, cls2)
if unit1 is None:
unit1 = Unit(registry=getattr(unit2, 'registry', None))
if unit2 is None and context[0] is not power:
unit2 = Unit(registry=getattr(unit1, 'registry', None))
elif context[0] is power:
- unit2 = context[1][1]
+ unit2 = oper2
if isinstance(unit2, np.ndarray):
if isinstance(unit2, YTArray):
if unit2.units.is_dimensionless:
@@ -1029,9 +1045,9 @@
def get_binary_op_return_class(cls1, cls2):
if cls1 is cls2:
return cls1
- if cls1 is np.ndarray or issubclass(cls1, (numeric_type, np.number)):
+ if cls1 is np.ndarray or issubclass(cls1, (numeric_type, np.number, list, tuple)):
return cls2
- if cls2 is np.ndarray or issubclass(cls2, (numeric_type, np.number)):
+ if cls2 is np.ndarray or issubclass(cls2, (numeric_type, np.number, list, tuple)):
return cls1
if issubclass(cls1, YTQuantity):
return cls2
@@ -1042,5 +1058,5 @@
if issubclass(cls2, cls1):
return cls2
else:
- raise RuntimeError("Operations are only defined on pairs of objects"
- "in which one is a subclass of the other")
+ raise RuntimeError("Undefined operation for a YTArray subclass. "
+ "Received operand types (%s) and (%s)" % (cls1, cls2))
diff -r 4702092b7f7dd94137bc5efda428a62eb0532f04 -r e3c68ccf0a9f6f5ac630acef4d0f76d0d432fad3 yt/utilities/exceptions.py
--- a/yt/utilities/exceptions.py
+++ b/yt/utilities/exceptions.py
@@ -193,9 +193,18 @@
def __str__(self):
err = "The NumPy %s operation is only allowed on objects with " \
- "identical units. Convert one of the arrays to the other\'s " \
- "units first. Received units (%s) and (%s)." % \
- (self.ufunc, self.unit1, self.unit2)
+ "identical units. Convert one of the arrays to the other\'s " \
+ "units first. Received units (%s) and (%s)." % \
+ (self.ufunc, self.unit1, self.unit2)
+ return err
+
+class YTIterableUnitCoercionError(YTException):
+ def __init__(self, quantity_list):
+ self.quantity_list = quantity_list
+
+ def __str__(self):
+ err = "Received a list or tuple of quantities with nonuniform units: " \
+ "%s" % self.quantity_list
return err
class YTHubRegisterError(YTException):
https://bitbucket.org/yt_analysis/yt/commits/27f6db04a8ef/
Changeset: 27f6db04a8ef
Branch: yt-3.0
User: ngoldbaum
Date: 2014-05-27 08:15:14
Summary: Improving efficiency and correctness of coercion logic.
Affected #: 1 file
diff -r e3c68ccf0a9f6f5ac630acef4d0f76d0d432fad3 -r 27f6db04a8efcd286ed3c1c442ad0f514f5c4ba8 yt/units/yt_array.py
--- a/yt/units/yt_array.py
+++ b/yt/units/yt_array.py
@@ -122,13 +122,13 @@
if isinstance(input_object, YTArray):
return input_object
if iterable(input_object):
- if any([not isinstance(o, (YTQuantity, numeric_type))
- for o in input_object]):
+ if all([isinstance(o, YTQuantity) for o in input_object]):
ff = input_object[0].units
if any([not ff.same_dimensions_as(getattr(_, 'units', Unit()))
for _ in input_object]):
raise YTIterableUnitCoercionError(input_object)
- return YTArray(input_object)
+ return YTArray(input_object)
+ return input_object
else:
return input_object
https://bitbucket.org/yt_analysis/yt/commits/3ea4944887cf/
Changeset: 3ea4944887cf
Branch: yt-3.0
User: ngoldbaum
Date: 2014-05-27 08:36:41
Summary: Avoid in-place conversions where we might stomp on user data.
Affected #: 1 file
diff -r 27f6db04a8efcd286ed3c1c442ad0f514f5c4ba8 -r 3ea4944887cfaa0bc427a8635455fe609c653043 yt/units/yt_array.py
--- a/yt/units/yt_array.py
+++ b/yt/units/yt_array.py
@@ -122,7 +122,8 @@
if isinstance(input_object, YTArray):
return input_object
if iterable(input_object):
- if all([isinstance(o, YTQuantity) for o in input_object]):
+ # This will create a copy of the data in the iterable.
+ if all([isinstance(o, YTArray) for o in input_object]):
ff = input_object[0].units
if any([not ff.same_dimensions_as(getattr(_, 'units', Unit()))
for _ in input_object]):
@@ -140,7 +141,7 @@
# dimensions.
if isinstance(ret, YTArray):
if inp.units.same_dimensions_as(ret.units):
- ret.convert_to_units(inp.units)
+ ret.in_units(inp.units)
return ret
def sanitize_units_add(this_object, other_object, op_string):
@@ -283,7 +284,7 @@
elif isinstance(input_array, np.ndarray):
pass
elif iterable(input_array):
- if isinstance(input_array[0], YTQuantity):
+ if isinstance(input_array[0], YTArray):
return YTArray(np.array(input_array, dtype=dtype),
input_array[0].units)
https://bitbucket.org/yt_analysis/yt/commits/c8b9fe149c7b/
Changeset: c8b9fe149c7b
Branch: yt-3.0
User: ngoldbaum
Date: 2014-05-27 09:40:12
Summary: Simplifying logic. Adding a short-circuit for ndarray.
Affected #: 1 file
diff -r 3ea4944887cfaa0bc427a8635455fe609c653043 -r c8b9fe149c7bc84e775ba87192481bd2951b9411 yt/units/yt_array.py
--- a/yt/units/yt_array.py
+++ b/yt/units/yt_array.py
@@ -118,16 +118,17 @@
def comparison_unit(unit1, unit2):
return None
+NULL_UNIT = (Unit(), )
+
def coerce_iterable_units(input_object):
- if isinstance(input_object, YTArray):
+ if isinstance(input_object, np.ndarray):
return input_object
if iterable(input_object):
- # This will create a copy of the data in the iterable.
- if all([isinstance(o, YTArray) for o in input_object]):
- ff = input_object[0].units
- if any([not ff.same_dimensions_as(getattr(_, 'units', Unit()))
- for _ in input_object]):
+ if any([isinstance(o, YTArray) for o in input_object]):
+ ff = getattr(input_object[0], 'units', NULL_UNIT, )
+ if any([ff != getattr(_, 'units', NULL_UNIT) for _ in input_object]):
raise YTIterableUnitCoercionError(input_object)
+ # This will create a copy of the data in the iterable.
return YTArray(input_object)
return input_object
else:
https://bitbucket.org/yt_analysis/yt/commits/8d1f7cd39264/
Changeset: 8d1f7cd39264
Branch: yt-3.0
User: ngoldbaum
Date: 2014-05-27 19:32:56
Summary: Fixing an indexing issue.
Affected #: 1 file
diff -r c8b9fe149c7bc84e775ba87192481bd2951b9411 -r 8d1f7cd39264352b41543de89eda0bd05dd19ec4 yt/units/yt_array.py
--- a/yt/units/yt_array.py
+++ b/yt/units/yt_array.py
@@ -118,7 +118,7 @@
def comparison_unit(unit1, unit2):
return None
-NULL_UNIT = (Unit(), )
+NULL_UNIT = Unit()
def coerce_iterable_units(input_object):
if isinstance(input_object, np.ndarray):
https://bitbucket.org/yt_analysis/yt/commits/f1fa8e20ab51/
Changeset: f1fa8e20ab51
Branch: yt-3.0
User: jzuhone
Date: 2014-05-29 18:47:13
Summary: Merged in ngoldbaum/yt/yt-3.0 (pull request #926)
Improved compatibility for YTArray operations that include iterables.
Affected #: 3 files
diff -r 3cfb38afe34da0d502ee9ddfb303426dfe9e053e -r f1fa8e20ab513e87f18447c48c299cbee5fdfd39 yt/units/tests/test_ytarray.py
--- a/yt/units/tests/test_ytarray.py
+++ b/yt/units/tests/test_ytarray.py
@@ -36,7 +36,8 @@
YTUnitOperationError, YTUfuncUnitError
from yt.testing import fake_random_pf, requires_module
from yt.funcs import fix_length
-
+from yt.units.unit_symbols import \
+ cm, m, g
def operate_and_compare(a, b, op, answer):
# Test generator for YTArrays tests
@@ -56,32 +57,46 @@
# Same units
a1 = YTArray([1, 2, 3], 'cm')
a2 = YTArray([4, 5, 6], 'cm')
+ a3 = [4*cm, 5*cm, 6*cm]
answer = YTArray([5, 7, 9], 'cm')
yield operate_and_compare, a1, a2, operator.add, answer
yield operate_and_compare, a2, a1, operator.add, answer
+ yield operate_and_compare, a1, a3, operator.add, answer
+ yield operate_and_compare, a3, a1, operator.add, answer
+ yield operate_and_compare, a2, a1, np.add, answer
yield operate_and_compare, a1, a2, np.add, answer
- yield operate_and_compare, a2, a1, np.add, answer
+ yield operate_and_compare, a1, a3, np.add, answer
+ yield operate_and_compare, a3, a1, np.add, answer
# different units
a1 = YTArray([1, 2, 3], 'cm')
a2 = YTArray([4, 5, 6], 'm')
+ a3 = [4*m, 5*m, 6*m]
answer1 = YTArray([401, 502, 603], 'cm')
answer2 = YTArray([4.01, 5.02, 6.03], 'm')
yield operate_and_compare, a1, a2, operator.add, answer1
yield operate_and_compare, a2, a1, operator.add, answer2
+ yield operate_and_compare, a1, a3, operator.add, answer1
+ yield operate_and_compare, a3, a1, operator.add, answer1
yield assert_raises, YTUfuncUnitError, np.add, a1, a2
+ yield assert_raises, YTUfuncUnitError, np.add, a1, a3
# Test dimensionless quantities
a1 = YTArray([1, 2, 3])
a2 = array([4, 5, 6])
+ a3 = [4, 5, 6]
answer = YTArray([5, 7, 9])
yield operate_and_compare, a1, a2, operator.add, answer
yield operate_and_compare, a2, a1, operator.add, answer
+ yield operate_and_compare, a1, a3, operator.add, answer
+ yield operate_and_compare, a3, a1, operator.add, answer
yield operate_and_compare, a1, a2, np.add, answer
yield operate_and_compare, a2, a1, np.add, answer
+ yield operate_and_compare, a1, a3, np.add, answer
+ yield operate_and_compare, a3, a1, np.add, answer
# Catch the different dimensions error
a1 = YTArray([1, 2, 3], 'm')
@@ -100,34 +115,49 @@
# Same units
a1 = YTArray([1, 2, 3], 'cm')
a2 = YTArray([4, 5, 6], 'cm')
+ a3 = [4*cm, 5*cm, 6*cm]
answer1 = YTArray([-3, -3, -3], 'cm')
answer2 = YTArray([3, 3, 3], 'cm')
yield operate_and_compare, a1, a2, operator.sub, answer1
yield operate_and_compare, a2, a1, operator.sub, answer2
+ yield operate_and_compare, a1, a3, operator.sub, answer1
+ yield operate_and_compare, a3, a1, operator.sub, answer2
yield operate_and_compare, a1, a2, np.subtract, answer1
yield operate_and_compare, a2, a1, np.subtract, answer2
+ yield operate_and_compare, a1, a3, np.subtract, answer1
+ yield operate_and_compare, a3, a1, np.subtract, answer2
# different units
a1 = YTArray([1, 2, 3], 'cm')
a2 = YTArray([4, 5, 6], 'm')
+ a3 = [4*m, 5*m, 6*m]
answer1 = YTArray([-399, -498, -597], 'cm')
answer2 = YTArray([3.99, 4.98, 5.97], 'm')
+ answer3 = YTArray([399, 498, 597], 'cm')
yield operate_and_compare, a1, a2, operator.sub, answer1
yield operate_and_compare, a2, a1, operator.sub, answer2
+ yield operate_and_compare, a1, a3, operator.sub, answer1
+ yield operate_and_compare, a3, a1, operator.sub, answer3
yield assert_raises, YTUfuncUnitError, np.subtract, a1, a2
+ yield assert_raises, YTUfuncUnitError, np.subtract, a1, a3
# Test dimensionless quantities
a1 = YTArray([1, 2, 3])
a2 = array([4, 5, 6])
+ a3 = [4, 5, 6]
answer1 = YTArray([-3, -3, -3])
answer2 = YTArray([3, 3, 3])
yield operate_and_compare, a1, a2, operator.sub, answer1
yield operate_and_compare, a2, a1, operator.sub, answer2
+ yield operate_and_compare, a1, a3, operator.sub, answer1
+ yield operate_and_compare, a3, a1, operator.sub, answer2
yield operate_and_compare, a1, a2, np.subtract, answer1
yield operate_and_compare, a2, a1, np.subtract, answer2
+ yield operate_and_compare, a1, a3, np.subtract, answer1
+ yield operate_and_compare, a3, a1, np.subtract, answer2
# Catch the different dimensions error
a1 = YTArray([1, 2, 3], 'm')
@@ -146,54 +176,79 @@
# Same units
a1 = YTArray([1, 2, 3], 'cm')
a2 = YTArray([4, 5, 6], 'cm')
+ a3 = [4*cm, 5*cm, 6*cm]
answer = YTArray([4, 10, 18], 'cm**2')
yield operate_and_compare, a1, a2, operator.mul, answer
yield operate_and_compare, a2, a1, operator.mul, answer
+ yield operate_and_compare, a1, a3, operator.mul, answer
+ yield operate_and_compare, a3, a1, operator.mul, answer
yield operate_and_compare, a1, a2, np.multiply, answer
yield operate_and_compare, a2, a1, np.multiply, answer
+ yield operate_and_compare, a1, a3, np.multiply, answer
+ yield operate_and_compare, a3, a1, np.multiply, answer
# different units, same dimension
a1 = YTArray([1, 2, 3], 'cm')
a2 = YTArray([4, 5, 6], 'm')
+ a3 = [4*m, 5*m, 6*m]
answer1 = YTArray([400, 1000, 1800], 'cm**2')
answer2 = YTArray([.04, .10, .18], 'm**2')
answer3 = YTArray([4, 10, 18], 'cm*m')
yield operate_and_compare, a1, a2, operator.mul, answer1
yield operate_and_compare, a2, a1, operator.mul, answer2
+ yield operate_and_compare, a1, a3, operator.mul, answer1
+ yield operate_and_compare, a3, a1, operator.mul, answer2
yield operate_and_compare, a1, a2, np.multiply, answer3
yield operate_and_compare, a2, a1, np.multiply, answer3
+ yield operate_and_compare, a1, a3, np.multiply, answer3
+ yield operate_and_compare, a3, a1, np.multiply, answer3
# different dimensions
a1 = YTArray([1, 2, 3], 'cm')
a2 = YTArray([4, 5, 6], 'g')
+ a3 = [4*g, 5*g, 6*g]
answer = YTArray([4, 10, 18], 'cm*g')
yield operate_and_compare, a1, a2, operator.mul, answer
yield operate_and_compare, a2, a1, operator.mul, answer
+ yield operate_and_compare, a1, a3, operator.mul, answer
+ yield operate_and_compare, a3, a1, operator.mul, answer
yield operate_and_compare, a1, a2, np.multiply, answer
yield operate_and_compare, a2, a1, np.multiply, answer
+ yield operate_and_compare, a1, a3, np.multiply, answer
+ yield operate_and_compare, a3, a1, np.multiply, answer
# One dimensionless, one unitful
a1 = YTArray([1, 2, 3], 'cm')
a2 = array([4, 5, 6])
+ a3 = [4, 5, 6]
answer = YTArray([4, 10, 18], 'cm')
yield operate_and_compare, a1, a2, operator.mul, answer
yield operate_and_compare, a2, a1, operator.mul, answer
+ yield operate_and_compare, a1, a3, operator.mul, answer
+ yield operate_and_compare, a3, a1, operator.mul, answer
yield operate_and_compare, a1, a2, np.multiply, answer
yield operate_and_compare, a2, a1, np.multiply, answer
+ yield operate_and_compare, a1, a3, np.multiply, answer
+ yield operate_and_compare, a3, a1, np.multiply, answer
# Both dimensionless quantities
a1 = YTArray([1, 2, 3])
a2 = array([4, 5, 6])
+ a3 = [4, 5, 6]
answer = YTArray([4, 10, 18])
yield operate_and_compare, a1, a2, operator.mul, answer
yield operate_and_compare, a2, a1, operator.mul, answer
+ yield operate_and_compare, a1, a3, operator.mul, answer
+ yield operate_and_compare, a3, a1, operator.mul, answer
yield operate_and_compare, a1, a2, np.multiply, answer
yield operate_and_compare, a2, a1, np.multiply, answer
+ yield operate_and_compare, a1, a3, np.multiply, answer
+ yield operate_and_compare, a3, a1, np.multiply, answer
def test_division():
@@ -205,17 +260,23 @@
# Same units
a1 = YTArray([1., 2., 3.], 'cm')
a2 = YTArray([4., 5., 6.], 'cm')
+ a3 = [4*cm, 5*cm, 6*cm]
answer1 = YTArray([0.25, 0.4, 0.5])
answer2 = YTArray([4, 2.5, 2])
yield operate_and_compare, a1, a2, operator.div, answer1
yield operate_and_compare, a2, a1, operator.div, answer2
+ yield operate_and_compare, a1, a3, operator.div, answer1
+ yield operate_and_compare, a3, a1, operator.div, answer2
yield operate_and_compare, a1, a2, np.divide, answer1
yield operate_and_compare, a2, a1, np.divide, answer2
+ yield operate_and_compare, a1, a3, np.divide, answer1
+ yield operate_and_compare, a3, a1, np.divide, answer2
# different units, same dimension
a1 = YTArray([1., 2., 3.], 'cm')
a2 = YTArray([4., 5., 6.], 'm')
+ a3 = [4*m, 5*m, 6*m]
answer1 = YTArray([.0025, .004, .005])
answer2 = YTArray([400, 250, 200])
answer3 = YTArray([0.25, 0.4, 0.5], 'cm/m')
@@ -223,41 +284,60 @@
yield operate_and_compare, a1, a2, operator.div, answer1
yield operate_and_compare, a2, a1, operator.div, answer2
+ yield operate_and_compare, a1, a3, operator.div, answer1
+ yield operate_and_compare, a3, a1, operator.div, answer2
yield operate_and_compare, a1, a2, np.divide, answer3
yield operate_and_compare, a2, a1, np.divide, answer4
+ yield operate_and_compare, a1, a3, np.divide, answer3
+ yield operate_and_compare, a3, a1, np.divide, answer4
# different dimensions
a1 = YTArray([1., 2., 3.], 'cm')
a2 = YTArray([4., 5., 6.], 'g')
+ a3 = [4*g, 5*g, 6*g]
answer1 = YTArray([0.25, 0.4, 0.5], 'cm/g')
answer2 = YTArray([4, 2.5, 2], 'g/cm')
yield operate_and_compare, a1, a2, operator.div, answer1
yield operate_and_compare, a2, a1, operator.div, answer2
+ yield operate_and_compare, a1, a3, operator.div, answer1
+ yield operate_and_compare, a3, a1, operator.div, answer2
yield operate_and_compare, a1, a2, np.divide, answer1
yield operate_and_compare, a2, a1, np.divide, answer2
+ yield operate_and_compare, a1, a3, np.divide, answer1
+ yield operate_and_compare, a3, a1, np.divide, answer2
# One dimensionless, one unitful
a1 = YTArray([1., 2., 3.], 'cm')
a2 = array([4., 5., 6.])
+ a3 = [4, 5, 6]
answer1 = YTArray([0.25, 0.4, 0.5], 'cm')
answer2 = YTArray([4, 2.5, 2], '1/cm')
yield operate_and_compare, a1, a2, operator.div, answer1
yield operate_and_compare, a2, a1, operator.div, answer2
+ yield operate_and_compare, a1, a3, operator.div, answer1
+ yield operate_and_compare, a3, a1, operator.div, answer2
yield operate_and_compare, a1, a2, np.divide, answer1
yield operate_and_compare, a2, a1, np.divide, answer2
+ yield operate_and_compare, a1, a3, np.divide, answer1
+ yield operate_and_compare, a3, a1, np.divide, answer2
# Both dimensionless quantities
a1 = YTArray([1., 2., 3.])
a2 = array([4., 5., 6.])
+ a3 = [4, 5, 6]
answer1 = YTArray([0.25, 0.4, 0.5])
answer2 = YTArray([4, 2.5, 2])
yield operate_and_compare, a1, a2, operator.div, answer1
yield operate_and_compare, a2, a1, operator.div, answer2
- yield operate_and_compare, a1, a2, np.divide, answer1
- yield operate_and_compare, a2, a1, np.divide, answer2
+ yield operate_and_compare, a1, a3, operator.div, answer1
+ yield operate_and_compare, a3, a1, operator.div, answer2
+ yield operate_and_compare, a1, a3, np.divide, answer1
+ yield operate_and_compare, a3, a1, np.divide, answer2
+ yield operate_and_compare, a1, a3, np.divide, answer1
+ yield operate_and_compare, a3, a1, np.divide, answer2
def test_power():
@@ -662,7 +742,7 @@
yt_arr2 = YTArray.from_astropy(ap_arr)
ap_quan = 10.*_astropy.units.Msun**0.5/(_astropy.units.kpc**3)
- yt_quan = YTQuantity(10.,"sqrt(Msun)/kpc**3")
+ yt_quan = YTQuantity(10., "sqrt(Msun)/kpc**3")
yt_quan2 = YTQuantity.from_astropy(ap_quan)
yield assert_array_equal, ap_arr, yt_arr.to_astropy()
@@ -687,6 +767,7 @@
nu = YTASubclass([10, 11, 12], '')
nda = np.array([3, 4, 5])
yta = YTArray([6, 7, 8], 'mg')
+ loq = [YTQuantity(6, 'mg'), YTQuantity(7, 'mg'), YTQuantity(8, 'mg')]
ytq = YTQuantity(4, 'cm')
ndf = np.float64(3)
@@ -695,7 +776,7 @@
assert_isinstance(op(inst2, inst1), compare_class)
for op in (operator.mul, operator.div, operator.truediv):
- for inst in (b, ytq, ndf, yta, nda):
+ for inst in (b, ytq, ndf, yta, nda, loq):
yield op_comparison, op, a, inst, YTASubclass
yield op_comparison, op, ytq, nda, YTArray
@@ -705,6 +786,7 @@
yield op_comparison, op, nu, nda, YTASubclass
yield op_comparison, op, a, b, YTASubclass
yield op_comparison, op, a, yta, YTASubclass
+ yield op_comparison, op, a, loq, YTASubclass
yield assert_isinstance, a[0], YTQuantity
yield assert_isinstance, a[:], YTASubclass
diff -r 3cfb38afe34da0d502ee9ddfb303426dfe9e053e -r f1fa8e20ab513e87f18447c48c299cbee5fdfd39 yt/units/yt_array.py
--- a/yt/units/yt_array.py
+++ b/yt/units/yt_array.py
@@ -33,7 +33,7 @@
from yt.units.dimensions import dimensionless
from yt.utilities.exceptions import \
YTUnitOperationError, YTUnitConversionError, \
- YTUfuncUnitError
+ YTUfuncUnitError, YTIterableUnitCoercionError
from numbers import Number as numeric_type
from yt.utilities.on_demand_imports import _astropy
from sympy import Rational
@@ -118,31 +118,47 @@
def comparison_unit(unit1, unit2):
return None
+NULL_UNIT = Unit()
+
+def coerce_iterable_units(input_object):
+ if isinstance(input_object, np.ndarray):
+ return input_object
+ if iterable(input_object):
+ if any([isinstance(o, YTArray) for o in input_object]):
+ ff = getattr(input_object[0], 'units', NULL_UNIT, )
+ if any([ff != getattr(_, 'units', NULL_UNIT) for _ in input_object]):
+ raise YTIterableUnitCoercionError(input_object)
+ # This will create a copy of the data in the iterable.
+ return YTArray(input_object)
+ return input_object
+ else:
+ return input_object
+
def sanitize_units_mul(this_object, other_object):
- ret = other_object
+ inp = coerce_iterable_units(this_object)
+ ret = coerce_iterable_units(other_object)
# If the other object is a YTArray and has the same dimensions as the object
# under consideration, convert so we don't mix units with the same
# dimensions.
- if isinstance(other_object, YTArray):
- if this_object.units.same_dimensions_as(other_object.units):
- ret = other_object.in_units(this_object.units)
+ if isinstance(ret, YTArray):
+ if inp.units.same_dimensions_as(ret.units):
+ ret.in_units(inp.units)
return ret
def sanitize_units_add(this_object, other_object, op_string):
+ inp = coerce_iterable_units(this_object)
+ ret = coerce_iterable_units(other_object)
# Make sure the other object is a YTArray before we use the `units`
# attribute.
- if isinstance(other_object, YTArray):
- if not this_object.units.same_dimensions_as(other_object.units):
- raise YTUnitOperationError(op_string, this_object.units,
- other_object.units)
- ret = other_object.in_units(this_object.units)
+ if isinstance(ret, YTArray):
+ if not inp.units.same_dimensions_as(ret.units):
+ raise YTUnitOperationError(op_string, inp.units, ret.units)
+ ret = ret.in_units(inp.units)
# If the other object is not a YTArray, the only valid case is adding
# dimensionless things.
else:
- if not this_object.units.is_dimensionless:
- raise YTUnitOperationError(op_string, this_object.units,
- dimensionless)
- ret = other_object
+ if not inp.units.is_dimensionless:
+ raise YTUnitOperationError(op_string, inp.units, dimensionless)
return ret
unary_operators = (
@@ -269,7 +285,7 @@
elif isinstance(input_array, np.ndarray):
pass
elif iterable(input_array):
- if isinstance(input_array[0], YTQuantity):
+ if isinstance(input_array[0], YTArray):
return YTArray(np.array(input_array, dtype=dtype),
input_array[0].units)
@@ -903,17 +919,19 @@
raise YTUnitOperationError(context[0], u)
ret_class = type(self)
elif context[0] in binary_operators:
- unit1 = getattr(context[1][0], 'units', None)
- unit2 = getattr(context[1][1], 'units', None)
- cls1 = type(context[1][0])
- cls2 = type(context[1][1])
+ oper1 = coerce_iterable_units(context[1][0])
+ oper2 = coerce_iterable_units(context[1][1])
+ cls1 = type(oper1)
+ cls2 = type(oper2)
+ unit1 = getattr(oper1, 'units', None)
+ unit2 = getattr(oper2, 'units', None)
ret_class = get_binary_op_return_class(cls1, cls2)
if unit1 is None:
unit1 = Unit(registry=getattr(unit2, 'registry', None))
if unit2 is None and context[0] is not power:
unit2 = Unit(registry=getattr(unit1, 'registry', None))
elif context[0] is power:
- unit2 = context[1][1]
+ unit2 = oper2
if isinstance(unit2, np.ndarray):
if isinstance(unit2, YTArray):
if unit2.units.is_dimensionless:
@@ -1029,9 +1047,9 @@
def get_binary_op_return_class(cls1, cls2):
if cls1 is cls2:
return cls1
- if cls1 is np.ndarray or issubclass(cls1, (numeric_type, np.number)):
+ if cls1 is np.ndarray or issubclass(cls1, (numeric_type, np.number, list, tuple)):
return cls2
- if cls2 is np.ndarray or issubclass(cls2, (numeric_type, np.number)):
+ if cls2 is np.ndarray or issubclass(cls2, (numeric_type, np.number, list, tuple)):
return cls1
if issubclass(cls1, YTQuantity):
return cls2
@@ -1042,5 +1060,5 @@
if issubclass(cls2, cls1):
return cls2
else:
- raise RuntimeError("Operations are only defined on pairs of objects"
- "in which one is a subclass of the other")
+ raise RuntimeError("Undefined operation for a YTArray subclass. "
+ "Received operand types (%s) and (%s)" % (cls1, cls2))
diff -r 3cfb38afe34da0d502ee9ddfb303426dfe9e053e -r f1fa8e20ab513e87f18447c48c299cbee5fdfd39 yt/utilities/exceptions.py
--- a/yt/utilities/exceptions.py
+++ b/yt/utilities/exceptions.py
@@ -193,9 +193,18 @@
def __str__(self):
err = "The NumPy %s operation is only allowed on objects with " \
- "identical units. Convert one of the arrays to the other\'s " \
- "units first. Received units (%s) and (%s)." % \
- (self.ufunc, self.unit1, self.unit2)
+ "identical units. Convert one of the arrays to the other\'s " \
+ "units first. Received units (%s) and (%s)." % \
+ (self.ufunc, self.unit1, self.unit2)
+ return err
+
+class YTIterableUnitCoercionError(YTException):
+ def __init__(self, quantity_list):
+ self.quantity_list = quantity_list
+
+ def __str__(self):
+ err = "Received a list or tuple of quantities with nonuniform units: " \
+ "%s" % self.quantity_list
return err
class YTHubRegisterError(YTException):
Repository URL: https://bitbucket.org/yt_analysis/yt/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
More information about the yt-svn
mailing list