3

Imagine something like

exp(49/200)+(x-49/200)

I want to pass as argument of the function "roundn" whatever operation that is not a addtion or a subtraction So my expression became

roundn(exp(roundn(49/200, n)), n) + (x - roundn(49/200, n)

Well the expression I want to manipulate is this:

exp(49/200)+exp(49/200)*(x-49/200)+1/2*exp(49/200)*(x-49/200)^2+1/6*exp(49/200)*(x-49/200)^3+1/24*exp(49/200)*(x-49/200)^4+1/120*exp(49/200)*(x-49/200)^5+1/720*exp(49/200)*(x-49/200)^6+1/5040*exp(49/200)*(x-49/200)^7+1/40320*exp(49/200)*(x-49/200)^8+1/362880*exp(49/200)*(x-49/200)^9+1/3628800*exp(49/200)*(x-49/200)^10+1/39916800*exp(49/200)*(x-49/200)^11
trent
  • 25,033
  • 7
  • 51
  • 90
Peterstone
  • 7,119
  • 14
  • 41
  • 49
  • I think you mean function `round()` described in the docs [here](http://docs.python.org/library/functions.html?highlight=round#round). – martineau Nov 23 '10 at 11:38
  • Seems like you could just write your own functions for multiply, divide, exp, pow, etc and rewrite you expression using them. If it's something you'll do to a lot of different expressions then it might be worthwhile to automate the conversion with an expression parser. The Python `ast` (Abstract Syntax Trees) module should be helpful. – martineau Nov 23 '10 at 14:17
  • As far as I can tell, your main expression is approximately `exp(x)`. Roughly, the first 12 terms of the [power series expansion](http://en.wikipedia.org/wiki/Characterizations_of_the_exponential_function). – Gary Kerr Nov 23 '10 at 15:05

4 Answers4

6

Maybe you think you want to do this, but you don't really want to do this. New Pythoners usually think they need to round floating point numbers because when evaluated they get unexpected results (like 1.0/10 = 0.100000000000001). Rather than do some goofy string substitution on your expression, I just created a variable for round(49/200,n), and did a little format cleanup. Also exp(49/200) does not need to be evaluated 13 times, just do it once and refer to the computed value.

zz = round(49/200,n)
e_zz = exp(zz)
ans = (e_zz + 
    e_zz * (x-zz) +
    1/2 * e_zz * (x-zz)**2 +
    1/6 * e_zz * (x-zz)**3 +
    1/24 * e_zz * (x-zz)**4 +
    1/120 * e_zz * (x-zz)**5 +
    1/720 * e_zz * (x-zz)**6 +
    1/5040 * e_zz * (x-zz)**7 +
    1/40320 * e_zz * (x-zz)**8 +
    1/362880 * e_zz * (x-zz)**9 +
    1/3628800 * e_zz * (x-zz)**10 +
    1/39916800 * e_zz * (x-zz)**11)

Raising e to a rounded number is almost never appropriate. Likewise for raising a rounded number to the 11'th power. (Note also that in Python, the exponentiation operator is **, not ^.)

Edited: If S.Lott hadn't suggested the algebraic simplification, I would have left this as-is. But the * e_zz can be factored out of every term, giving the simpler (and probably faster):

zz = round(49/200,n)
e_zz = exp(zz)
ans = e_zz * (1 + 
    (x-zz) +
    1/2 * (x-zz)**2 +
    1/6 * (x-zz)**3 +
    1/24 * (x-zz)**4 +
    1/120 * (x-zz)**5 +
    1/720 * (x-zz)**6 +
    1/5040 * (x-zz)**7 +
    1/40320 * (x-zz)**8 +
    1/362880 * (x-zz)**9 +
    1/3628800 * (x-zz)**10 +
    1/39916800 * (x-zz)**11)
PaulMcG
  • 62,419
  • 16
  • 94
  • 130
2

Use this

http://sympy.org/

S.Lott
  • 384,516
  • 81
  • 508
  • 779
1

I wonder whether this is what you need:

If you original equation is in the string variable eq you can create your new equations using the replace method of strings:

eq.replace('49/200', 'roundn(49/200,n)')

and a similar expression could put roundn around the exp() function (possibly need some nifty regex here).

Ber
  • 40,356
  • 16
  • 72
  • 88
  • eq.replace will not do inplace modification (strings being immutable and all). Change to `eq = eq.replace(etc.)` – PaulMcG Nov 30 '10 at 12:25
  • Maybe that's not what the OP wants. The expression in my answer creates a new string containing the modified equation. No need to change that. – Ber Nov 30 '10 at 16:14
0

You could sub every match of say, p=re.compile(r'\d+/\d+') with the output of your roundn function. FYI, approximating so many terms in you expression will yield a result that is not necessarily very close to the actual result, depending on how many digits you round to.

JonC
  • 277
  • 1
  • 4
  • 18