Tutorial :SymPy: How to return an expression in terms of other expression(s)?



Question:

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?

Example:

>>> 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'  


Solution:1

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: https://github.com/sympy/sympy

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


Solution:2

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  


Solution:3

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.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »