tags:

views:

268

answers:

3

I'm fairly new to sympy and have what might be a basic question. Or I might simply be misinterpreting how sympy is supposed to be used.

Is there a way to create an expression that is not represented by atoms, but by a combination of other expressions?

Ex:

>>> from sympy.physics.units import *
>>> expr1 = m/s
>>> expr2 = mile/hour
>>> expr1
m/s
>>> expr2
1397*m/(3125*s)
>>> expr1.in_terms_of([mile,hour]) #in my dreams?
3125*mile/(1397*hour)
>>> 

On a side note: Can i find an 'official' pdf (or other printable) version of the complete sympy documentation. (I'm under draconian internet usage restrictions at work and am tired of doing work at home on the weekend.)

Update:

This is what I ended up with following Prelude's suggestion, however it's not likely to get much use like this as it feels dirty. Comments and WTF's welcome.

def in_terms_of(self, terms):
    expr2 = eval(str(self), physics.units.__dict__)
    converter = {}
    for term in terms:
        term_expr = physics.units.__dict__[term]
        coeff = term_expr.as_coeff_terms()[0]
        unit = physics.units.Unit('my_'+term, term)
        converter[term_expr/coeff] = unit/coeff
    return str(expr2.subs(converter))

Usage:

>>> x = in_terms_of('J',['gram','mile','hour'])
>>> x
'9765625000*mile**2*gram/(1951609*hour**2)'
>>> in_terms_of(x,['J'])
'J'
+1  A: 

In sympy units you convert from expr1 to expr2 by dividing:

In [120]: import sympy.physics.units as units

In [121]: expr1 = units.m / units.s

In [122]: expr2 = units.miles / units.hour

In [123]: a = (1397/3125) * expr1 / expr2

In [124]: a
Out[124]: 1

The only issue is that you end up with a dimensionless quantity. You might also consider the Quantities package for this type of thing:

In [125]: import quantities as pq

In [126]: a = pq.Quantity(1397/3125, 'm/s')

In [127]: a
Out[127]: array(0.44703999999999999) * m/s

In [128]: a.units = pq.mile / pq.hour

In [129]: a
Out[129]: array(1.0) * mi/h

There's also Unum.

I don't know of a PDF version of the sympy docs, but you might be able to check the distribution out from their repository and use Sphinx to generate a PDF for yourself.

ars
+=1 for Quantities. However, I'm not ready to bring it into the battlefield yet. ..and Sphinx2pdf
bpowah
+2  A: 

Checking the source for sympy.physics.units you can see that all units are defined in terms of meters, kilograms, seconds, amperes, kelvins, moles and candelas. These are the base units.

Then a mile is defined as 5280 feet, and a foot is defined as 0.3048 meters.

So all expressions using non-base units will have the non-base units replaced with the base units.

You can define your own units which you can subsitute into an expression when you need an expression to use particular units:

import sympy.physics.units as units
from sympy import Rational

my_mile = units.Unit('my_mile', 'mile')
my_hour = units.Unit('my_hour', 'hour')

Then define a dictionary which will substitute the base units for your new units.

converter = {units.m: my_mile/Rational('1609.344'),
             units.s: my_hour/Rational('3600')}

Perform all your calculations using the base units. Then if you want a value using miles and hours, you can substitute your new units into the expression.

v = 10*units.miles/units.hour
print v # = 2794*m/(625*s)

print v.subs(converter) # = 10*mile/hour

Use ars answer for getting the docs. Sympy's repository is here: http://git.sympy.org/?p=sympy.git;a=summary

There is a README file in the docs folder which describes how to create html docs.

PreludeAndFugue
+1  A: 

there's also quantities:

In [1]: from quantities import *
In [2]: v = 1397*m / (3125*s)
In [3]: v
Out[3]: array(0.44704) * m/s
In [8]: v.units = mile/hour
In [9]: v
Out[9]: array(1.0) * mi/h
Autoplectic