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?
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
> 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
> 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
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
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.
The simplest workaround would be to recognize simpler forms for units
at the pretty-printing stage.
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
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
Yes, that is a fair point.
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
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
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 ========================