Вычисление интеграла по методу Уэддля

Моажет кто-нибудь сказать мне, почему моя функция Weddle1() вычисляет интеграл по методу Уэддля неправильно?

def f(x):
    return x**2          # неопределенный интеграл: x**3 / 3, т.е. от 0 до 3 будет 9

def Weddle1(f, a, b, n): #Определяем интеграл по методу Уэддля
    h = (b - a) / n
    summa1 = 0
    summa1 += ((3*h/10)*(f(a)+5*f(a+h)+f(a+2*h)+6*f(a+3*h)+f(a+4*h)+5*f(a+5*h)+f (a+6*h)))
    return summa1  
    
a = float(input('Введите нижний предел интегрирования: '))
b = float(input('Введите верхний предел интегрирования: '))
n = int(input('Введите количество интервалов-разбиений для подсчета интеграла (В первый раз): '))
print(Weddle1(f, a, b, n))

Например для такого ввода

Введите нижний предел интегрирования:  0
Введите верхний предел интегрирования:  3
Введите количество интервалов-разбиений для подсчета интеграла (В первый раз):  12

я получаю (вместо правильного результата 9) неправильный результат 1.125.

Спасибо заранее.


Ответы (1 шт):

Автор решения: MarianD

введите сюда описание изображения

Картинка показывает, что надо подсчитать.
Итоговую сумму затем нужно умножить на 3/10 деления на оси x.


К самому вопросу:

  1. n должно выть положительным и делится на 6. Иначе издать сообщение об ошибке.
  2. Вычисление должно сделать для всякого целого кратного 6 повторно (т.е. в цикле).
  3. Почему summa1, когда другой суммы нет? Я изменил это имя просто на summa.
  4. Хорошо класть пробелы пред/за операторами и длинное выражения не писать в одною строку.
  5. В PEP 8 - руководства по написанию кода на Python рекомендуется, чтобы имена функций состояли только из строчных букв, потому я изменил имя Weddle1 на weddle1.

Значит, ваша (слегка исправлена) программа может быть такой:

def weddle1(f, a, b, n): #Определяем интеграл по методу Уэддля
    if n % 6 != 0 or n <= 0:
        raise ValueError("n должно быть положительным и целым кратным 6")
    else:
        h = (b - a) /  n
        summa = 0
        for __ in range(n // 6):
            summa += ((3 * h / 10) * (f(a) + 5 * f(a + h) + f(a + 2 * h)   
                      + 6 * f(a + 3 * h) + f(a + 4 * h) + 5 * f(a + 5 * h)  
                      + f(a + 6 * h)))  
            a += 6 * h  
        return summa

Для более продвинутых более питонический подход:

def weddle1(f, a, b, n): #Определяем интеграл по методу Уэддля
    if n % 6 != 0 or n <= 0:
        raise ValueError("n должно быть положительным и целым кратным 6")
    else:
        h = (b - a) /  n
        coefs = 1, 5, 1, 6, 1, 5, 1 
        summa = 0
        for a in [a + 6 * k * h for k in range(n // 6)]:
            points = (a + k * h for k in range(7))
            values = map(f, points)
            summa += sum(c * v for c, v in zip(coefs, values))  
        return 3 * h / 10 * summa

Даже более хитро (из математической точки зрения):

def weddle1(f, a, b, n): #Определяем интеграл по методу Уэддля
    if n % 6 != 0 or n <= 0:
        raise ValueError("n должно быть положительным и целым кратным 6")
    else:
        h = (b - a) /  n
        coefs = (0, ) + n // 5  * (5, 1, 6, 1, 5, 2)
        points = (a + k * h for k in range(n + 1))
        values = map(f, points)
        summa =  sum(c * v for c, v in zip(coefs, values))
        return 3 * h / 10 * (summa - f(b) + f(a))
→ Ссылка