2
\$\begingroup\$

I have an implementation of an Euler method for solving N-many 1st order coupled differential equations, but I feel that I did not write it as efficiently as I could, due to lack of programming experience.

Here is the implementation:

def eulerMethod(f, init0, h, om, mesh):
    """
    f          - array of ODES
    init0      - intial values     
    h          - step size
    om         - array of symbols 
    mesh       - time mesh to evolve over

    This implements Euler's method for finding numerically the
    solution of the 1st order system of N-many ODEs

    output in form of: [t:, om0:, om1:, om2:, ... ]  
    """

    numOfDE = len(f)
    t00 = mesh[0]
    soln = [[t00]]
    for i in xrange(numOfDE): # create intitial soln
        soln[0].append(init0[i])   

    subVal = {} # for diff eq substituion 
    for i in xrange(len(om)):
        subVal.update({om[i]:init0[i]})

    g = sympy.symbols('g0:%d'%len(om))
    s = sympy.symbols('s0:%d'%len(om))

    # set up dictionary for equations 
    eqDict = {g[0]:init0[0]}    
    for i in xrange(1,len(om)):
        eqDict[g[i]] = init0[i]

    for i in xrange(6): # number of steps
        for i in xrange(len(om)): # performs euler steps
            eqDict[s[i]] = eqDict[g[i]] + h*1.0*(f[i].subs(subVal))

        for i in xrange(len(om)): # set recursive values
            eqDict[g[i]] = eqDict[s[i]]

        t00 += h 
        soln.append([t00])
        for i in xrange(numOfDE): # append rest of solutions 
            soln[len(soln)-1].append(eqDict[s[i]])

        subVal = {} # update values to be subsititied        
        for i in xrange(len(om)):
            subVal.update({om[i]:eqDict[g[i]]})

    return soln       

I know my naming is sort of confusing, but I just wanted to see how solid my algorithm is. I will be using this to typically solve 1000 coupled differential equations.

\$\endgroup\$
3
  • \$\begingroup\$ @Bhathiya-JaDogg-Perera It means differential equations as the Euler method is a numerical method of solving differential equation, but my apologies, I have edited it. \$\endgroup\$
    – bynx
    Commented Aug 18, 2014 at 16:50
  • \$\begingroup\$ @JanneKarila This was an error in copying into this post, I'll edit it to correct it. \$\endgroup\$
    – bynx
    Commented Aug 18, 2014 at 17:02
  • 1
    \$\begingroup\$ Obligatory link: legacy.python.org/dev/peps/pep-0008 \$\endgroup\$
    – jonrsharpe
    Commented Aug 18, 2014 at 17:21

1 Answer 1

2
\$\begingroup\$
  • Naming is confusing indeed. What is sy, om, etc?

  • I do not understand a need for eqDict and subVal. Using init directly is much more straightforward:

for example,

 result = [ init0[i] + h*f[i].subs(init0) for i in xrange(init0) ]
 init0 = [ x for x in result]
  • Updating subVal at the end of the function is meaningless.

  • It is very unclear why the Euler step is repeated 6 times for one time step.

  • Is there a reason to pass mesh, if the code only uses mesh[0]?

  • The description should mention that the function only addresses autonomous systems.

\$\endgroup\$
4
  • \$\begingroup\$ The reason I use eqDict and subVal is because each step the values of 'init0' is changed as the next of the Euler step depends on the solutions of the previous step. I could see how it seems confusing, hence why I assumed that this is not that efficient of a method. The time step is increasing with each Euler step and included in the array of the returned solution, but I do agree, passing mesh does seem quite pointless as I could not find a way to correlate the each mesh point to each Euler step. \$\endgroup\$
    – bynx
    Commented Aug 18, 2014 at 18:03
  • \$\begingroup\$ You only need to replace init0 with a calculated result. See update. \$\endgroup\$
    – vnp
    Commented Aug 18, 2014 at 18:06
  • \$\begingroup\$ Ah. That seems to work much better and thankfully looks much cleaner. Thank you. I drastically over-thought this code. \$\endgroup\$
    – bynx
    Commented Aug 18, 2014 at 18:10
  • \$\begingroup\$ I'm having a bit of trouble with your solution, due to the use of sympy, the symbols used cannot be substituted without using subVal, unless if there is another way to substitute an unknown number of symbols with their values without using a dictionary. \$\endgroup\$
    – bynx
    Commented Aug 18, 2014 at 19:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.