Commit 4941cc7d authored by Justin MacCallum's avatar Justin MacCallum
Browse files

Removed trailing whitespace

parent 3862202e
...@@ -15,7 +15,7 @@ Portions copyright (c) 2012 Stanford University and the Authors. ...@@ -15,7 +15,7 @@ Portions copyright (c) 2012 Stanford University and the Authors.
Authors: Christopher M. Bruns Authors: Christopher M. Bruns
Contributors: Peter Eastman Contributors: Peter Eastman
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense, the rights to use, copy, modify, merge, publish, distribute, sublicense,
...@@ -40,14 +40,14 @@ __version__ = "0.6" ...@@ -40,14 +40,14 @@ __version__ = "0.6"
class BaseUnit(object): class BaseUnit(object):
''' '''
Physical unit expressed in exactly one BaseDimension. Physical unit expressed in exactly one BaseDimension.
For example, meter_base_unit could be a BaseUnit for the length dimension. For example, meter_base_unit could be a BaseUnit for the length dimension.
The BaseUnit class is used internally in the more general Unit class. The BaseUnit class is used internally in the more general Unit class.
''' '''
def __init__(self, base_dim, name, symbol): def __init__(self, base_dim, name, symbol):
"""Creates a new BaseUnit. """Creates a new BaseUnit.
Parameters Parameters
- self: The newly created BaseUnit. - self: The newly created BaseUnit.
- base_dim: (BaseDimension) The dimension of the new unit, e.g. 'mass' - base_dim: (BaseDimension) The dimension of the new unit, e.g. 'mass'
...@@ -62,7 +62,7 @@ class BaseUnit(object): ...@@ -62,7 +62,7 @@ class BaseUnit(object):
self._conversion_factor_to[self] = 1.0 self._conversion_factor_to[self] = 1.0
self._conversion_factor_to_by_name = {} self._conversion_factor_to_by_name = {}
self._conversion_factor_to_by_name[self.name] = 1.0 self._conversion_factor_to_by_name[self.name] = 1.0
def __lt__(self, other): def __lt__(self, other):
""" """
Comparison function that sorts BaseUnits by BaseDimension Comparison function that sorts BaseUnits by BaseDimension
...@@ -78,10 +78,10 @@ class BaseUnit(object): ...@@ -78,10 +78,10 @@ class BaseUnit(object):
Returns a dictionary of BaseDimension:exponent pairs, describing the dimension of this unit. Returns a dictionary of BaseDimension:exponent pairs, describing the dimension of this unit.
""" """
yield (self.dimension, 1) yield (self.dimension, 1)
def iter_base_units(self): def iter_base_units(self):
yield (self, 1) yield (self, 1)
def get_dimension_tuple(self): def get_dimension_tuple(self):
""" """
Returns a sorted tuple of (BaseDimension, exponent) pairs, that can be used as a dictionary key. Returns a sorted tuple of (BaseDimension, exponent) pairs, that can be used as a dictionary key.
...@@ -89,7 +89,7 @@ class BaseUnit(object): ...@@ -89,7 +89,7 @@ class BaseUnit(object):
l = list(self.iter_base_dimensions()) l = list(self.iter_base_dimensions())
l.sort() l.sort()
return tuple(l) return tuple(l)
def __str__(self): def __str__(self):
"""Returns a string with the name of this BaseUnit """Returns a string with the name of this BaseUnit
""" """
...@@ -97,40 +97,40 @@ class BaseUnit(object): ...@@ -97,40 +97,40 @@ class BaseUnit(object):
def __repr__(self): def __repr__(self):
return 'BaseUnit(base_dim=%s, name="%s", symbol="%s")' % (self.dimension, self.name, self.symbol) return 'BaseUnit(base_dim=%s, name="%s", symbol="%s")' % (self.dimension, self.name, self.symbol)
def define_conversion_factor_to(self, other, factor): def define_conversion_factor_to(self, other, factor):
""" """
Defines a conversion factor between two BaseUnits. Defines a conversion factor between two BaseUnits.
self * factor = other self * factor = other
Parameters: Parameters:
- self: (BaseUnit) 'From' unit in conversion. - self: (BaseUnit) 'From' unit in conversion.
- other: (BaseUnit) 'To' unit in conversion. - other: (BaseUnit) 'To' unit in conversion.
- factor: (float) Conversion factor. - factor: (float) Conversion factor.
After calling this method, both self and other will have stored After calling this method, both self and other will have stored
conversion factors for one another, plus all other BaseUnits which conversion factors for one another, plus all other BaseUnits which
self and other have previously defined. self and other have previously defined.
Both self and other must have the same dimension, otherwise a TypeError Both self and other must have the same dimension, otherwise a TypeError
will be raised. will be raised.
Returns None. Returns None.
""" """
if self.dimension != other.dimension: if self.dimension != other.dimension:
raise TypeError('Cannot define conversion for BaseUnits with different dimensions.') raise TypeError('Cannot define conversion for BaseUnits with different dimensions.')
assert(factor != 0) assert(factor != 0)
assert(not self is other) assert(not self is other)
# import all transitive conversions # import all transitive conversions
self._conversion_factor_to[other] = factor self._conversion_factor_to[other] = factor
self._conversion_factor_to_by_name[other.name] = factor self._conversion_factor_to_by_name[other.name] = factor
for (unit, cfac) in other._conversion_factor_to.items(): for (unit, cfac) in other._conversion_factor_to.items():
if unit is self: continue if unit is self: continue
if self._conversion_factor_to.has_key(unit): continue if self._conversion_factor_to.has_key(unit): continue
self._conversion_factor_to[unit] = factor * cfac self._conversion_factor_to[unit] = factor * cfac
unit._conversion_factor_to[self] = pow(factor * cfac, -1) unit._conversion_factor_to[self] = pow(factor * cfac, -1)
self._conversion_factor_to_by_name[unit.name] = factor * cfac self._conversion_factor_to_by_name[unit.name] = factor * cfac
unit._conversion_factor_to_by_name[self.name] = pow(factor * cfac, -1) unit._conversion_factor_to_by_name[self.name] = pow(factor * cfac, -1)
# and for the other guy # and for the other guy
invFac = pow(factor, -1.0) invFac = pow(factor, -1.0)
...@@ -146,13 +146,13 @@ class BaseUnit(object): ...@@ -146,13 +146,13 @@ class BaseUnit(object):
def conversion_factor_to(self, other): def conversion_factor_to(self, other):
"""Returns a conversion factor from this BaseUnit to another BaseUnit. """Returns a conversion factor from this BaseUnit to another BaseUnit.
It does not matter which existing BaseUnit you define the conversion factor to. It does not matter which existing BaseUnit you define the conversion factor to.
Conversions for all other known BaseUnits will be computed at the same time. Conversions for all other known BaseUnits will be computed at the same time.
Raises TypeError if dimension does not match. Raises TypeError if dimension does not match.
Raises LookupError if no conversion has been defined. (see define_conversion_factor_to). Raises LookupError if no conversion has been defined. (see define_conversion_factor_to).
""" """
if self is other: return 1.0 if self is other: return 1.0
if self.dimension != other.dimension: if self.dimension != other.dimension:
......
...@@ -11,7 +11,7 @@ Portions copyright (c) 2012 Stanford University and the Authors. ...@@ -11,7 +11,7 @@ Portions copyright (c) 2012 Stanford University and the Authors.
Authors: Christopher M. Bruns Authors: Christopher M. Bruns
Contributors: Peter Eastman Contributors: Peter Eastman
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense, the rights to use, copy, modify, merge, publish, distribute, sublicense,
......
...@@ -17,7 +17,7 @@ Examples ...@@ -17,7 +17,7 @@ Examples
>>> furlong_base_unit.define_conversion_factor_to(meter_base_unit, 201.16800) >>> furlong_base_unit.define_conversion_factor_to(meter_base_unit, 201.16800)
>>> furlong_base_unit.conversion_factor_to(angstrom_base_unit) >>> furlong_base_unit.conversion_factor_to(angstrom_base_unit)
2011680000000.0 2011680000000.0
Examples Examples
>>> furlong_base_unit = BaseUnit(length_dimension, "furlong", "fur") >>> furlong_base_unit = BaseUnit(length_dimension, "furlong", "fur")
...@@ -32,7 +32,7 @@ from unit.is_unit ...@@ -32,7 +32,7 @@ from unit.is_unit
True True
>>> is_unit(5*meter) >>> is_unit(5*meter)
False False
>>> c = 1.0*calories >>> c = 1.0*calories
>>> c >>> c
Quantity(value=1.0, unit=calorie) Quantity(value=1.0, unit=calorie)
...@@ -166,7 +166,7 @@ Examples ...@@ -166,7 +166,7 @@ Examples
>>> meter.is_compatible(centimeter) >>> meter.is_compatible(centimeter)
True True
>>> meter.is_compatible(meter) >>> meter.is_compatible(meter)
True True
>>> meter.is_compatible(kelvin) >>> meter.is_compatible(kelvin)
False False
...@@ -261,20 +261,20 @@ Collections of numbers can also be used as values. ...@@ -261,20 +261,20 @@ Collections of numbers can also be used as values.
Numpy examples are commented out because not all systems have numpy installed Numpy examples are commented out because not all systems have numpy installed
# >>> import numpy # >>> import numpy
# >>> # >>>
# >>> a = Quantity(numpy.array([1,2,3]), centimeters) # >>> a = Quantity(numpy.array([1,2,3]), centimeters)
# >>> print(a) # >>> print(a)
# [1 2 3] cm # [1 2 3] cm
# >>> print(a / millimeters) # >>> print(a / millimeters)
# [ 10. 20. 30.] # [ 10. 20. 30.]
# >>> # >>>
# >>> a2 = Quantity(numpy.array([[1,2,3],[4,5,6]]), centimeters) # >>> a2 = Quantity(numpy.array([[1,2,3],[4,5,6]]), centimeters)
# >>> print(a2) # >>> print(a2)
# [[1 2 3] # [[1 2 3]
# [4 5 6]] cm # [4 5 6]] cm
# >>> print(a2 / millimeters) # >>> print(a2 / millimeters)
# [[ 10. 20. 30.] # [[ 10. 20. 30.]
# [ 40. 50. 60.]] # [ 40. 50. 60.]]
Addition, subtraction, multiplication, division, and powers of Quantities Addition, subtraction, multiplication, division, and powers of Quantities
exhibit correct dimensional analysis and unit conversion. exhibit correct dimensional analysis and unit conversion.
...@@ -293,12 +293,12 @@ The following examples are derived from the C++ Boost.Units examples at ...@@ -293,12 +293,12 @@ The following examples are derived from the C++ Boost.Units examples at
http://www.boost.org/doc/libs/1_37_0/doc/html/boost_units/Examples.html http://www.boost.org/doc/libs/1_37_0/doc/html/boost_units/Examples.html
>>> >>>
>>> l = 2.0 * meters >>> l = 2.0 * meters
>>> >>>
>>> print(l + 2.0 * nanometers) >>> print(l + 2.0 * nanometers)
2.000000002 m 2.000000002 m
>>> print(2.0 * nanometers + l) >>> print(2.0 * nanometers + l)
2000000002.0 nm 2000000002.0 nm
>>> >>>
>>> print(l) >>> print(l)
2.0 m 2.0 m
>>> print(l+l) >>> print(l+l)
...@@ -410,25 +410,25 @@ True ...@@ -410,25 +410,25 @@ True
False False
>>> print(l1 > l2) >>> print(l1 > l2)
False False
>>> >>>
>>> def work(f, dx): >>> def work(f, dx):
... return f * dx ... return f * dx
... ...
>>> F = 1.0 * kilogram * meter / second**2 >>> F = 1.0 * kilogram * meter / second**2
>>> dx = 1.0 * meter >>> dx = 1.0 * meter
>>> E = work(F, dx) >>> E = work(F, dx)
>>> >>>
>>> print("F = ", F) >>> print("F = ", F)
F = 1.0 kg m/(s**2) F = 1.0 kg m/(s**2)
>>> print("dx = ", dx) >>> print("dx = ", dx)
dx = 1.0 m dx = 1.0 m
>>> >>>
>>> def idealGasLaw(P, V, T): >>> def idealGasLaw(P, V, T):
... R = MOLAR_GAS_CONSTANT_R ... R = MOLAR_GAS_CONSTANT_R
... print("P * V = ", P * V) ... print("P * V = ", P * V)
... print("R * T = ", R * T) ... print("R * T = ", R * T)
... return (P * V / (R * T)).in_units_of(mole) ... return (P * V / (R * T)).in_units_of(mole)
... ...
>>> T = (273.0 + 37.0) * kelvin >>> T = (273.0 + 37.0) * kelvin
>>> P = 1.01325e5 * pascals >>> P = 1.01325e5 * pascals
>>> r = 0.5e-6 * meters >>> r = 0.5e-6 * meters
...@@ -437,7 +437,7 @@ dx = 1.0 m ...@@ -437,7 +437,7 @@ dx = 1.0 m
P * V = 5.3053601125e-14 m**3 Pa P * V = 5.3053601125e-14 m**3 Pa
R * T = 2577.48646608 J/mol R * T = 2577.48646608 J/mol
>>> R = MOLAR_GAS_CONSTANT_R >>> R = MOLAR_GAS_CONSTANT_R
>>> >>>
>>> print("r = ", r) >>> print("r = ", r)
r = 5e-07 m r = 5e-07 m
>>> print("P = ", P) >>> print("P = ", P)
...@@ -460,7 +460,7 @@ is_quantity(V) = True ...@@ -460,7 +460,7 @@ is_quantity(V) = True
57.2957795131 deg 57.2957795131 deg
>>> print((1.0*angstroms).in_units_of(nanometers)) >>> print((1.0*angstroms).in_units_of(nanometers))
0.1 nm 0.1 nm
>>> >>>
>>> print((90*degrees)/radians) >>> print((90*degrees)/radians)
1.57079632679 1.57079632679
>>> print(sin(90*degrees)) >>> print(sin(90*degrees))
...@@ -475,7 +475,7 @@ True ...@@ -475,7 +475,7 @@ True
Traceback (most recent call last): Traceback (most recent call last):
... ...
TypeError: Unit "degree" is not compatible with Unit "nanometer". TypeError: Unit "degree" is not compatible with Unit "nanometer".
>>> >>>
>>> x = 1.5 * nanometers >>> x = 1.5 * nanometers
>>> print(x / meters) >>> print(x / meters)
1.5e-09 1.5e-09
...@@ -503,7 +503,7 @@ Examples ...@@ -503,7 +503,7 @@ Examples
10.0 10.0
>>> print(x.value_in_unit_system(md_unit_system)) >>> print(x.value_in_unit_system(md_unit_system))
100000000.0 100000000.0
>>> >>>
>>> y = 20 * millimeters / millisecond**2 >>> y = 20 * millimeters / millisecond**2
>>> print(y.value_in_unit_system(si_unit_system)) >>> print(y.value_in_unit_system(si_unit_system))
20000.0 20000.0
...@@ -519,7 +519,7 @@ Examples ...@@ -519,7 +519,7 @@ Examples
Dimensionless quantities return their unmodified values. Dimensionless quantities return their unmodified values.
>>> Quantity(5, dimensionless).value_in_unit_system(md_unit_system) >>> Quantity(5, dimensionless).value_in_unit_system(md_unit_system)
5 5
Examples Examples
>>> x = 2.3*meters >>> x = 2.3*meters
...@@ -581,9 +581,9 @@ Examples ...@@ -581,9 +581,9 @@ Examples
>>> print(8.4 / x) >>> print(8.4 / x)
2.0 /cm 2.0 /cm
Examples Examples
>>> x = 4.3 * meters >>> x = 4.3 * meters
>>> print(x/centimeters) >>> print(x/centimeters)
430.0 430.0
...@@ -593,15 +593,15 @@ Examples ...@@ -593,15 +593,15 @@ Examples
>>> x/millimeter >>> x/millimeter
[10.0, 20.0, 30.0] [10.0, 20.0, 30.0]
Examples Examples
>>> x = 1.2*meters >>> x = 1.2*meters
>>> print(5*x) >>> print(5*x)
6.0 m 6.0 m
Examples Examples
>>> x = 1.2*meters >>> x = 1.2*meters
>>> y = 72*centimeters >>> y = 72*centimeters
>>> print(x*y) >>> print(x*y)
...@@ -620,42 +620,42 @@ Examples ...@@ -620,42 +620,42 @@ Examples
Quantity(value=2.0, unit=nanometer**2/(angstrom**2)) Quantity(value=2.0, unit=nanometer**2/(angstrom**2))
>>> "%.1f" % q.reduce_unit() >>> "%.1f" % q.reduce_unit()
'200.0' '200.0'
Examples Examples
>>> 1.2*meters < 72*centimeters >>> 1.2*meters < 72*centimeters
False False
>>> meter != None >>> meter != None
True True
>>> meter == None >>> meter == None
False False
Examples Examples
>>> print(1.2 * meters - 72 * centimeters) >>> print(1.2 * meters - 72 * centimeters)
0.48 m 0.48 m
Examples Examples
>>> print(1.2 * meters + 72 * centimeters) >>> print(1.2 * meters + 72 * centimeters)
1.92 m 1.92 m
Examples Examples
>>> print(repr(1.2*meter)) >>> print(repr(1.2*meter))
Quantity(value=1.2, unit=meter) Quantity(value=1.2, unit=meter)
Examples Examples
>>> print(5.0 * nanometers) >>> print(5.0 * nanometers)
5.0 nm 5.0 nm
Examples Examples
>>> Quantity(5.0, meters) >>> Quantity(5.0, meters)
Quantity(value=5.0, unit=meter) Quantity(value=5.0, unit=meter)
>>> Quantity([1*angstrom,2*nanometer,3*angstrom]) >>> Quantity([1*angstrom,2*nanometer,3*angstrom])
Quantity(value=[1, 20.0, 3], unit=angstrom) Quantity(value=[1, 20.0, 3], unit=angstrom)
>>> Quantity((1,2,3)) >>> Quantity((1,2,3))
...@@ -684,14 +684,14 @@ Examples ...@@ -684,14 +684,14 @@ Examples
>>> Quantity(value=5.0, unit=100.0*meters) >>> Quantity(value=5.0, unit=100.0*meters)
Quantity(value=500.0, unit=meter) Quantity(value=500.0, unit=meter)
Examples Examples
>>> x = 2.3*meters >>> x = 2.3*meters
>>> y = x.in_units_of(centimeters) >>> y = x.in_units_of(centimeters)
>>> print(y) >>> print(y)
230.0 cm 230.0 cm
>>> x = 2.3*meters >>> x = 2.3*meters
>>> print(x.in_units_of(centimeters)) >>> print(x.in_units_of(centimeters))
230.0 cm 230.0 cm
...@@ -699,9 +699,9 @@ Examples ...@@ -699,9 +699,9 @@ Examples
Traceback (most recent call last): Traceback (most recent call last):
... ...
TypeError: Unit "meter" is not compatible with Unit "second". TypeError: Unit "meter" is not compatible with Unit "second".
Examples Examples
>>> x = 100.0 * millimeter >>> x = 100.0 * millimeter
>>> print(x) >>> print(x)
100.0 mm 100.0 mm
...@@ -725,22 +725,22 @@ Examples ...@@ -725,22 +725,22 @@ Examples
>>> q = 1.0 * md_kilocalorie/mole/angstrom >>> q = 1.0 * md_kilocalorie/mole/angstrom
>>> print(q.in_units_of(md_kilojoule/mole/nanometer)) >>> print(q.in_units_of(md_kilojoule/mole/nanometer))
41.84 kJ/(nm mol) 41.84 kJ/(nm mol)
Examples Examples
>>> class Foo: >>> class Foo:
... def bar(self): ... def bar(self):
... print("bar") ... print("bar")
... ...
>>> x = Foo() >>> x = Foo()
>>> x.bar() >>> x.bar()
bar bar
>>> y = x * nanometers >>> y = x * nanometers
>>> y.bar() >>> y.bar()
bar bar
Examples Examples
>>> print(meters * centimeters) >>> print(meters * centimeters)
centimeter*meter centimeter*meter
>>> print(meters * meters) >>> print(meters * meters)
...@@ -748,43 +748,43 @@ Examples ...@@ -748,43 +748,43 @@ Examples
>>> print(meter * meter ) >>> print(meter * meter )
meter**2 meter**2
Examples Examples
>>> print(meter / 2) >>> print(meter / 2)
0.5 m 0.5 m
Examples Examples
>>> define_prefixed_units(kelvin_base_unit, sys.modules["__main__"]) >>> define_prefixed_units(kelvin_base_unit, sys.modules["__main__"])
>>> from __main__ import millikelvin >>> from __main__ import millikelvin
>>> print(5.0 * millikelvin) >>> print(5.0 * millikelvin)
5.0 mK 5.0 mK
Creating a new BaseUnit: Creating a new BaseUnit:
>>> ms = milli * second_base_unit >>> ms = milli * second_base_unit
>>> ms >>> ms
BaseUnit(base_dim=BaseDimension("time"), name="millisecond", symbol="ms") BaseUnit(base_dim=BaseDimension("time"), name="millisecond", symbol="ms")
>>> ms.conversion_factor_to(second_base_unit) >>> ms.conversion_factor_to(second_base_unit)
0.001 0.001
Creating a new ScaledUnit: Creating a new ScaledUnit:
>>> mC = milli * ScaledUnit(4.184, joule, "calorie", "cal") >>> mC = milli * ScaledUnit(4.184, joule, "calorie", "cal")
>>> mC >>> mC
ScaledUnit(factor=0.0041840000000000002, master=joule, name='millicalorie', symbol='mcal') ScaledUnit(factor=0.0041840000000000002, master=joule, name='millicalorie', symbol='mcal')
Creating a new Unit: Creating a new Unit:
>>> ms = milli * second >>> ms = milli * second
>>> ms >>> ms
Unit({BaseUnit(base_dim=BaseDimension("time"), name="millisecond", symbol="ms"): 1.0}) Unit({BaseUnit(base_dim=BaseDimension("time"), name="millisecond", symbol="ms"): 1.0})
Don't try a Quantity though: Don't try a Quantity though:
>>> ms = milli * (1.0 * second) >>> ms = milli * (1.0 * second)
Traceback (most recent call last): Traceback (most recent call last):
... ...
TypeError: Unit prefix "milli" can only be applied to a Unit, BaseUnit, or ScaledUnit. TypeError: Unit prefix "milli" can only be applied to a Unit, BaseUnit, or ScaledUnit.
Comparison of dimensionless quantities issue (fixed in svn 513) Comparison of dimensionless quantities issue (fixed in svn 513)
>>> x = Quantity(1.0, dimensionless) >>> x = Quantity(1.0, dimensionless)
>>> y = Quantity(1.0, dimensionless) >>> y = Quantity(1.0, dimensionless)
...@@ -839,7 +839,7 @@ Examples ...@@ -839,7 +839,7 @@ Examples
# April 2010, thanks to John Chodera for reporting # April 2010, thanks to John Chodera for reporting
>>> try: >>> try:
... import numpy ... import numpy
... x = Quantity(numpy.array([1.,2.]), nanometer) ... x = Quantity(numpy.array([1.,2.]), nanometer)
... y = Quantity(numpy.array([3.,4.]), picosecond) ... y = Quantity(numpy.array([3.,4.]), picosecond)
... assert str(x/y) == '[ 0.33333333 0.5 ] nm/ps' ... assert str(x/y) == '[ 0.33333333 0.5 ] nm/ps'
... except ImportError: ... except ImportError:
......
...@@ -10,7 +10,7 @@ Portions copyright (c) 2012 Stanford University and the Authors. ...@@ -10,7 +10,7 @@ Portions copyright (c) 2012 Stanford University and the Authors.
Authors: Christopher M. Bruns Authors: Christopher M. Bruns
Contributors: Peter Eastman Contributors: Peter Eastman
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense, the rights to use, copy, modify, merge, publish, distribute, sublicense,
...@@ -34,7 +34,7 @@ import sys ...@@ -34,7 +34,7 @@ import sys
def eye(size): def eye(size):
""" """
Returns identity matrix. Returns identity matrix.
>>> print(eye(3)) >>> print(eye(3))
[[1, 0, 0] [[1, 0, 0]
[0, 1, 0] [0, 1, 0]
...@@ -50,11 +50,11 @@ def eye(size): ...@@ -50,11 +50,11 @@ def eye(size):
r.append(0) r.append(0)
result.append(r) result.append(r)
return MyMatrix(result) return MyMatrix(result)
def zeros(m, n=None): def zeros(m, n=None):
""" """
Returns matrix of zeroes Returns matrix of zeroes
>>> print(zeros(3)) >>> print(zeros(3))
[[0, 0, 0] [[0, 0, 0]
[0, 0, 0] [0, 0, 0]
...@@ -82,7 +82,7 @@ class MyVector(object): ...@@ -82,7 +82,7 @@ class MyVector(object):
def __str__(self): def __str__(self):
return str(self.data) return str(self.data)
def __repr__(self): def __repr__(self):
return self.__class__.__name__ + "(" + repr(self.data) + ")" return self.__class__.__name__ + "(" + repr(self.data) + ")"
...@@ -91,20 +91,20 @@ class MyVector(object): ...@@ -91,20 +91,20 @@ class MyVector(object):
def __contains__(self, item): def __contains__(self, item):
return item in self.data return item in self.data
def __delitem__(self, key): def __delitem__(self, key):
del self.data[key] del self.data[key]
def __iter__(self): def __iter__(self):
for item in self.data: for item in self.data:
yield item yield item
def __len__(self): def __len__(self):
return len(self.data) return len(self.data)
def __setitem__(self, key, value): def __setitem__(self, key, value):
self.data[key] = value self.data[key] = value
def __rmul__(self, lhs): def __rmul__(self, lhs):
try: try:
len(lhs) len(lhs)
...@@ -119,7 +119,7 @@ class MyVector(object): ...@@ -119,7 +119,7 @@ class MyVector(object):
class MyMatrix(MyVector): class MyMatrix(MyVector):
""" """
Pure python linear algebra matrix for internal matrix inversion in UnitSystem. Pure python linear algebra matrix for internal matrix inversion in UnitSystem.
>>> m = MyMatrix([[1,0,],[0,1,]]) >>> m = MyMatrix([[1,0,],[0,1,]])
>>> print(m) >>> print(m)
[[1, 0] [[1, 0]
...@@ -158,7 +158,7 @@ class MyMatrix(MyVector): ...@@ -158,7 +158,7 @@ class MyMatrix(MyVector):
""" """
def numRows(self): def numRows(self):
return len(self.data) return len(self.data)
def numCols(self): def numCols(self):
if len(self.data) == 0: if len(self.data) == 0:
return 0 return 0
...@@ -179,13 +179,13 @@ class MyMatrix(MyVector): ...@@ -179,13 +179,13 @@ class MyMatrix(MyVector):
start_char = " " start_char = " "
result += "]" result += "]"
return result return result
def __repr__(self): def __repr__(self):
return 'MyMatrix(' + MyVector.__repr__(self) + ')' return 'MyMatrix(' + MyVector.__repr__(self) + ')'
def is_square(self): def is_square(self):
return self.numRows() == self.numCols() return self.numRows() == self.numCols()
def __iter__(self): def __iter__(self):
for item in self.data: for item in self.data:
yield MyVector(item) yield MyVector(item)
...@@ -206,7 +206,7 @@ class MyMatrix(MyVector): ...@@ -206,7 +206,7 @@ class MyMatrix(MyVector):
def __mul__(self, rhs): def __mul__(self, rhs):
""" """
Matrix multiplication. Matrix multiplication.
>>> a = MyMatrix([[1,2],[3,4]]) >>> a = MyMatrix([[1,2],[3,4]])
>>> b = MyMatrix([[5,6],[7,8]]) >>> b = MyMatrix([[5,6],[7,8]])
>>> print(a) >>> print(a)
...@@ -218,7 +218,7 @@ class MyMatrix(MyVector): ...@@ -218,7 +218,7 @@ class MyMatrix(MyVector):
>>> print(a*b) >>> print(a*b)
[[19, 22] [[19, 22]
[43, 50]] [43, 50]]
""" """
m = self.numRows() m = self.numRows()
n = len(rhs[0]) n = len(rhs[0])
...@@ -235,7 +235,7 @@ class MyMatrix(MyVector): ...@@ -235,7 +235,7 @@ class MyMatrix(MyVector):
def __add__(self, rhs): def __add__(self, rhs):
""" """
Matrix addition. Matrix addition.
>>> print(MyMatrix([[1, 2],[3, 4]]) + MyMatrix([[5, 6],[7, 8]])) >>> print(MyMatrix([[1, 2],[3, 4]]) + MyMatrix([[5, 6],[7, 8]]))
[[6, 8] [[6, 8]
[10, 12]] [10, 12]]
...@@ -253,7 +253,7 @@ class MyMatrix(MyVector): ...@@ -253,7 +253,7 @@ class MyMatrix(MyVector):
def __sub__(self, rhs): def __sub__(self, rhs):
""" """
Matrix subtraction. Matrix subtraction.
>>> print(MyMatrix([[1, 2],[3, 4]]) - MyMatrix([[5, 6],[7, 8]])) >>> print(MyMatrix([[1, 2],[3, 4]]) - MyMatrix([[5, 6],[7, 8]]))
[[-4, -4] [[-4, -4]
[-4, -4]] [-4, -4]]
...@@ -270,7 +270,7 @@ class MyMatrix(MyVector): ...@@ -270,7 +270,7 @@ class MyMatrix(MyVector):
def __pos__(self): def __pos__(self):
return self return self
def __neg__(self): def __neg__(self):
m = self.numRows() m = self.numRows()
n = self.numCols() n = self.numCols()
...@@ -384,7 +384,7 @@ class MyMatrix(MyVector): ...@@ -384,7 +384,7 @@ class MyMatrix(MyVector):
for k in range(0,n): for k in range(0,n):
temp = a[k][indxr[l]] temp = a[k][indxr[l]]
a[k][indxr[l]] = a[k][indxc[l]] a[k][indxr[l]] = a[k][indxc[l]]
a[k][indxc[l]] = temp a[k][indxc[l]] = temp
return a return a
def transpose(self): def transpose(self):
...@@ -395,13 +395,13 @@ class MyMatrixTranspose(MyMatrix): ...@@ -395,13 +395,13 @@ class MyMatrixTranspose(MyMatrix):
def transpose(self): def transpose(self):
return MyMatrix(self.data) return MyMatrix(self.data)
def numRows(self): def numRows(self):
if len(self.data) == 0: if len(self.data) == 0:
return 0 return 0
else: else:
return len(self.data[0]) return len(self.data[0])
def numCols(self): def numCols(self):
return len(self.data) return len(self.data)
...@@ -461,7 +461,7 @@ class MyMatrixTranspose(MyMatrix): ...@@ -461,7 +461,7 @@ class MyMatrixTranspose(MyMatrix):
# run module directly for testing # run module directly for testing
if __name__=='__main__': if __name__=='__main__':
# Test the examples in the docstrings # Test the examples in the docstrings
import doctest, sys import doctest, sys
doctest.testmod(sys.modules[__name__]) doctest.testmod(sys.modules[__name__])
...@@ -11,7 +11,7 @@ Portions copyright (c) 2012 Stanford University and the Authors. ...@@ -11,7 +11,7 @@ Portions copyright (c) 2012 Stanford University and the Authors.
Authors: Christopher M. Bruns Authors: Christopher M. Bruns
Contributors: Peter Eastman Contributors: Peter Eastman
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense, the rights to use, copy, modify, merge, publish, distribute, sublicense,
...@@ -44,14 +44,14 @@ import sys ...@@ -44,14 +44,14 @@ import sys
class SiPrefix(object): class SiPrefix(object):
""" """
Unit prefix that can be multiplied by a unit to yield a new unit. Unit prefix that can be multiplied by a unit to yield a new unit.
e.g. millimeter = milli*meter e.g. millimeter = milli*meter
""" """
def __init__(self, prefix, factor, symbol): def __init__(self, prefix, factor, symbol):
self.prefix = prefix self.prefix = prefix
self.factor = factor self.factor = factor
self.symbol = symbol self.symbol = symbol
def __mul__(self, unit): def __mul__(self, unit):
""" """
SiPrefix * BaseUnit yields new BaseUnit SiPrefix * BaseUnit yields new BaseUnit
...@@ -136,7 +136,7 @@ si_prefixes = ( yotto ...@@ -136,7 +136,7 @@ si_prefixes = ( yotto
def define_prefixed_units(base_unit, module = sys.modules[__name__]): def define_prefixed_units(base_unit, module = sys.modules[__name__]):
""" """
Create attributes for prefixed units derived from a particular BaseUnit, e.g. "kilometer" from "meter_base_unit" Create attributes for prefixed units derived from a particular BaseUnit, e.g. "kilometer" from "meter_base_unit"
Parameters Parameters
- base_unit (BaseUnit) existing base unit to use as a basis for prefixed units - base_unit (BaseUnit) existing base unit to use as a basis for prefixed units
- module (Module) module which will contain the new attributes. Defaults to simtk.unit module. - module (Module) module which will contain the new attributes. Defaults to simtk.unit module.
...@@ -146,7 +146,7 @@ def define_prefixed_units(base_unit, module = sys.modules[__name__]): ...@@ -146,7 +146,7 @@ def define_prefixed_units(base_unit, module = sys.modules[__name__]):
name = new_base_unit.name name = new_base_unit.name
new_unit = Unit({new_base_unit: 1.0}) new_unit = Unit({new_base_unit: 1.0})
# Create base_unit attribute, needed for creating UnitSystems # Create base_unit attribute, needed for creating UnitSystems
module.__dict__[name + '_base_unit'] = new_base_unit # e.g. "kilometer_base_unit" module.__dict__[name + '_base_unit'] = new_base_unit # e.g. "kilometer_base_unit"
# Create attribue in this module # Create attribue in this module
module.__dict__[name] = new_unit # e.g. "kilometer" module.__dict__[name] = new_unit # e.g. "kilometer"
# And plural version # And plural version
......
...@@ -10,7 +10,7 @@ In particular, there is no underlying set of 'canonical' base ...@@ -10,7 +10,7 @@ In particular, there is no underlying set of 'canonical' base
units, whereas in Scientific.Physics.PhysicalQuantities all units, whereas in Scientific.Physics.PhysicalQuantities all
units are secretly in terms of SI units. Also, it is easier units are secretly in terms of SI units. Also, it is easier
to add new fundamental dimensions to simtk.dimensions. You to add new fundamental dimensions to simtk.dimensions. You
might want to make new dimensions for, say, "currency" or might want to make new dimensions for, say, "currency" or
"information". "information".
Some features of this implementation: Some features of this implementation:
...@@ -23,15 +23,15 @@ Some features of this implementation: ...@@ -23,15 +23,15 @@ Some features of this implementation:
ones are predefined. ones are predefined.
* Conversion factors between units are applied transitively, so all * Conversion factors between units are applied transitively, so all
possible conversions are available. possible conversions are available.
* I want dimensioned Quantities that are compatible with numpy arrays, * I want dimensioned Quantities that are compatible with numpy arrays,
but do not necessarily require the python numpy package. In other but do not necessarily require the python numpy package. In other
words, Quantities can be based on either numpy arrays or on built in words, Quantities can be based on either numpy arrays or on built in
python types. python types.
* Units are NOT necessarily stored in terms of SI units internally. * Units are NOT necessarily stored in terms of SI units internally.
This is very important for me, because one important application This is very important for me, because one important application
area for us is at the molecular scale. Using SI units internally area for us is at the molecular scale. Using SI units internally
can lead to exponent overflow in commonly used molecular force can lead to exponent overflow in commonly used molecular force
calculations. Internally, all unit systems are equally fundamental calculations. Internally, all unit systems are equally fundamental
in SimTK. in SimTK.
Two possible enhancements that have not been implemented are Two possible enhancements that have not been implemented are
...@@ -49,7 +49,7 @@ Portions copyright (c) 2012 Stanford University and the Authors. ...@@ -49,7 +49,7 @@ Portions copyright (c) 2012 Stanford University and the Authors.
Authors: Christopher M. Bruns Authors: Christopher M. Bruns
Contributors: Peter Eastman Contributors: Peter Eastman
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense, the rights to use, copy, modify, merge, publish, distribute, sublicense,
...@@ -81,7 +81,7 @@ from unit import Unit, is_unit, dimensionless ...@@ -81,7 +81,7 @@ from unit import Unit, is_unit, dimensionless
class Quantity(object): class Quantity(object):
"""Physical quantity, such as 1.3 meters per second. """Physical quantity, such as 1.3 meters per second.
Quantities contain both a value, such as 1.3; and a unit, Quantities contain both a value, such as 1.3; and a unit,
such as 'meters per second'. such as 'meters per second'.
...@@ -92,7 +92,7 @@ class Quantity(object): ...@@ -92,7 +92,7 @@ class Quantity(object):
Note - unit conversions will cause tuples to be converted to lists Note - unit conversions will cause tuples to be converted to lists
4 - lists of tuples of numbers, lists of lists of ... etc. of numbers 4 - lists of tuples of numbers, lists of lists of ... etc. of numbers
5 - numpy.arrays 5 - numpy.arrays
Create numpy.arrays with units using the Quantity constructor, not the Create numpy.arrays with units using the Quantity constructor, not the
multiply operator. e.g. multiply operator. e.g.
...@@ -104,11 +104,11 @@ class Quantity(object): ...@@ -104,11 +104,11 @@ class Quantity(object):
because numpy.arrays already overload the multiply operator for EVERYTHING. because numpy.arrays already overload the multiply operator for EVERYTHING.
""" """
def __init__(self, value=None, unit=None): def __init__(self, value=None, unit=None):
""" """
Create a new Quantity from a value and a unit. Create a new Quantity from a value and a unit.
Parameters Parameters
- value: (any type, usually a number) Measure of this quantity - value: (any type, usually a number) Measure of this quantity
- unit: (Unit) the physical unit, e.g. simtk.unit.meters. - unit: (Unit) the physical unit, e.g. simtk.unit.meters.
...@@ -161,18 +161,18 @@ class Quantity(object): ...@@ -161,18 +161,18 @@ class Quantity(object):
else: else:
# Non-Quantity, non container # Non-Quantity, non container
# Wrap in a dimensionless Quantity # Wrap in a dimensionless Quantity
unit = dimensionless unit = dimensionless
# Accept simple scalar quantities as units # Accept simple scalar quantities as units
if is_quantity(unit): if is_quantity(unit):
value = value * unit._value value = value * unit._value
unit = unit.unit unit = unit.unit
# Use empty list for unspecified values # Use empty list for unspecified values
if value == None: if value == None:
value = [] value = []
self._value = value self._value = value
self.unit = unit self.unit = unit
def __getstate__(self): def __getstate__(self):
state = dict() state = dict()
state['_value'] = self._value state['_value'] = self._value
...@@ -204,33 +204,33 @@ class Quantity(object): ...@@ -204,33 +204,33 @@ class Quantity(object):
""" """
ret_val = getattr(self._value, attribute) ret_val = getattr(self._value, attribute)
return ret_val return ret_val
def __str__(self): def __str__(self):
"""Printable string version of this Quantity. """Printable string version of this Quantity.
Returns a string consisting of quantity number followed by unit abbreviation. Returns a string consisting of quantity number followed by unit abbreviation.
""" """
return str(self._value) + ' ' + str(self.unit.get_symbol()) return str(self._value) + ' ' + str(self.unit.get_symbol())
def __repr__(self): def __repr__(self):
""" """
""" """
return (Quantity.__name__ + '(value=' + repr(self._value) + ', unit=' + return (Quantity.__name__ + '(value=' + repr(self._value) + ', unit=' +
str(self.unit) + ')') str(self.unit) + ')')
def format(self, format_spec): def format(self, format_spec):
return format_spec % self._value + ' ' + str(self.unit.get_symbol()) return format_spec % self._value + ' ' + str(self.unit.get_symbol())
def __add__(self, other): def __add__(self, other):
"""Add two Quantities. """Add two Quantities.
Only Quantities with the same dimensions (e.g. length) Only Quantities with the same dimensions (e.g. length)
can be added. Raises TypeError otherwise. can be added. Raises TypeError otherwise.
Parameters Parameters
- self: left hand member of sum - self: left hand member of sum
- other: right hand member of sum - other: right hand member of sum
Returns a new Quantity that is the sum of the two arguments. Returns a new Quantity that is the sum of the two arguments.
""" """
# can only add using like units # can only add using like units
...@@ -242,14 +242,14 @@ class Quantity(object): ...@@ -242,14 +242,14 @@ class Quantity(object):
def __sub__(self, other): def __sub__(self, other):
"""Subtract two Quantities. """Subtract two Quantities.
Only Quantities with the same dimensions (e.g. length) Only Quantities with the same dimensions (e.g. length)
can be subtracted. Raises TypeError otherwise. can be subtracted. Raises TypeError otherwise.
Parameters Parameters
- self: left hand member (a) of a - b. - self: left hand member (a) of a - b.
- other: right hand member (b) of a - b. - other: right hand member (b) of a - b.
Returns a new Quantity that is the difference of the two arguments. Returns a new Quantity that is the difference of the two arguments.
""" """
if not self.unit.is_compatible(other.unit): if not self.unit.is_compatible(other.unit):
...@@ -257,7 +257,7 @@ class Quantity(object): ...@@ -257,7 +257,7 @@ class Quantity(object):
value = self._value - other.value_in_unit(self.unit) value = self._value - other.value_in_unit(self.unit)
unit = self.unit unit = self.unit
return Quantity(value, unit) return Quantity(value, unit)
def __eq__(self, other): def __eq__(self, other):
""" """
""" """
...@@ -266,7 +266,7 @@ class Quantity(object): ...@@ -266,7 +266,7 @@ class Quantity(object):
if not self.unit.is_compatible(other.unit): if not self.unit.is_compatible(other.unit):
return False return False
return self.value_in_unit(other.unit) == other._value return self.value_in_unit(other.unit) == other._value
def __ne__(self, other): def __ne__(self, other):
""" """
""" """
...@@ -274,21 +274,21 @@ class Quantity(object): ...@@ -274,21 +274,21 @@ class Quantity(object):
def __lt__(self, other): def __lt__(self, other):
"""Compares two quantities. """Compares two quantities.
Raises TypeError if the Quantities are of different dimension (e.g. length vs. mass) Raises TypeError if the Quantities are of different dimension (e.g. length vs. mass)
Returns True if self < other, False otherwise. Returns True if self < other, False otherwise.
""" """
return self._value < other.value_in_unit(self.unit) return self._value < other.value_in_unit(self.unit)
def __ge__(self, other): def __ge__(self, other):
return self._value >= (other.value_in_unit(self.unit)) return self._value >= (other.value_in_unit(self.unit))
def __gt__(self, other): def __gt__(self, other):
return self._value > (other.value_in_unit(self.unit)) return self._value > (other.value_in_unit(self.unit))
def __le__(self, other): def __le__(self, other):
return self._value <= (other.value_in_unit(self.unit)) return self._value <= (other.value_in_unit(self.unit))
def __lt__(self, other): def __lt__(self, other):
return self._value < (other.value_in_unit(self.unit)) return self._value < (other.value_in_unit(self.unit))
_reduce_cache = {} _reduce_cache = {}
...@@ -296,7 +296,7 @@ class Quantity(object): ...@@ -296,7 +296,7 @@ class Quantity(object):
""" """
Combine similar component units and scale, to form an Combine similar component units and scale, to form an
equal Quantity in simpler units. equal Quantity in simpler units.
Returns underlying value type if unit is dimensionless. Returns underlying value type if unit is dimensionless.
""" """
key = (self.unit, guide_unit) key = (self.unit, guide_unit)
...@@ -353,7 +353,7 @@ class Quantity(object): ...@@ -353,7 +353,7 @@ class Quantity(object):
def __mul__(self, other): def __mul__(self, other):
"""Multiply a quantity by another object """Multiply a quantity by another object
Returns a new Quantity that is the product of the self * other, Returns a new Quantity that is the product of the self * other,
unless the resulting unit is dimensionless, in which case the unless the resulting unit is dimensionless, in which case the
underlying value type is returned, instead of a Quantity. underlying value type is returned, instead of a Quantity.
...@@ -373,12 +373,12 @@ class Quantity(object): ...@@ -373,12 +373,12 @@ class Quantity(object):
else: else:
# print "quantity * scalar" # print "quantity * scalar"
return self._change_units_with_factor(self.unit, other, post_multiply=False) return self._change_units_with_factor(self.unit, other, post_multiply=False)
# value type might not be commutative for multiplication # value type might not be commutative for multiplication
def __rmul__(self, other): def __rmul__(self, other):
"""Multiply a scalar by a Quantity """Multiply a scalar by a Quantity
Returns a new Quantity with the same units as self, but with the value Returns a new Quantity with the same units as self, but with the value
multiplied by other. multiplied by other.
""" """
if is_unit(other): if is_unit(other):
...@@ -391,7 +391,7 @@ class Quantity(object): ...@@ -391,7 +391,7 @@ class Quantity(object):
# print "scalar * quantity" # print "scalar * quantity"
return self._change_units_with_factor(self.unit, other, post_multiply=True) return self._change_units_with_factor(self.unit, other, post_multiply=True)
# return Quantity(other * self._value, self.unit) # return Quantity(other * self._value, self.unit)
def __truediv__(self, other): def __truediv__(self, other):
"""Divide a Quantity by another object """Divide a Quantity by another object
...@@ -416,7 +416,7 @@ class Quantity(object): ...@@ -416,7 +416,7 @@ class Quantity(object):
def __rtruediv__(self, other): def __rtruediv__(self, other):
"""Divide a scalar by a quantity. """Divide a scalar by a quantity.
Returns a new Quantity. The resulting units are the inverse of the self argument units. Returns a new Quantity. The resulting units are the inverse of the self argument units.
""" """
if is_unit(other): if is_unit(other):
...@@ -433,17 +433,17 @@ class Quantity(object): ...@@ -433,17 +433,17 @@ class Quantity(object):
def __pow__(self, exponent): def __pow__(self, exponent):
"""Raise a Quantity to a power. """Raise a Quantity to a power.
Generally both the value and the unit of the Quantity are affected by this operation. Generally both the value and the unit of the Quantity are affected by this operation.
Returns a new Quantity equal to self**exponent. Returns a new Quantity equal to self**exponent.
""" """
return Quantity(pow(self._value, exponent), pow(self.unit, exponent)) return Quantity(pow(self._value, exponent), pow(self.unit, exponent))
def sqrt(self): def sqrt(self):
""" """
Returns square root of a Quantity. Returns square root of a Quantity.
Raises ArithmeticError if component exponents are not even. Raises ArithmeticError if component exponents are not even.
This behavior can be changed if you present a reasonable real life case to me. This behavior can be changed if you present a reasonable real life case to me.
""" """
...@@ -458,25 +458,25 @@ class Quantity(object): ...@@ -458,25 +458,25 @@ class Quantity(object):
def __abs__(self): def __abs__(self):
""" """
Return absolute value of a Quantity. Return absolute value of a Quantity.
The unit is unchanged. A negative value of self will result in a positive value The unit is unchanged. A negative value of self will result in a positive value
in the result. in the result.
""" """
return Quantity(abs(self._value), self.unit) return Quantity(abs(self._value), self.unit)
def __pos__(self): def __pos__(self):
""" """
Returns a reference to self. Returns a reference to self.
""" """
return Quantity(+(self._value), self.unit) return Quantity(+(self._value), self.unit)
def __neg__(self): def __neg__(self):
"""Negate a Quantity. """Negate a Quantity.
Returns a new Quantity with a different sign on the value. Returns a new Quantity with a different sign on the value.
""" """
return Quantity(-(self._value), self.unit) return Quantity(-(self._value), self.unit)
def __nonzero__(self): def __nonzero__(self):
"""Returns True if value underlying Quantity is zero, False otherwise. """Returns True if value underlying Quantity is zero, False otherwise.
""" """
...@@ -490,7 +490,7 @@ class Quantity(object): ...@@ -490,7 +490,7 @@ class Quantity(object):
return Quantity(int(self._value), self.unit) return Quantity(int(self._value), self.unit)
def __long__(self): def __long__(self):
return Quantity(int(self._value), self.unit) return Quantity(int(self._value), self.unit)
def value_in_unit(self, unit): def value_in_unit(self, unit):
""" """
Returns underlying value, in the specified units. Returns underlying value, in the specified units.
...@@ -510,7 +510,7 @@ class Quantity(object): ...@@ -510,7 +510,7 @@ class Quantity(object):
return result._value return result._value
else: else:
return result # dimensionless return result # dimensionless
def in_unit_system(self, system): def in_unit_system(self, system):
""" """
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.
...@@ -525,7 +525,7 @@ class Quantity(object): ...@@ -525,7 +525,7 @@ class Quantity(object):
If the units are the same as those in self, a reference to self is returned. If the units are the same as those in self, a reference to self is returned.
Raises a TypeError if the new unit is not compatible with the original unit. Raises a TypeError if the new unit is not compatible with the original unit.
The post_multiply argument is used in case the multiplication operation is not commutative. The post_multiply argument is used in case the multiplication operation is not commutative.
i.e. result = factor * value when post_multiply is False i.e. result = factor * value when post_multiply is False
and result = value * factor when post_multiply is True and result = value * factor when post_multiply is True
...@@ -534,7 +534,7 @@ class Quantity(object): ...@@ -534,7 +534,7 @@ class Quantity(object):
raise TypeError('Unit "%s" is not compatible with Unit "%s".' % (self.unit, other_unit)) raise TypeError('Unit "%s" is not compatible with Unit "%s".' % (self.unit, other_unit))
f = self.unit.conversion_factor_to(other_unit) f = self.unit.conversion_factor_to(other_unit)
return self._change_units_with_factor(other_unit, f) return self._change_units_with_factor(other_unit, f)
def _change_units_with_factor(self, new_unit, factor, post_multiply=True): def _change_units_with_factor(self, new_unit, factor, post_multiply=True):
# numpy arrays cannot be compared with 1.0, so just "try" # numpy arrays cannot be compared with 1.0, so just "try"
factor_is_identity = False factor_is_identity = False
...@@ -555,7 +555,7 @@ class Quantity(object): ...@@ -555,7 +555,7 @@ class Quantity(object):
if post_multiply: if post_multiply:
value = self._value * factor # works for number, numpy.array, or vec3, e.g. value = self._value * factor # works for number, numpy.array, or vec3, e.g.
else: else:
value = factor * self._value # works for number, numpy.array, or vec3, e.g. value = factor * self._value # works for number, numpy.array, or vec3, e.g.
result = Quantity(value, new_unit) result = Quantity(value, new_unit)
except TypeError: except TypeError:
# list * float fails with TypeError # list * float fails with TypeError
...@@ -614,7 +614,7 @@ class Quantity(object): ...@@ -614,7 +614,7 @@ class Quantity(object):
""" """
assert not is_quantity(self._value[key]) assert not is_quantity(self._value[key])
return Quantity(self._value[key], self.unit) return Quantity(self._value[key], self.unit)
def __setitem__(self, key, value): def __setitem__(self, key, value):
# Delegate slices to one-at-a time ___setitem___ # Delegate slices to one-at-a time ___setitem___
if isinstance(key, slice): # slice if isinstance(key, slice): # slice
...@@ -629,13 +629,13 @@ class Quantity(object): ...@@ -629,13 +629,13 @@ class Quantity(object):
raise TypeError('Unit "%s" is not compatible with Unit "%s".' % (self.unit, value.unit)) raise TypeError('Unit "%s" is not compatible with Unit "%s".' % (self.unit, value.unit))
self._value[key] = value / self.unit self._value[key] = value / self.unit
assert not is_quantity(self._value[key]) assert not is_quantity(self._value[key])
def __delitem__(self, key): def __delitem__(self, key):
del(self._value[key]) del(self._value[key])
def __contains__(self, item): def __contains__(self, item):
return self._value.__contains__(item.value_in_unit(self.unit)) return self._value.__contains__(item.value_in_unit(self.unit))
def __iter__(self): def __iter__(self):
for item in self._value: for item in self._value:
yield Quantity(item, self.unit) yield Quantity(item, self.unit)
......
...@@ -13,7 +13,7 @@ Portions copyright (c) 2012 Stanford University and the Authors. ...@@ -13,7 +13,7 @@ Portions copyright (c) 2012 Stanford University and the Authors.
Authors: Christopher M. Bruns Authors: Christopher M. Bruns
Contributors: Peter Eastman Contributors: Peter Eastman
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense, the rights to use, copy, modify, merge, publish, distribute, sublicense,
......
...@@ -13,7 +13,7 @@ Portions copyright (c) 2012 Stanford University and the Authors. ...@@ -13,7 +13,7 @@ Portions copyright (c) 2012 Stanford University and the Authors.
Authors: Christopher M. Bruns Authors: Christopher M. Bruns
Contributors: Peter Eastman Contributors: Peter Eastman
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense, the rights to use, copy, modify, merge, publish, distribute, sublicense,
...@@ -51,7 +51,7 @@ class Unit(object): ...@@ -51,7 +51,7 @@ class Unit(object):
""" """
def __init__(self, base_or_scaled_units): def __init__(self, base_or_scaled_units):
"""Create a new Unit. """Create a new Unit.
Parameters: Parameters:
- self (Unit) The newly created Unit. - self (Unit) The newly created Unit.
- base_or_scaled_units (dict) Keys are BaseUnits or ScaledUnits. Values are exponents (numbers). - base_or_scaled_units (dict) Keys are BaseUnits or ScaledUnits. Values are exponents (numbers).
...@@ -113,7 +113,7 @@ class Unit(object): ...@@ -113,7 +113,7 @@ class Unit(object):
new_base_unit.define_conversion_factor_to(parent_base_unit, true_scale) new_base_unit.define_conversion_factor_to(parent_base_unit, true_scale)
new_unit = Unit({new_base_unit: 1.0}) new_unit = Unit({new_base_unit: 1.0})
return new_unit return new_unit
def iter_base_dimensions(self): def iter_base_dimensions(self):
""" """
Yields (BaseDimension, exponent) tuples comprising this unit. Yields (BaseDimension, exponent) tuples comprising this unit.
...@@ -130,7 +130,7 @@ class Unit(object): ...@@ -130,7 +130,7 @@ class Unit(object):
""" """
Yields (BaseUnit, exponent) tuples comprising this unit, including those BaseUnits Yields (BaseUnit, exponent) tuples comprising this unit, including those BaseUnits
found within ScaledUnits. found within ScaledUnits.
There might be multiple BaseUnits with the same dimension. There might be multiple BaseUnits with the same dimension.
""" """
for dimension in sorted(self._all_base_units.iterkeys()): for dimension in sorted(self._all_base_units.iterkeys()):
...@@ -146,7 +146,7 @@ class Unit(object): ...@@ -146,7 +146,7 @@ class Unit(object):
for unit in sorted(self._top_base_units[dimension].iterkeys()): for unit in sorted(self._top_base_units[dimension].iterkeys()):
exponent = self._top_base_units[dimension][unit] exponent = self._top_base_units[dimension][unit]
yield (unit, exponent) yield (unit, exponent)
def iter_scaled_units(self): def iter_scaled_units(self):
for unit, exponent in self._scaled_units: for unit, exponent in self._scaled_units:
yield (unit, exponent) yield (unit, exponent)
...@@ -169,7 +169,7 @@ class Unit(object): ...@@ -169,7 +169,7 @@ class Unit(object):
# print scaled_unit.factor # print scaled_unit.factor
factor *= scaled_unit.factor ** exponent factor *= scaled_unit.factor ** exponent
return factor return factor
def __eq__(self, other): def __eq__(self, other):
if not is_unit(other): if not is_unit(other):
return False return False
...@@ -180,9 +180,9 @@ class Unit(object): ...@@ -180,9 +180,9 @@ class Unit(object):
def __lt__(self, other): def __lt__(self, other):
"""Compare two Units. """Compare two Units.
Raises a TypeError if the units have different dimensions. Raises a TypeError if the units have different dimensions.
Returns True if self < other, False otherwise. Returns True if self < other, False otherwise.
""" """
if not self.is_compatible(other): if not self.is_compatible(other):
...@@ -202,12 +202,12 @@ class Unit(object): ...@@ -202,12 +202,12 @@ class Unit(object):
# def __mul__(self, other): # def __mul__(self, other):
# See unit_operators.py for Unit.__mul__ operator # See unit_operators.py for Unit.__mul__ operator
def __truediv__(self, other): def __truediv__(self, other):
"""Divide a Unit by another object. """Divide a Unit by another object.
Returns a composite Unit if other is another Unit. Returns a composite Unit if other is another Unit.
Returns a Quantity otherwise. UNLESS other is a Quantity AND Returns a Quantity otherwise. UNLESS other is a Quantity AND
the resulting unit type is dimensionless, in which case the underlying the resulting unit type is dimensionless, in which case the underlying
value type of the Quantity is returned. value type of the Quantity is returned.
...@@ -223,7 +223,7 @@ class Unit(object): ...@@ -223,7 +223,7 @@ class Unit(object):
def __pow__(self, exponent): def __pow__(self, exponent):
"""Raise a Unit to a power. """Raise a Unit to a power.
Returns a new Unit with different exponents on the BaseUnits. Returns a new Unit with different exponents on the BaseUnits.
""" """
if self in Unit._pow_cache: if self in Unit._pow_cache:
...@@ -241,7 +241,7 @@ class Unit(object): ...@@ -241,7 +241,7 @@ class Unit(object):
def sqrt(self): def sqrt(self):
""" """
Returns square root of a unit. Returns square root of a unit.
Raises ArithmeticError if component exponents are not even. Raises ArithmeticError if component exponents are not even.
This behavior can be changed if you present a reasonable real life case to me. This behavior can be changed if you present a reasonable real life case to me.
""" """
...@@ -280,7 +280,7 @@ class Unit(object): ...@@ -280,7 +280,7 @@ class Unit(object):
def __str__(self): def __str__(self):
"""Returns the human-readable name of this unit""" """Returns the human-readable name of this unit"""
return self.get_name() return self.get_name()
def __repr__(self): def __repr__(self):
""" """
Returns a unit name (string) for this Unit, composed of its various Returns a unit name (string) for this Unit, composed of its various
...@@ -321,7 +321,7 @@ class Unit(object): ...@@ -321,7 +321,7 @@ class Unit(object):
Unit._is_compatible_cache[self] = {} Unit._is_compatible_cache[self] = {}
Unit._is_compatible_cache[self][other] = result Unit._is_compatible_cache[self][other] = result
return result return result
_is_dimensionless_cache = {} _is_dimensionless_cache = {}
def is_dimensionless(self): def is_dimensionless(self):
...@@ -336,7 +336,7 @@ class Unit(object): ...@@ -336,7 +336,7 @@ class Unit(object):
return False return False
Unit._is_dimensionless_cache[self] = True Unit._is_dimensionless_cache[self] = True
return True return True
# Performance # Performance
_conversion_factor_cache = {} _conversion_factor_cache = {}
...@@ -344,7 +344,7 @@ class Unit(object): ...@@ -344,7 +344,7 @@ class Unit(object):
""" """
Returns conversion factor for computing all of the common dimensions Returns conversion factor for computing all of the common dimensions
between self and other from self base units to other base units. between self and other from self base units to other base units.
The two units need not share all of the same dimensions. In case they The two units need not share all of the same dimensions. In case they
do not, the conversion factor applies only to the BaseUnits of self do not, the conversion factor applies only to the BaseUnits of self
that correspond to different BaseUnits in other. that correspond to different BaseUnits in other.
...@@ -352,7 +352,7 @@ class Unit(object): ...@@ -352,7 +352,7 @@ class Unit(object):
This method requires strict compatibility between the two units. This method requires strict compatibility between the two units.
""" """
factor = 1.0 factor = 1.0
if (self is other): if (self is other):
return factor return factor
if self in Unit._conversion_factor_cache: if self in Unit._conversion_factor_cache:
if other in Unit._conversion_factor_cache[self]: if other in Unit._conversion_factor_cache[self]:
...@@ -385,9 +385,9 @@ class Unit(object): ...@@ -385,9 +385,9 @@ class Unit(object):
def in_unit_system(self, system): def in_unit_system(self, system):
""" """
Returns a new Unit with the same dimensions as this one, expressed in a particular unit system. Returns a new Unit with the same dimensions as this one, expressed in a particular unit system.
Strips off any ScaledUnits in the Unit, leaving only BaseUnits. Strips off any ScaledUnits in the Unit, leaving only BaseUnits.
Parameters Parameters
- system: a dictionary of (BaseDimension, BaseUnit) pairs - system: a dictionary of (BaseDimension, BaseUnit) pairs
""" """
...@@ -402,7 +402,7 @@ class Unit(object): ...@@ -402,7 +402,7 @@ class Unit(object):
# emit positive exponents first # emit positive exponents first
pos = "" pos = ""
pos_count = 0 pos_count = 0
for unit, power in self.iter_base_or_scaled_units(): for unit, power in self.iter_base_or_scaled_units():
if power > 0: if power > 0:
pos_count += 1 pos_count += 1
if pos_count > 1: pos += " " if pos_count > 1: pos += " "
...@@ -413,7 +413,7 @@ class Unit(object): ...@@ -413,7 +413,7 @@ class Unit(object):
neg = "" neg = ""
neg_count = 0 neg_count = 0
simple_denominator = True simple_denominator = True
for unit, power in self.iter_base_or_scaled_units(): for unit, power in self.iter_base_or_scaled_units():
if power < 0: if power < 0:
neg_count += 1 neg_count += 1
if neg_count > 1: neg += " " if neg_count > 1: neg += " "
...@@ -421,7 +421,7 @@ class Unit(object): ...@@ -421,7 +421,7 @@ class Unit(object):
if power != -1.0: if power != -1.0:
neg += "**%g" % -power neg += "**%g" % -power
simple_denominator = False simple_denominator = False
# Format of denominator depends on number of terms # Format of denominator depends on number of terms
if 0 == neg_count: if 0 == neg_count:
neg_string = "" neg_string = ""
elif 1 == neg_count and simple_denominator: elif 1 == neg_count and simple_denominator:
...@@ -450,7 +450,7 @@ class Unit(object): ...@@ -450,7 +450,7 @@ class Unit(object):
# emit positive exponents first # emit positive exponents first
pos = "" pos = ""
pos_count = 0 pos_count = 0
for unit, power in self.iter_base_or_scaled_units(): for unit, power in self.iter_base_or_scaled_units():
if power > 0: if power > 0:
pos_count += 1 pos_count += 1
if pos_count > 1: pos += "*" if pos_count > 1: pos += "*"
...@@ -461,7 +461,7 @@ class Unit(object): ...@@ -461,7 +461,7 @@ class Unit(object):
neg = "" neg = ""
neg_count = 0 neg_count = 0
simple_denominator = True simple_denominator = True
for unit, power in self.iter_base_or_scaled_units(): for unit, power in self.iter_base_or_scaled_units():
if power < 0: if power < 0:
neg_count += 1 neg_count += 1
if neg_count > 1: neg += "*" if neg_count > 1: neg += "*"
...@@ -469,7 +469,7 @@ class Unit(object): ...@@ -469,7 +469,7 @@ class Unit(object):
if power != -1.0: if power != -1.0:
neg += "**%g" % -power neg += "**%g" % -power
simple_denominator = False simple_denominator = False
# Format of denominator depends on number of terms # Format of denominator depends on number of terms
if 0 == neg_count: if 0 == neg_count:
neg_string = "" neg_string = ""
elif 1 == neg_count and simple_denominator: elif 1 == neg_count and simple_denominator:
...@@ -491,7 +491,7 @@ class Unit(object): ...@@ -491,7 +491,7 @@ class Unit(object):
class ScaledUnit(object): class ScaledUnit(object):
""" """
ScaledUnit is like a BaseUnit, but it is based on another Unit. ScaledUnit is like a BaseUnit, but it is based on another Unit.
ScaledUnit and BaseUnit are both used in the internals of Unit. They ScaledUnit and BaseUnit are both used in the internals of Unit. They
should only be used during the construction of Units. should only be used during the construction of Units.
""" """
...@@ -536,10 +536,10 @@ class ScaledUnit(object): ...@@ -536,10 +536,10 @@ class ScaledUnit(object):
l = list(self.iter_base_dimensions()) l = list(self.iter_base_dimensions())
l.sort() l.sort()
return tuple(l) return tuple(l)
def get_conversion_factor_to_base_units(self): def get_conversion_factor_to_base_units(self):
return self.factor return self.factor
def conversion_factor_to(self, other): def conversion_factor_to(self, other):
# Create fake unit based on base units # Create fake unit based on base units
if self is other: if self is other:
...@@ -557,7 +557,7 @@ class ScaledUnit(object): ...@@ -557,7 +557,7 @@ class ScaledUnit(object):
"""Compare two ScaledUnits. """Compare two ScaledUnits.
""" """
return hash(self) < hash(other) return hash(self) < hash(other)
def __str__(self): def __str__(self):
"""Returns a string with the name of this ScaledUnit """Returns a string with the name of this ScaledUnit
""" """
...@@ -610,7 +610,7 @@ class UnitSystem(object): ...@@ -610,7 +610,7 @@ class UnitSystem(object):
# except ArithmeticError: # except ArithmeticError:
# e=sys.exc_info[1] # e=sys.exc_info[1]
raise ArithmeticError("UnitSystem is not a valid basis set. " + str(e)) raise ArithmeticError("UnitSystem is not a valid basis set. " + str(e))
def __iter__(self): def __iter__(self):
for unit in self.units: for unit in self.units:
yield unit yield unit
...@@ -667,14 +667,14 @@ class UnitSystem(object): ...@@ -667,14 +667,14 @@ class UnitSystem(object):
def is_unit(x): def is_unit(x):
""" """
Returns True if x is a Unit, False otherwise. Returns True if x is a Unit, False otherwise.
Examples Examples
>>> is_unit(16) >>> is_unit(16)
False False
""" """
return isinstance(x, Unit) return isinstance(x, Unit)
dimensionless = Unit({}) dimensionless = Unit({})
# run module directly for testing # run module directly for testing
......
...@@ -11,7 +11,7 @@ Portions copyright (c) 2012 Stanford University and the Authors. ...@@ -11,7 +11,7 @@ Portions copyright (c) 2012 Stanford University and the Authors.
Authors: Christopher M. Bruns Authors: Christopher M. Bruns
Contributors: Peter Eastman Contributors: Peter Eastman
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense, the rights to use, copy, modify, merge, publish, distribute, sublicense,
......
...@@ -13,7 +13,7 @@ Portions copyright (c) 2012 Stanford University and the Authors. ...@@ -13,7 +13,7 @@ Portions copyright (c) 2012 Stanford University and the Authors.
Authors: Christopher M. Bruns Authors: Christopher M. Bruns
Contributors: Peter Eastman Contributors: Peter Eastman
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense, the rights to use, copy, modify, merge, publish, distribute, sublicense,
...@@ -49,7 +49,7 @@ from unit_definitions import * ...@@ -49,7 +49,7 @@ from unit_definitions import *
def sin(angle): def sin(angle):
""" """
Examples Examples
>>> sin(90*degrees) >>> sin(90*degrees)
1.0 1.0
""" """
...@@ -67,7 +67,7 @@ def sinh(angle): ...@@ -67,7 +67,7 @@ def sinh(angle):
def cos(angle): def cos(angle):
""" """
Examples Examples
>>> cos(180*degrees) >>> cos(180*degrees)
-1.0 -1.0
""" """
...@@ -102,10 +102,10 @@ def acos(x): ...@@ -102,10 +102,10 @@ def acos(x):
0.0 rad 0.0 rad
""" """
return math.acos(x) * radians return math.acos(x) * radians
def acosh(x): def acosh(x):
return math.acosh(x) * radians return math.acosh(x) * radians
def asin(x): def asin(x):
return math.asin(x) * radians return math.asin(x) * radians
...@@ -114,10 +114,10 @@ def asinh(x): ...@@ -114,10 +114,10 @@ def asinh(x):
def atan(x): def atan(x):
return math.atan(x) * radians return math.atan(x) * radians
def atanh(x): def atanh(x):
return math.atanh(x) * radians return math.atanh(x) * radians
def atan2(x, y): def atan2(x, y):
return math.atan2(x, y) * radians return math.atan2(x, y) * radians
......
...@@ -10,7 +10,7 @@ In particular, there is no underlying set of 'canonical' base ...@@ -10,7 +10,7 @@ In particular, there is no underlying set of 'canonical' base
units, whereas in Scientific.Physics.PhysicalQuantities all units, whereas in Scientific.Physics.PhysicalQuantities all
units are secretly in terms of SI units. Also, it is easier units are secretly in terms of SI units. Also, it is easier
to add new fundamental dimensions to simtk.dimensions. You to add new fundamental dimensions to simtk.dimensions. You
might want to make new dimensions for, say, "currency" or might want to make new dimensions for, say, "currency" or
"information". "information".
Two possible enhancements that have not been implemented are Two possible enhancements that have not been implemented are
...@@ -28,7 +28,7 @@ Portions copyright (c) 2012 Stanford University and the Authors. ...@@ -28,7 +28,7 @@ Portions copyright (c) 2012 Stanford University and the Authors.
Authors: Christopher M. Bruns Authors: Christopher M. Bruns
Contributors: Peter Eastman Contributors: Peter Eastman
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense, the rights to use, copy, modify, merge, publish, distribute, sublicense,
...@@ -60,7 +60,7 @@ from quantity import Quantity, is_quantity ...@@ -60,7 +60,7 @@ from quantity import Quantity, is_quantity
def _unit_class_rdiv(self, other): def _unit_class_rdiv(self, other):
""" """
Divide another object type by a Unit. Divide another object type by a Unit.
Returns a new Quantity with a value of other and units Returns a new Quantity with a value of other and units
of the inverse of self. of the inverse of self.
""" """
...@@ -78,14 +78,14 @@ Unit.__rdiv__ = _unit_class_rdiv ...@@ -78,14 +78,14 @@ Unit.__rdiv__ = _unit_class_rdiv
def _unit_class_mul(self, other): def _unit_class_mul(self, other):
"""Multiply a Unit by an object. """Multiply a Unit by an object.
If other is another Unit, returns a new composite Unit. If other is another Unit, returns a new composite Unit.
Exponents of similar dimensions are added. If self and Exponents of similar dimensions are added. If self and
other share similar BaseDimension, but other share similar BaseDimension, but
with different BaseUnits, the resulting BaseUnit for that with different BaseUnits, the resulting BaseUnit for that
BaseDimension will be that used in self. BaseDimension will be that used in self.
If other is a not another Unit, this method returns a If other is a not another Unit, this method returns a
new Quantity... UNLESS other is a Quantity and the resulting new Quantity... UNLESS other is a Quantity and the resulting
unit is dimensionless, in which case the underlying value type unit is dimensionless, in which case the underlying value type
of the Quantity is returned. of the Quantity is returned.
...@@ -133,7 +133,7 @@ def _unit_class_mul(self, other): ...@@ -133,7 +133,7 @@ def _unit_class_mul(self, other):
# Is reduce_unit needed here? I hope not, there is a performance issue... # Is reduce_unit needed here? I hope not, there is a performance issue...
# return Quantity(other, self).reduce_unit(self) # return Quantity(other, self).reduce_unit(self)
return Quantity(other, self) return Quantity(other, self)
Unit.__mul__ = _unit_class_mul Unit.__mul__ = _unit_class_mul
Unit.__rmul__ = Unit.__mul__ Unit.__rmul__ = Unit.__mul__
Unit._multiplication_cache = {} Unit._multiplication_cache = {}
......
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