Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
tsoc
openmm
Commits
1db8640d
Commit
1db8640d
authored
Mar 12, 2011
by
Peter Eastman
Browse files
Further optimizations to units code
parent
ee78f1e7
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
65 additions
and
51 deletions
+65
-51
wrappers/python/simtk/unit/quantity.py
wrappers/python/simtk/unit/quantity.py
+39
-32
wrappers/python/simtk/unit/unit.py
wrappers/python/simtk/unit/unit.py
+17
-18
wrappers/python/simtk/unit/unit_operators.py
wrappers/python/simtk/unit/unit_operators.py
+9
-1
No files found.
wrappers/python/simtk/unit/quantity.py
View file @
1db8640d
...
@@ -261,6 +261,8 @@ class Quantity(object):
...
@@ -261,6 +261,8 @@ class Quantity(object):
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
=
{}
def
reduce_unit
(
self
,
guide_unit
=
None
):
def
reduce_unit
(
self
,
guide_unit
=
None
):
"""
"""
Combine similar component units and scale, to form an
Combine similar component units and scale, to form an
...
@@ -268,41 +270,46 @@ class Quantity(object):
...
@@ -268,41 +270,46 @@ class Quantity(object):
Returns underlying value type if unit is dimensionless.
Returns underlying value type if unit is dimensionless.
"""
"""
value_factor
=
1.0
key
=
(
self
.
unit
,
guide_unit
)
canonical_units
=
{}
# dict of dimensionTuple: (Base/ScaledUnit, exponent)
if
key
in
Quantity
.
_reduce_cache
:
# Bias result toward guide units
(
unit
,
value_factor
)
=
Quantity
.
_reduce_cache
[
key
]
if
guide_unit
!=
None
:
else
:
for
u
,
exponent
in
guide_unit
.
iter_base_or_scaled_units
():
value_factor
=
1.0
canonical_units
=
{}
# dict of dimensionTuple: (Base/ScaledUnit, exponent)
# Bias result toward guide units
if
guide_unit
!=
None
:
for
u
,
exponent
in
guide_unit
.
iter_base_or_scaled_units
():
d
=
u
.
get_dimension_tuple
()
if
d
not
in
canonical_units
:
canonical_units
[
d
]
=
[
u
,
0
]
for
u
,
exponent
in
self
.
unit
.
iter_base_or_scaled_units
():
d
=
u
.
get_dimension_tuple
()
d
=
u
.
get_dimension_tuple
()
# Take first unit found in a dimension as canonical
if
d
not
in
canonical_units
:
if
d
not
in
canonical_units
:
canonical_units
[
d
]
=
[
u
,
0
]
canonical_units
[
d
]
=
[
u
,
exponent
]
for
u
,
exponent
in
self
.
unit
.
iter_base_or_scaled_units
():
else
:
d
=
u
.
get_dimension_tuple
()
value_factor
*=
(
u
.
conversion_factor_to
(
canonical_units
[
d
][
0
])
**
exponent
)
# Take first unit found in a dimension as canonical
canonical_units
[
d
][
1
]
+=
exponent
if
d
not
in
canonical_units
:
new_base_units
=
{}
canonical_units
[
d
]
=
[
u
,
exponent
]
for
d
in
canonical_units
:
u
,
exponent
=
canonical_units
[
d
]
if
exponent
!=
0
:
assert
u
not
in
new_base_units
new_base_units
[
u
]
=
exponent
# Create new unit
if
len
(
new_base_units
)
==
0
:
unit
=
dimensionless
else
:
else
:
value_factor
*=
(
u
.
conversion_factor_to
(
canonical_units
[
d
][
0
])
**
exponent
)
unit
=
Unit
(
new_base_units
)
canonical_units
[
d
][
1
]
+=
exponent
# There might be a factor due to unit conversion, even though unit is dimensionless
new_base_units
=
{}
# e.g. suppose unit is meter/centimeter
for
d
in
canonical_units
:
if
unit
.
is_dimensionless
():
u
,
exponent
=
canonical_units
[
d
]
unit_factor
=
unit
.
conversion_factor_to
(
dimensionless
)
if
exponent
!=
0
:
if
unit_factor
!=
1.0
:
assert
u
not
in
new_base_units
value_factor
*=
unit_factor
new_base_units
[
u
]
=
exponent
# print "value_factor = %s" % value_factor
# Create new unit
unit
=
dimensionless
if
len
(
new_base_units
)
==
0
:
Quantity
.
_reduce_cache
[
key
]
=
(
unit
,
value_factor
)
unit
=
dimensionless
else
:
unit
=
Unit
(
new_base_units
)
# There might be a factor due to unit conversion, even though unit is dimensionless
# e.g. suppose unit is meter/centimeter
if
unit
.
is_dimensionless
():
unit_factor
=
unit
.
conversion_factor_to
(
dimensionless
)
if
unit_factor
!=
1.0
:
value_factor
*=
unit_factor
# print "value_factor = %s" % value_factor
unit
=
dimensionless
# Create Quantity, then scale (in case value is a container)
# Create Quantity, then scale (in case value is a container)
# That's why we don't just scale the value.
# That's why we don't just scale the value.
result
=
Quantity
(
self
.
_value
,
unit
)
result
=
Quantity
(
self
.
_value
,
unit
)
...
...
wrappers/python/simtk/unit/unit.py
View file @
1db8640d
...
@@ -144,19 +144,7 @@ class Unit(object):
...
@@ -144,19 +144,7 @@ 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
self
.
_all_base_units
==
other
.
_all_base_units
and
self
.
_scaled_units
==
other
.
_scaled_units
:
return
self
.
get_name
()
==
other
.
get_name
()
return
True
if
hash
(
self
)
!=
hash
(
other
):
return
False
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
):
return
not
self
.
__eq__
(
other
)
return
not
self
.
__eq__
(
other
)
...
@@ -181,10 +169,7 @@ class Unit(object):
...
@@ -181,10 +169,7 @@ class Unit(object):
return
self
.
_hash
return
self
.
_hash
except
AttributeError
:
except
AttributeError
:
pass
pass
description
=
""
self
.
_hash
=
hash
(
self
.
get_name
())
for
unit
,
power
in
self
.
iter_all_base_units
():
description
+=
unit
.
name
+
str
(
power
)
self
.
_hash
=
hash
(
description
)
return
self
.
_hash
return
self
.
_hash
# def __mul__(self, other):
# def __mul__(self, other):
...
@@ -204,15 +189,24 @@ class Unit(object):
...
@@ -204,15 +189,24 @@ class Unit(object):
# def __rdiv__(self, other):
# def __rdiv__(self, other):
# Because rdiv returns a Quantity, look in quantity.py for definition of Unit.__rdiv__
# Because rdiv returns a Quantity, look in quantity.py for definition of Unit.__rdiv__
_pow_cache
=
{}
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
exponent
in
Unit
.
_pow_cache
[
self
]:
return
Unit
.
_pow_cache
[
self
][
exponent
]
else
:
Unit
.
_pow_cache
[
self
]
=
{}
result
=
{}
# dictionary of unit: exponent
result
=
{}
# dictionary of unit: exponent
for
unit
,
exponent2
in
self
.
iter_base_or_scaled_units
():
for
unit
,
exponent2
in
self
.
iter_base_or_scaled_units
():
result
[
unit
]
=
exponent2
*
exponent
result
[
unit
]
=
exponent2
*
exponent
return
Unit
(
result
)
new_unit
=
Unit
(
result
)
Unit
.
_pow_cache
[
self
][
exponent
]
=
new_unit
return
new_unit
def
sqrt
(
self
):
def
sqrt
(
self
):
"""
"""
...
@@ -419,6 +413,10 @@ class Unit(object):
...
@@ -419,6 +413,10 @@ class Unit(object):
Returns a unit name (string) for this Unit, composed of its various
Returns a unit name (string) for this Unit, composed of its various
BaseUnit symbols. e.g. 'kilogram meter**2 secon**-1'.
BaseUnit symbols. e.g. 'kilogram meter**2 secon**-1'.
"""
"""
try
:
return
self
.
_name
except
AttributeError
:
pass
# emit positive exponents first
# emit positive exponents first
pos
=
""
pos
=
""
pos_count
=
0
pos_count
=
0
...
@@ -456,6 +454,7 @@ class Unit(object):
...
@@ -456,6 +454,7 @@ class Unit(object):
name
=
"dimensionless"
name
=
"dimensionless"
else
:
else
:
name
=
"%s%s"
%
(
pos_string
,
neg_string
)
name
=
"%s%s"
%
(
pos_string
,
neg_string
)
self
.
_name
=
name
return
name
return
name
...
...
wrappers/python/simtk/unit/unit_operators.py
View file @
1db8640d
...
@@ -61,6 +61,11 @@ def _unit_class_mul(self, other):
...
@@ -61,6 +61,11 @@ def _unit_class_mul(self, other):
of the Quantity is returned.
of the Quantity is returned.
"""
"""
if
is_unit
(
other
):
if
is_unit
(
other
):
if
self
in
Unit
.
_multiplication_cache
:
if
other
in
Unit
.
_multiplication_cache
[
self
]:
return
Unit
.
_multiplication_cache
[
self
][
other
]
else
:
Unit
.
_multiplication_cache
[
self
]
=
{}
# print "unit * unit"
# print "unit * unit"
result1
=
{}
# dictionary of dimensionTuple: (BaseOrScaledUnit, exponent)
result1
=
{}
# dictionary of dimensionTuple: (BaseOrScaledUnit, exponent)
for
unit
,
exponent
in
self
.
iter_base_or_scaled_units
():
for
unit
,
exponent
in
self
.
iter_base_or_scaled_units
():
...
@@ -83,7 +88,9 @@ def _unit_class_mul(self, other):
...
@@ -83,7 +88,9 @@ def _unit_class_mul(self, other):
if
exponent
!=
0
:
if
exponent
!=
0
:
assert
unit
not
in
result2
assert
unit
not
in
result2
result2
[
unit
]
=
exponent
result2
[
unit
]
=
exponent
return
Unit
(
result2
)
new_unit
=
Unit
(
result2
)
Unit
.
_multiplication_cache
[
self
][
other
]
=
new_unit
return
new_unit
elif
is_quantity
(
other
):
elif
is_quantity
(
other
):
# print "unit * quantity"
# print "unit * quantity"
value
=
other
.
_value
value
=
other
.
_value
...
@@ -99,6 +106,7 @@ def _unit_class_mul(self, other):
...
@@ -99,6 +106,7 @@ def _unit_class_mul(self, other):
Unit
.
__mul__
=
_unit_class_mul
Unit
.
__mul__
=
_unit_class_mul
Unit
.
__rmul__
=
Unit
.
__mul__
Unit
.
__rmul__
=
Unit
.
__mul__
Unit
.
_multiplication_cache
=
{}
# run module directly for testing
# run module directly for testing
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment