Как избежать выхода за пределы диапазона в цикле Python?
В функции gauss_integrated()
реализую расчет интеграла методом Гаусса. Надо не просто получить значение, но и уложить его в требуемую точность delta
. По идее бы удваивать число интервалов, на которые дробится площадь под кривой. Но расчет завязан на коэффициенты A
и t
(дробим на пять - и коэффициенты берем под цифрой 5), которые я не считаю, а просто перенес из таблицы. "Пакетов" с коэффициентами всего 6 - не разбежишься. В общем я просто прибавляю по одному узлу для дробления (вместо радикального удваивания), пока не достигну шести (и если повезет - требуемой точности при этом).
Первый расчет внутренней функции gauss()
(дает неточное значение) реализуется (в пункте 10 кода - строка integ_1 = gauss(n)
). Но стоит прибавить единицу (и рассчитать gauss()
с новым n
), как получаю выход за пределы диапазона:
IndexError: list index out of range
Из диапазона выхожу в пункте 9.1 кода, в строке x_k_j = ( (b +(a*(2*j_els+1)) )/(2*(j_els+1))) + ( ( (b-a) / (2*(j_els+1)) ) * t_a_total_list[k_elems][0][0] )
. Как преодолеть ошибку?
Вот код (схематично):
import numpy as np
def func_for_integrate(x):
"""
Исходная функция для последующего интергрирования
"""
res = (1+np.sqrt(x))/(x**2)
return res
def gauss_integrated(a, b):
"""
Функция получения интеграла по методу Гаусса
"""
# 1. запросим порядок формулы и точность
n = int( input('Введите порядок формулы (количество узлов от 1 до 6): ') )
delta = float( input('Введите точность расчета (десятичная дробь): ') )
# 2. определим условие, при котором n не может быть меньше единицы и больше шести
assert n>=1 and n<=6, 'Определите n от 1 до 6'
# 3. определим словарь с коэффициентами t:
# здесь ключи верхнего порядка (1,2,3 и т.д.) - это n из таблицы
# ключи второго порядка - i из таблицы,
# значения ключей второго порядка коэффициенты t
dict_of_koeffs_t = {
1:
{1:[0]},
2:
{1:[0.57735027], 2:[-0.57735027]},
...
6:
{1:[0.932469515], 2:[0.66120939], 3:[0.23861919], 4:[-0.23861919], 5:[-0.66120939], 6:[-0.932469515]}
}
# 4. определим словарь с коэффициентами А
dict_of_koeffs_A = {
1:
{1:[2]},
2:
{1:[1], 2:[1]},
...
6:
{1:[0.17132450], 2:[0.36076158], 3:[0.46791394], 4:[0.46791394], 5:[0.36076158], 6:[0.17132450]}
}
# 5. по заданному пользователем n извлекаем в список
# значения коэффициента t словаря соответствующего порядка n
t_list = []
for t in dict_of_koeffs_t[n].keys():
t_list.append(dict_of_koeffs_t[n][t])
# 6. по заданному пользователем n извлекаем в список
# значения коэффициента A словаря соответствующего порядка n
a_list = []
for a_els in dict_of_koeffs_A[n].keys():
a_list.append(dict_of_koeffs_A[n][a_els])
# 7. формируем список кортежей, в которых сложены соответствующие t и А:
# первый t - первый А, второй t - второй А и т.д.
t_a_total_list = list(zip(t_list, a_list))
def gauss(n):
# 8. определим переменную для параметра j
j_els = n-1
# 9. Рассчитаем интеграл с параметром j
# 9.1. определим цикл для получения интеграла с параметром j
sum_outside = 0 # первая сумма
# Ниже диапазон: по количеству коэф-ов в зависимости от n
# (например, при n=3 таких три: t1, t2, t3 и A1, A2, A3)
for k_elems in range(1, n):
sum_inside = 0 # вторая сумма
# i_elems - кол-во точек рассечения отрезка [a,b]
for i_elems in range(0, j_els):
x_k_j = ( (b +(a*(2*j_els+1)) )/(2*(j_els+1))) + ( ( (b-a) / (2*(j_els+1)) ) * t_a_total_list[k_elems][0][0] )
...
sum_inside += ...
sum_outside += sum_inside
# 9.2. получим значение интеграла по формуле
s_j = ( ((b-a)/(2*(j_els+1))) * sum_outside )
return s_j
# 10. приблизим расчет по заданной пользователем точности
integ_1 = gauss(n)
if n <= 5:
n += 1
else:
raise Exception('Достигнуто максимальное значение параметра узлов n')
integ_2 = gauss(n)
# 11. применим критерий точности вычисления
err_gauss = abs((integ_2 - integ_1)/integ_2)
# 12. С помощью цикла добьемся требуемой точности расчета
while err_gauss > delta:
if n <= 5:
integ_1 = integ_2
n += 1
integ_2 = gauss(n)
err_gauss = abs((integ_2 - integ_1)/integ_2)
else:
raise Exception('Достигнуто максимальное значение параметра узлов n')
# 13. Выведем результаты
print('Интеграл по методу Гаусса: ', s_j)
print('Достигнутая ошибка интегрирования: ', err_gauss)
return s_j, err_gauss
gauss_integrated(1, 4)