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