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.
- Documentation: numpy.geomspace
- Documentation: itertools.accumulate
- Question: Geometric progression using Python / Pandas / Numpy
- Question: python geometric sequence
- Question: Generate a geometric progression using list comprehension
- Question: Making a list of a geometric progression when the ratio and range are given
- Question: Writing python code to calculate a Geometric progression
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