Неизвестная ошибка с самоопределенной функцией для аппроксимации интеграла - PullRequest
0 голосов
/ 28 ноября 2018

Я определил следующую функцию как метод аппроксимации интеграла с использованием правила Буля:

def integrate_boole(f,l,r,N):
    h=((r-l)/N)
    xN = np.linspace(l,r,N+1)
    fN = f(xN)
    return ((2*h)/45)*(7*fN[0]+32*(np.sum(fN[1:-2:2]))+12*(np.sum(fN[2:-3:4]))+14*(np.sum(fN[4:-5]))+7*fN[-1])

Я использовал функцию, чтобы получить значение интеграла для sin(x)dx между 0 и пи (где N = 8) и присвоил его переменной sine_int.

Ответ был 1.3938101893248442

После выполнения исходного уравнения (см. здесь ) вручнуюЯ понял, что этот ответ был довольно неточным.

Суммы fN дают неправильные значения, но я не уверен, почему.Например, np.sum(fN[4:-5]) равно 0.

Есть ли лучший способ кодирования соответствующих сумм или в моих параметрах есть ошибка, которая приводит к неточности вычислений?

Заранее спасибо.

РЕДАКТИРОВАТЬ

Я должен был прояснить, что это должна быть составная версия правила, то есть аппроксимация по N точкам, где Nделится на 4. Таким образом, к сожалению, типичные 5 точек с 4 интервалами здесь не помогут.Я скопировал бы уравнение, которое я использую здесь, но у меня нет изображения этого, и LaTex не вариант.Это должно быть ясно из кода, который я имею после return.

Ответы [ 3 ]

0 голосов
/ 28 ноября 2018

Во-первых, один из ваших коэффициентов был неверным, как указал @nixon.Тогда, я думаю, вы на самом деле не понимаете, как работает правило Boole - оно аппроксимирует интеграл функции, используя только 5 точек функции.Следовательно, такие термины, как np.sum(fN[1:-2:2]), не имеют смысла.Вам нужно всего пять очков, которые вы можете получить с xN = np.linspace(l,r,5).Ваша h - это просто расстояние между 2 смежными точками h = xN[1] - xN[0].А потом, легкий peasy:

import numpy as np 

def integrate_boole(f,l,r):
    xN = np.linspace(l,r,5)
    h = xN[1] - xN[0]
    fN = f(xN)
    return ((2*h)/45)*(7*fN[0]+32*fN[1]+12*fN[2]+32*fN[3]+7*fN[4])

def f(x):
  return np.sin(x)

I = integrate_boole(f, 0, np.pi)
print(I) # Outputs 1.99857...
0 голосов
/ 28 ноября 2018

Я не уверен, что вы надеетесь, что ваш код соответствует правилу Boole.Почему вы суммируете по образцам функции (т.е. np.sum(fN[2:-3:4]))?Я думаю, что ваш N параметр также не очень хорошо определен, и я не уверен, что он должен представлять.Возможно, вы используете другое правило, с которым я не знаком: я позволю вам решить.

В любом случае, вот реализация правила Буля, как его определяет Википедия.Переменные отображаются на версию Википедии, которую вы связали:

def integ_boole(func, left, right):
    h = (right - left) / 4
    x1 = left
    x2 = left + h
    x3 = left + 2*h
    x4 = left + 3*h
    x5 = right # or left + 4h

    result = (2*h / 45) * (7*func(x1) + 32*func(x2) + 12*func(x3) + 32*func(x4) + 7*func(x5))
    return result

, а затем, для проверки:

import numpy as np
print(integ_boole(np.sin, 0, np.pi))

выводит 1.9985707318238357, что очень близко к правильному ответу 2.

HTH.

0 голосов
/ 28 ноября 2018

Из быстрого осмотра похоже, что термин умножения f (x_4) должен быть 32, а не 14:

def integrate_boole(f,l,r,N):
    h=((r-l)/N)
    xN = np.linspace(l,r,N+1)
    fN = f(xN)
    return ((2*h)/45)*(7*fN[0]+32*(np.sum(fN[1:-2:2]))+
                       12*(np.sum(fN[2:-3:4]))+32*(np.sum(fN[4:-5]))+7*fN[-1])
...