Commit c3c84a28 authored by Peter Eastman's avatar Peter Eastman
Browse files

Further optimizations to unit code

parent 47ab0a62
...@@ -475,7 +475,9 @@ class Quantity(object): ...@@ -475,7 +475,9 @@ class Quantity(object):
""" """
Returns a new Quantity equal to this one, expressed in a particular unit system. Returns a new Quantity equal to this one, expressed in a particular unit system.
""" """
return self.in_units_of(self.unit.in_unit_system(system)) new_units = system.express_unit(self.unit)
f = self.unit.conversion_factor_to(new_units)
return self._change_units_with_factor(new_units, f)
def in_units_of(self, other_unit): def in_units_of(self, other_unit):
""" """
......
...@@ -144,16 +144,22 @@ class Unit(object): ...@@ -144,16 +144,22 @@ class Unit(object):
def __eq__(self, other): def __eq__(self, other):
if not is_unit(other): if not is_unit(other):
return False return False
if not self.is_compatible(other): if self._all_base_units == other._all_base_units and self._scaled_units == other._scaled_units:
return True
if hash(self) != hash(other):
return False return False
return NotImplemented # punt to cmp() factor = 1.0
factor *= self.get_conversion_factor_to_base_units()
factor /= other.get_conversion_factor_to_base_units()
for (base1, exp1), (base2, exp2) in zip(self.iter_all_base_units(), other.iter_all_base_units()):
if base1.dimension != base2.dimension or exp1 != exp2:
return False
if base1 != base2:
factor *= base1.conversion_factor_to(base2)**exp1
return factor == 1.0
def __ne__(self, other): def __ne__(self, other):
if not is_unit(other): return not self.__eq__(other)
return True
if not self.is_compatible(other):
return True
return NotImplemented # punt to cmp()
def __cmp__(self, other): def __cmp__(self, other):
"""Compare two Units. """Compare two Units.
...@@ -167,6 +173,20 @@ class Unit(object): ...@@ -167,6 +173,20 @@ class Unit(object):
raise TypeError('Unit "%s" is not compatible with Unit "%s".', (self, other)) raise TypeError('Unit "%s" is not compatible with Unit "%s".', (self, other))
return cmp(self.conversion_factor_to(other), 1.0) return cmp(self.conversion_factor_to(other), 1.0)
def __hash__(self):
"""
Compute a hash code for this object.
"""
try:
return self._hash
except AttributeError:
pass
description = ""
for unit, power in self.iter_all_base_units():
description += unit.name + str(power)
self._hash = hash(description)
return self._hash
# def __mul__(self, other): # def __mul__(self, other):
# See unit_operators.py for Unit.__mul__ operator # See unit_operators.py for Unit.__mul__ operator
...@@ -576,9 +596,8 @@ class UnitSystem(object): ...@@ -576,9 +596,8 @@ class UnitSystem(object):
def express_unit(self, old_unit): def express_unit(self, old_unit):
""" """
""" """
unit_name = old_unit.get_name() if old_unit in self._unit_conversion_cache:
if unit_name in self._unit_conversion_cache: return self._unit_conversion_cache[old_unit]
return self._unit_conversion_cache[unit_name]
# First express unit in terms of base dimensions found in this unit system # First express unit in terms of base dimensions found in this unit system
# (plus other dimensions not found) # (plus other dimensions not found)
m = len(self.dimensions) m = len(self.dimensions)
...@@ -608,7 +627,7 @@ class UnitSystem(object): ...@@ -608,7 +627,7 @@ class UnitSystem(object):
found_dims[dim] = base_unit found_dims[dim] = base_unit
exponent = other_dims[dim] exponent = other_dims[dim]
new_unit *= Unit({base_unit: exponent}) new_unit *= Unit({base_unit: exponent})
self._unit_conversion_cache[unit_name] = new_unit self._unit_conversion_cache[old_unit] = new_unit
return new_unit return new_unit
def is_unit(x): def is_unit(x):
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment