Search code examples
pythonmathindex-errordifference-equations

IndexError trying to solve difference equations numerically in python


I'm practicing how to numerically solve difference equations, but I often run into problems like the one below.

Can anyone help me sort this out?

import numpy as np

N = 10
#alternative 1
#x = np.zeros(N+1, int)       # Produces error IndexError: index 11 is out of bounds for axis 0 with size 11

#alternative 2
x = (N+1)*[0]                 # Produces error: IndexError: list assignment index out of range

x[0] = 1000
r = 1.02

for n in range(1, N+1):
    x[n+1] = r**(n+1)*x[0]
    print(f"x[{n}] = {x[n+1]}")


Solution

  • Fixing the indices

    The range of your indices is inconsistent with the way you use them in the loop. You can use either of the following two possible loops, but don't mix them:

    for n in range(1, N+1):
        x[n] = r**n * x[0]
    
    for n in range(0, N):
        x[n+1] = r**(n+1) * x[0]
    

    Optimization: multiplications instead of exponentiations

    Note that computing an exponent ** is always more costly than computing a multiplication *; you can slightly optimize your code by using a recurrence formula:

    for n in range(1, N+1):
        x[n] = r * x[n-1]
    
    for n in range(0, N):
        x[n+1] = r * x[n]
    

    Using library functions: itertools, numpy or pandas

    What you are asking for is called a geometric progression. Python provides several ways of computing geometric progressions without writing the loop yourself.

    For instance:

    import itertools  # accumulate, repeat
    import operator   # mul
    def geometric_progression(x0, r, N):
        return list(itertools.accumulate(itertools.repeat(r,N), operator.mul, initial=x0))
    
    print(geometric_progression(1000, 1.2, 10))
    # [1000, 1200.0, 1440.0, 1728.0, 2073.6, 2488.3199999999997, 2985.9839999999995, 3583.180799999999, 4299.816959999999, 5159.780351999999, 6191.736422399998]