understanding physics.units

482 views
Skip to first unread message

flyeng4

unread,
Apr 7, 2009, 4:18:16 PM4/7/09
to sympy
I am trying to understand physics.units. Here is an ipython session
illustrating my mental block

In [32]: from sympy.physics.units import *

In [33]: V/ohm
Out[33]: A <-- This makes sense.

In [34]: A*ohm
Out[34]: m**2*kg/(A*s**3) <-- Why not 'V'?

In [35]: V/A
Out[35]: m**2*kg/(A**2*s**3) <-- Why not 'ohm'?

In [36]: W/A
Out[36]: m**2*kg/(A*s**3) <-- Why not 'V'>

In [37]: V/ohm
Out[37]: A <-- Again this makes sense.

In [38]: W/V
Out[38]: A <-- This makes sense.

In [40]: 1/s
Out[40]: 1/s <-- Makes sense but might be 'hz'?

In [42]: sympy.__version__
Out[42]: '0.6.4.beta1'

Can someone explain this behavior and maybe shed some light on how I
could get this to work the way that I think it should?

Thanks,
Bill

Riccardo Gori

unread,
Apr 7, 2009, 6:56:51 PM4/7/09
to sy...@googlegroups.com
2009/4/7 flyeng4 <fly...@gmail.com>


Hello Bill,
I think it's because sympy uses the international system of units, look at:

http://en.wikipedia.org/wiki/SI#Units

Cheers,
Riccardo

Neal Becker

unread,
Apr 7, 2009, 8:16:49 PM4/7/09
to sy...@googlegroups.com

Umm, maybe I'm missing something here, but if V/Ohm -> A, then A*Ohm-> V.
What's that got to do with SI Units?

Fredrik Johansson

unread,
Apr 7, 2009, 8:32:11 PM4/7/09
to sy...@googlegroups.com
On Tue, Apr 7, 2009 at 10:18 PM, flyeng4 <fly...@gmail.com> wrote:
>
> I am trying to understand physics.units.  Here is an ipython session
> illustrating my mental block
>
> In [32]: from sympy.physics.units import *
>
> In [33]: V/ohm
> Out[33]: A         <-- This makes sense.
>
> In [34]: A*ohm
> Out[34]: m**2*kg/(A*s**3)  <-- Why not 'V'?

Because that is how V is defined:

>>> V
m**2*kg/(A*s**3)

All quantities in physics.units are defined in terms of SI base units
(http://en.wikipedia.org/wiki/SI_base_unit). The derived units (such
as V) are just composite expressions, not atomic symbols. This ensures
that expressions involving units always are in canonical form (with
the downside that this form is not always pretty), and thus SymPy's
generic symbolic algorithms can handle units without the need for any
special code.

The simplest workaround would be to recognize simpler forms for units
at the pretty-printing stage.

Fredrik

Fredrik Johansson

unread,
Apr 7, 2009, 8:35:49 PM4/7/09
to sy...@googlegroups.com
On Wed, Apr 8, 2009 at 2:32 AM, Fredrik Johansson
<fredrik....@gmail.com> wrote:

> All quantities in physics.units are defined in terms of SI base units
> (http://en.wikipedia.org/wiki/SI_base_unit). The derived units (such
> as V) are just composite expressions, not atomic symbols. This ensures
> that expressions involving units always are in canonical form (with
> the downside that this form is not always pretty), and thus SymPy's
> generic symbolic algorithms can handle units without the need for any
> special code.
>
> The simplest workaround would be to recognize simpler forms for units
> at the pretty-printing stage.

This is, by the way, similar to the fact that SymPy actually represents x/y
as x*(1/y), although it does pretty-print it as x/y.

Fredrik

Robert Kern

unread,
Apr 7, 2009, 8:44:01 PM4/7/09
to sy...@googlegroups.com
On Tue, Apr 7, 2009 at 15:18, flyeng4 <fly...@gmail.com> wrote:

> In [40]: 1/s
> Out[40]: 1/s <-- Makes sense but might be 'hz'?

You need to be careful with that. Hz specifically means "cycles per
second", which is not always the same thing as 1/s. In particular,
angular frequencies are also measured in 1/s (technically radians/s
but radians are a ratio of distances and so are "unitless" by the
usual logic), but they differ from Hz by a factor of 2*pi. Sadly,
units are not the most rigorous of mathematical constructs.

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless
enigma that is made terrible by our own mad attempt to interpret it as
though it had an underlying truth."
-- Umberto Eco

Fredrik Johansson

unread,
Apr 7, 2009, 9:28:25 PM4/7/09
to sy...@googlegroups.com
On Wed, Apr 8, 2009 at 2:44 AM, Robert Kern <rober...@gmail.com> wrote:
>
> On Tue, Apr 7, 2009 at 15:18, flyeng4 <fly...@gmail.com> wrote:
>
>> In [40]: 1/s
>> Out[40]: 1/s <-- Makes sense but might be 'hz'?
>
> You need to be careful with that. Hz specifically means "cycles per
> second", which is not always the same thing as 1/s. In particular,
> angular frequencies are also measured in 1/s (technically radians/s
> but radians are a ratio of distances and so are "unitless" by the
> usual logic), but they differ from Hz by a factor of 2*pi. Sadly,
> units are not the most rigorous of mathematical constructs.

I disagree, 1/s is the definition of the hertz, period (pun accidental :-).

Frequencies and angular frequencies differ by a factor 2*pi precisely
because they measure different things, so equating them is (usually)
an error, like equating meters and kilometers. The inability of
dimensional analysis to prevent such errors is a limit of scope, not
one of rigor.

Fredrik

Robert Kern

unread,
Apr 7, 2009, 9:35:48 PM4/7/09
to sy...@googlegroups.com
On Tue, Apr 7, 2009 at 20:28, Fredrik Johansson
<fredrik....@gmail.com> wrote:
>
> On Wed, Apr 8, 2009 at 2:44 AM, Robert Kern <rober...@gmail.com> wrote:
>>
>> On Tue, Apr 7, 2009 at 15:18, flyeng4 <fly...@gmail.com> wrote:
>>
>>> In [40]: 1/s
>>> Out[40]: 1/s <-- Makes sense but might be 'hz'?
>>
>> You need to be careful with that. Hz specifically means "cycles per
>> second", which is not always the same thing as 1/s. In particular,
>> angular frequencies are also measured in 1/s (technically radians/s
>> but radians are a ratio of distances and so are "unitless" by the
>> usual logic), but they differ from Hz by a factor of 2*pi. Sadly,
>> units are not the most rigorous of mathematical constructs.
>
> I disagree, 1/s is the definition of the hertz, period (pun accidental :-).

Sorry, but that's just not true. There are other 1/s quantities that
have nothing to do with cycles, like the becquerel:

http://www.unc.edu/~rowlett/units/siderive.html

> Frequencies and angular frequencies differ by a factor 2*pi precisely
> because they measure different things, so equating them is (usually)
> an error, like equating meters and kilometers. The inability of
> dimensional analysis to prevent such errors is a limit of scope, not
> one of rigor.

The lack of rigor is that we use the same units to describe different
quantities by silently dropping the "radians", "cycles", and
"disintegrations". I entirely agree with you that they measure
different things. We apply the same units to them regardless of that,
and that is the lack of rigor I refer to.

William Purcell

unread,
Apr 7, 2009, 10:30:48 PM4/7/09
to sy...@googlegroups.com
On Tue, Apr 7, 2009 at 7:32 PM, Fredrik Johansson <fredrik....@gmail.com> wrote:

The simplest workaround would be to recognize simpler forms for units
at the pretty-printing stage.

For my particular application I need a simpler 'pretty form'.  I am trying to do something similar to the way Mathcad handles units.  I do all my calculations at work with a python pre-parser to LaTeX that finds all the python code in a LaTeX document, executes it, and then tries to intellegently replace the code with an equation, figure, or whatever the block of code might represent.  It's pretty slick (and it keeps me from using Mathcad or Excel) except I need someway to attach units to my calculations for better documentation (i.e. I need to know if a moment on a beam I am sizing is in ft-lbs or N-m).   Do you have a suggestion on the best way to approach this?  A specific example, how could I get V from sympy.units.A*sympy.units.ohm if that is really what I wanted? 

In short, what would be the best way to recognize m**2*kg/(A*s**3) as V, and do you have any thoughts on a printer method to do this?

Ondrej Certik

unread,
Apr 7, 2009, 10:34:13 PM4/7/09
to sy...@googlegroups.com

I would try our matching functions, e.g. try to match:

m**a * kg**b * A**c * s**d

and then from a, b, c, d, determine what to substitute it for. If
something doesn't work, please report it and we'll fix it.

Ondrej

Fredrik Johansson

unread,
Apr 7, 2009, 11:18:46 PM4/7/09
to sy...@googlegroups.com
On Wed, Apr 8, 2009 at 3:35 AM, Robert Kern <rober...@gmail.com> wrote:
>> I disagree, 1/s is the definition of the hertz, period (pun accidental :-).
>
> Sorry, but that's just not true. There are other 1/s quantities that
> have nothing to do with cycles, like the becquerel:
>
>  http://www.unc.edu/~rowlett/units/siderive.html

I stand corrected; the SI standard does state the purpose of the
hertz. From http://physics.nist.gov/Pubs/SP330/sp330.pdf: "Although it
would be formally correct to write all three of these units as the
reciprocal second, the use of the different names emphasises the
different nature of
the quantities concerned." (I could make an argument out of the
"formally correct" part, but I'm not going to do pursue that...)

Anyway, my main disagreement was with "units are not the most rigorous
of mathematical constructs". As mathematical constructs, using only
their formal definitions, units are perfectly rigorous. It is the
interpretation of units that is sometimes nonrigorous (we seem to
agree on this).

Fredrik

Robert Kern

unread,
Apr 7, 2009, 11:27:23 PM4/7/09
to sy...@googlegroups.com

Yes, that is a fair point.

Ryan James

unread,
Apr 8, 2009, 4:30:46 AM4/8/09
to sy...@googlegroups.com
one weird thing is that A is a base unit, while C is derived. so when
it prints everything as SI base units, A is correct, not C/s.

>
>
> >

Gael Varoquaux

unread,
Apr 8, 2009, 7:50:00 AM4/8/09
to sy...@googlegroups.com
On Wed, Apr 08, 2009 at 03:28:25AM +0200, Fredrik Johansson wrote:
> I disagree, 1/s is the definition of the hertz, period (pun accidental :-).

Correct.

> Frequencies and angular frequencies differ by a factor 2*pi precisely
> because they measure different things, so equating them is (usually)
> an error, like equating meters and kilometers. The inability of
> dimensional analysis to prevent such errors is a limit of scope, not
> one of rigor.

I have halways written these as rad/s, not Hertz. For a unit point of
view (IOW typing), this is indistinguishable from Hertz, however :(.

Gaël

Aaron S. Meurer

unread,
Apr 8, 2009, 10:29:45 AM4/8/09
to sy...@googlegroups.com
On Apr 8, 2009, at 2:30 AM, Ryan James wrote:
>
> one weird thing is that A is a base unit, while C is derived. so when
> it prints everything as SI base units, A is correct, not C/s.


This is weird to most people when they first see it, but it is true
that A, not C, is the base unit relating to electromagnetism in the SI
system. See http://en.wikipedia.org/wiki/SI_base_unit. I have
forgotten why exactly this is. I think it has something to do with
working nicer with Maxwell's equations or something.

Aaron

kenji

unread,
Apr 9, 2009, 3:43:25 AM4/9/09
to sy...@googlegroups.com
Hello Bill and alls.

I claim to use MKSA+V base units system, not MKSA

I know volt unit is derived and "m**2*kg/(A*s**3)" at SI:International System
of Units.

But no electrical/electronics engineers can't understand
voltage:115*m**2*kg/(A*s**3). They can understand only 115*V.

Similarly they can't understand resistor:1*m**2*kg/(A**2*s**3). They can under
stand 1*ohm or 1*V/A.

SI unit system was constructed compromising with previously established
volt/ampere. Because it compromised with volt/ampere/ohm, it had to use kg as
a unit mass and couldn't use g. It had to use weird value 2*10**-7*newton to
define a unit current and couldn't use 1*newton.

For electrical/electronics engineers, 1*ohm is resistance shedding 1*ampere
between 1*volt. There are two base units for them in electro magnetic arear.

----------------------------------
Bill wrote


>In [34]: A*ohm
>Out[34]: m**2*kg/(A*s**3) <-- Why not 'V'?

I agree with you. The result must be V

>In [35]: V/A
>Out[35]: m**2*kg/(A**2*s**3) <-- Why not 'ohm'?

I don't agree with you. It is easy to break down to base unit. But It is
uneasy to synthesize unit, because the best synthesized unit is not determined
uniquely and depends on user purposes.

----------------------------------
I am dissatisfied that sympy unit module uses MKSA base units and V:volt is a
derived unit.

I am also dissatisfied that sympy.sin etc functions accept physical values
with unit and math, scipy functions can't accept it.

//@@
import sympy as ts
import sympy.physics.units as ut
import math
import scipy
print ts.sin(2*ut.s)
#print math.sin(2*ut.s) #ValueError: Symbolic value, can't compute
#print scipy.sin(1.5*ut.s) #AttributeError: sin
//@@@
sin(2*s)

sin(2*s) is correct as a result of symbolic operations, but is nonsence as a
physical equation. Physically, sin function's parameter must be unitless.

----------------------------------
I propose to introduce MSKA+V base unit and Float(physicalValue) function as
codes in appendix. V,A,ohm units operations become as below examples

print 1.5* ohm --> 1.50000000000000*V/A
print 1.5* ohm *(1*A) --> 1.50000000000000*V


****************** Help me out *******************
Yet I am dissatisfied that one * unit become Unit instance, not a Mul
instance. So the it's str value dosen't have 1 and only unit.e.g
//@@
import sympy.physics.units as ut
print 1*ut.s
print 1*ut.m/(10*ut.s)
//@@@
s
m/(10*s)

This is not a severe problem. But 1*s, (1/10)*m/s results are desirable.
Is there a countermeasure?

--
Kenji Kobayashi


============== appendix begin ========================
//@@
"""
Physical units and dimensions.

The base class is Unit, where all here defined units (~200) inherit from.
"""

import sympy as ts
from sympy import Rational, pi
from sympy.core.basic import Basic, Atom

class Unit(Atom):
"""
Base class for all physical units.

Create own units like:
m = Unit("meter", "m")
"""
is_positive = True # make (m**2)**Rational(1,2) --> m
is_commutative = True

__slots__ = ["name", "abbrev"]

def __new__(cls, name, abbrev, **assumptions):
#import pdb; pdb.set_trace()
obj = Basic.__new__(cls, **assumptions)
assert isinstance(name, str),`type(name)`
assert isinstance(abbrev, str),`type(abbrev)`
obj.name = name
obj.abbrev = abbrev
return obj

def __eq__(self, other):
return isinstance(other, Unit) and self.name == other.name

def _hashable_content(self):
return (self.name,self.abbrev)

# Delete this so it doesn't pollute the namespace
del Atom

def defunit(value, *names):
u = value
g = globals()
for name in names:
g[name] = u


# Dimensionless

percent = percents = Rational(1,100)
permille = permille = Rational(1,1000)

ten = Rational(10)

yotta = ten**24
zetta = ten**21
exa = ten**18
peta = ten**15
tera = ten**12
giga = ten**9
mega = ten**6
kilo = ten**3
deca = ten**1
deci = ten**-1
centi = ten**-2
milli = ten**-3
micro = ten**-6
nano = ten**-9
pico = ten**-12
femto = ten**-15
atto = ten**-18
zepto = ten**-21
yocto = ten**-24

rad = radian = radians = 1
deg = degree = degrees = pi/180


# Base units

defunit(Unit('meter', 'm'), 'm', 'meter', 'meters')
defunit(Unit('kilogram', 'kg'), 'kg', 'kilogram', 'kilograms')
defunit(Unit('second', 's'), 's', 'second', 'seconds')
defunit(Unit('ampere', 'A'), 'A', 'ampere', 'amperes')
defunit(Unit('kelvin', 'K'), 'K', 'kelvin', 'kelvins')
defunit(Unit('mole', 'mol'), 'mol', 'mole', 'moles')
defunit(Unit('candela', 'cd'), 'cd', 'candela', 'candelas')
defunit(Unit('volt', 'V'), 'V', 'volt', 'volts')


# Derived units

defunit(1/s, 'Hz', 'hz', 'hertz')
defunit(m*kg/s**2, 'N', 'newton', 'newtons')
defunit(N*m, 'J', 'joule', 'joules')
#defunit(J/s, 'W', 'watt', 'watts')
defunit(V*A, 'W', 'watt', 'watts')
defunit(N/m**2, 'Pa', 'pa', 'pascal', 'pascals')
defunit(s*A, 'C', 'coulomb', 'coulombs')
defunit(V/A, 'ohm', 'ohms')
defunit(A/V, 'S', 'siemens', 'mho', 'mhos')
defunit(C/V, 'F', 'farad', 'farads')
defunit(J/A, 'Wb', 'wb', 'weber', 'webers')
defunit(V*s/m**2, 'T', 'tesla', 'teslas')
defunit(V*s/A, 'H', 'henry', 'henrys')


def Float(physicalValAg):
if isinstance(physicalValAg, ts.Number):
return float(physicalValAg)
else:
assert isinstance(physicalValAg, ts.Mul)
# covert V to m**2*kg/(A*s**3)
compensatingUnitAt = 1
for elmAt in physicalValAg.args:
if elmAt == V:
compensatingUnitAt = compensatingUnitAt*(m**2*kg/(A*s**3))/V
elif isinstance(elmAt, ts.Pow):
if elmAt.args[0] == V:
powNumAt = elmAt.args[1]
compensatingUnitAt = (compensatingUnitAt
*((m**2*kg/(A*s**3))**powNumAt)
*(V**-powNumAt)
)
if compensatingUnitAt == 1:
assert False, ("At Float(.), you set physical quantity parameter"
+",the unit of which is not cancelled:"
+ str(physicalValAg)
)
else:
valAt = physicalValAg * compensatingUnitAt
assert isinstance(valAt, ts.Number),("At Floa(.)"
+ " you set physical quantity parameter"
+",the unit of which is not cancelled:"
+ str(valAt)
)

return float(valAt)

print 1* W
print 1* V
print 1* ohm
print 1* ohm *(1*A)

print 1.5* W
print 1.5* V
print 1.5* ohm
print 1.5* ohm *(1*A)

print 1*W/(10*V *(5*A))
print 1*W/(10*J/s)
print 3.3*F
print 1*F *(1*V)/(2*C)

print "========== Float ============="
print Float(1.5*s *(1.1/s) )
print Float(1*s/s)
print Float(1.5*V*A /(1.1*W) )
print Float(1.5*W*s /(1.1*N*m) )
print Float(1.5* m**2*kg/(A*s**3)/(1.1*V) )

import math
import scipy
print math.sin(Float(1.5*V*A /(1.1*W) ))
print scipy.sin(Float(1.5*V*A /(1.1*W) ))
print ts.sin(Float(1*V*A /W ))
//@@@
//copy \#####.### temp.py /y

A*V
V
V/A
V
1.50000000000000*A*V
1.50000000000000*V
1.50000000000000*V/A
1.50000000000000*V
1/50
s**3*A*V/(10*kg*m**2)
3.30000000000000*A*s/V
1/2
========== Float =============
1.65
1.0
1.36363636364
1.36363636364
1.36363636364
0.978619003421
0.978619003421
sin(1.00000000000000)

============== appendix end ========================

Aaron S. Meurer

unread,
Apr 9, 2009, 10:50:35 AM4/9/09
to sy...@googlegroups.com
I'm inclined to agree that maybe SymPy should be smarter when it
prints combined units, but there is the question of how it would
resolve ambiguities. For example, the force on a lever arm (Fxr) has
the same units as energy (mgh), but saying that it is in Joules would
be incorrect, because the force on a lever arm is a vector and energy
(and thus Joules) is a scalar. There are other cases when it would
not be as incorrect but might still be confusing if the user was
expecting one unit but got a dimensionally equivalent one. Can't
think of any off the top of my head, but I know I have ran into
several of them, especially in electricity and magnetism.

Aaron Meurer
Reply all
Reply to author
Forward
0 new messages