Home > Enterprise >  IndexError trying to solve difference equations numerically in python
IndexError trying to solve difference equations numerically in python

Time:09-22

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]}")

CodePudding user response:

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]

CodePudding user response:

I think your problem that you should remember the index of any element in the list starting from zero and the index of the last element is N - 1 where N is the count of the elements in the list.
So you should make this change in your for loop:

for n in range(0, N):

Also, your using of print should be a reflection to the data in your list. So you should fix the argument of your print function to the following:

print(f"x[{n 1}] = {x[n 1]}")

After making these changes, you will get this result:

x[1] = 1020.0
x[2] = 1040.4
x[3] = 1061.208
x[4] = 1082.43216
x[5] = 1104.0808032
x[6] = 1126.1624192640002
x[7] = 1148.68566764928
x[8] = 1171.6593810022657
x[9] = 1195.092568622311
x[10] = 1218.9944199947574

Please, Note you have N 1 elements not N elements in your list because of this line of your code

x = (N 1)*[0]

Hope this help.

CodePudding user response:

The length of your array is 11, which means the last element is accessed by x[10]. But in the loop, the value being called when n is 10 is x[11] which makes it go out of range.
I'm not sure about the constraints of your problem, but if you want to access x[11], change the total size of the array to x = (N 2)*[0].

Output

x[1] = 1040.4
x[2] = 1061.208
x[3] = 1082.43216
x[4] = 1104.0808032
x[5] = 1126.1624192640002
x[6] = 1148.68566764928
x[7] = 1171.6593810022657
x[8] = 1195.092568622311
x[9] = 1218.9944199947574
x[10] = 1243.3743083946524
  • Related