IndexError пытается численно решить разностные уравнения в Python
Я практикуюсь в численном решении разностных уравнений, но часто сталкиваюсь с проблемами, подобными приведенной ниже.
Может ли кто-нибудь помочь мне разобраться в этом?
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]}")
3 ответа
Я думаю, ваша проблема в том, что вы должны запомнить индекс любого элемента, начиная с нуля, а индекс последнего элемента равен
N - 1
где - количество элементов в.
Поэтому вам следует внести это изменение в свой
for
петля:
for n in range(0, N):
Кроме того, ваше использование должно отражать данные в вашем. Итак, вы должны исправить аргумент вашего
print
функция к следующему:
print(f"x[{n+1}] = {x[n+1]}")
После внесения этих изменений вы получите такой результат:
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
Пожалуйста, обратите внимание, что у вас есть
N + 1
элементы не
N
элементы в вашем
list
из-за этой строки вашего кода
x = (N+1)*[0]
Надеюсь на эту помощь.
Исправление индексов
Диапазон ваших индексов несовместим с тем, как вы их используете в цикле. Вы можете использовать любой из следующих двух возможных циклов, но не смешивайте их:
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]
Оптимизация: умножение вместо возведения в степень
Обратите внимание, что вычисление экспоненты
**
всегда дороже, чем вычисление умножения
*
; вы можете немного оптимизировать свой код, используя формулу повторения:
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]
Использование библиотечных функций:
itertools
,
numpy
или
pandas
То, что вы просите, называется геометрической прогрессией . Python предоставляет несколько способов вычисления геометрических прогрессий без написания цикла самостоятельно.
- Документация: numpy.geomspace
- Документация: itertools.accumulate
- Вопрос: геометрическая прогрессия с использованием Python / Pandas / Numpy
- Вопрос: геометрическая последовательность Python
- Вопрос: построение геометрической прогрессии с использованием списка
- Вопрос: Составление списка геометрической прогрессии с указанием соотношения и диапазона
- Вопрос: написание кода на Python для вычисления геометрической прогрессии
Например:
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]
Длина вашего массива равна 11, что означает, что к последнему элементу обращается
x[10]
. Но в цикле значение, вызываемое, когда n равно 10, выходит за пределы допустимого диапазона.
Я не уверен в ограничениях вашей проблемы, но если вы хотите получить доступ
x[11]
измените общий размер массива на
x = (N+2)*[0]
.
Выход
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