Attached is a simple class for modeling the derivation of the Euler method
for solving a first order ODE. (Mostly because it's one of the easiest
algorithms to start with)

Running it outputs all the steps:

D(f(x), x) == 2*x
(f_1 - f_0)/h == 2*x Approximate derivative with finite difference
f_1 - f_0 == 2*x*h
f_1 == f_0 + 2*x*h

Imagine this output to latex or mathml or some other pretty printer.  Also
imagine passing the last step to some sort of code generation.

Is this a useful direction?  It seems a little bit different than using
sympy to derive equations directly - it's similar to the way one would
derive by hand, but using sympy to verify each step.


Mark

-- 
You received this message because you are subscribed to the Google Groups 
"sympy" group.
To post to this group, send email to sy...@googlegroups.com.
To unsubscribe from this group, send email to 
sympy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sympy?hl=en.

from sympy import *

class approx_lhs(object):
    ''' Replace the left hand side with a new value (approximation)'''
    def __init__(self,  new_value):
        self.new_value = new_value

    def __call__(self, eqn):
        eqn = Eq(self.new_value,eqn.args[1])
        return eqn

class add_term(object):
    '''Add a term an equation'''
    def __init__(self,  term):
        self.term = term

    def __call__(self, eqn):
        eqn = Eq(eqn.args[0] + self.term, eqn.args[1] + self.term)
        return eqn

class mul_factor(object):
    '''Multiply equation by a factor'''
    def __init__(self,  factor):
        self.factor = factor

    def __call__(self, eqn):
        eqn = Eq(eqn.args[0] * self.factor, eqn.args[1] * self.factor)
        return eqn

class derivation(object):
    def __init__(self, initial_lhs, initial_rhs):
        self.steps = [(None,'')]
        self.eqn = Eq(initial_lhs, initial_rhs)
        self.eqns = [self.eqn]

    def add_step(self, operation, description=''):
        self.steps.append((operation, description))
        self.eqns.append(operation(self.eqns[-1]))

    def do_print(self):
        for (s,e) in zip(self.steps,self.eqns):
            print e,s[1]
       

def derive_euler():
    f = Function('f')
    x = Symbol('x')
    df = diff(f(x),x)
    fd = sympify('(f_1 - f_0)/h')
    g = Symbol('2*x')
    h = Symbol('h')
    f0 = Symbol('f_0')

    d = derivation(df,g)

    d.add_step(approx_lhs(fd),'Approximate derivative with finite difference')
    d.add_step(mul_factor(h))
    d.add_step(add_term(f0))

    d.do_print()


if __name__ == '__main__':
    derive_euler()

Reply via email to