Numerisk integrasjon#
TMA4400 Matematikk 1: Kalkulus og lineær algebra
Dato: 03. november 2025
Generell fremgangsmåte#
Vi ønsker å beregne det bestemte integralet
hvor \(a<b\) begge er reelle tall.
En måte å gjøre dette på er å finne en funksjon \(F(x)\) slik at \(F'(x)=f(x)\) og
Men det er ikke alltid like lett å finne en \(F(x)\) som har et fornuftig uttrykk. Hvis for eksempel \(f(x)=e^{x^2}\), er
La oss heller velge en litt annen strategi som vil gjøre oss i stand til å integrere de fleste \(f(x)\). Hvis vi kan finne en annen funksjon \(g(x)\) slik at
vil også
Hvis vi i tillegg velger en \(g(x)\) som er enkel å integrere, kan vi kanskje finne en slags formel for integralet til \(f(x)\) også.
Fra Taylors teorem vet vi at polynomer er gode kandidater for \(g(x)\), og at de approksimerer \(f(x)\) godt under visse forutsetninger.
Definer følgende første ordens polynom:
da vil \(g(a)=f(a)\) og \(g(b)=f(b)\). Videre er
Her krevde vi at approksimasjonen \(g(x)\) skulle være lik funksjonen \(f(x)\) i punktene \(x=a\) og \(x=b\) og lineær ellers. La oss gjøre denne ideen mer generell.
Som i Eulers metode deler vi opp intervallet \([a,b]\) i like store deler. For \(n\in \mathbb{N}\), definerer vi altså steglengden \(h\) og nodene \(x_i\) ved
hvor \(x_0=a\) og \(x_n=b\).
I hver enkelt node ønsker vi at \(g(x)\) og \(f(x)\) skal ha samme funksjonsverdi. Vi skriver derfor
hvor \(0\leq l_i(x)\leq 1\) er et polynom av vilkårlig orden mellom nodene. Vi legger også merke til at
hvor \(w_i=\int_a^bl_i(x) \ dx\). Dette er den såkalte Newton-Cotes formelen som vi ikke skal gå mer inn på i TMA4400.
Rektangelmetoden#
Hvis vi nå lar \(l_i(x)\) være et polynom med orden lik 0, altså den konstante funksjonen
når \(i=0,\ldots,n-1\) og \(l_n(x)=0\) når \(i=n\), får vi
Dette gir at
Bemerkning. Dette er akkurat samme formel som opptrer i Riemann-summer bare at vi har bestemt oss for å velge venstre endepunkt i delintervallene. Vi kunne selvsagt også ha valgt høyre endepunkt uten store endringer.
import numpy as np
def rektangel(f, a, b, n):
# vi finner en approksimasjon av integralet ved rektangelmetoden
# Input:
# f: integranden
# a, b: integrasjonsintervallet
# n: antall delintervall
# Output: approksimasjonen av integralet
x_noder = np.linspace(a, b, n+1) # jevnt fordelte noder fra a til b
h = (b-a)/n # steglengden
R = h*(sum(f(x_noder[0:n]))) # summerer f(x_0), f(x_1), ... , f(x_{n-1})
return (n, R)
Eksempel#
Test koden på følgende eksempel:
Det eksakte svaret er 18.
def f(x): # integranden
return 4*x**3+x**2+2*x-1
a, b = -1, 2 # integrasjonsintervallet
n = 10 # antall delintervaller
(n, R) = rektangel(f, a, b, n) # numerisk løsning
print('n = {:3d}, Approksimasjon = {:.8f}'.format(n,R))
n = 10, Approksimasjon = 11.56500000
Prøv gjerne med konstanten \(-1\). Hva skjer da?
La oss nå illustrere hvordan dette ser ut grafisk.
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
x = np.linspace(a, b, n+1)
y = f(x)
h = (b - a)/n
x_plot = np.linspace(a , b, 200)
fig, ax1 = plt.subplots(figsize=(8,4))
ax1.plot(x_plot, f(x_plot),color="black",linewidth=2.0)
xm = x[0:n+1]
for i in range(0,n):
ax1.add_patch(Rectangle((x[i], 0), h , f(xm[i]), edgecolor="blue", facecolor="cyan"))
plt.xlabel("x-akse")
plt.ylabel("y-akse")
plt.title("Rektangelmetoden")
plt.show()
Feilanalyse for rektangelmetoden#
Vi lar feilen være gitt som
Teorem. Anta at \(f(x)\) og dens førstederiverte, \(f'(x)\), er kontinuerlige for \(x\in[a,b]\), og at \(|f'(x)|\leq K\) for alle \(x\in[a,b]\). Da har vi at
Bevis. Ved hjelp av egenskapene til integralet vil
som betyr at
Siden \(x\in[x_i,x_{i+1}]\), gir Taylors teorem følgende:
eller
Dette betyr at
La oss teste dette estimatet numerisk.
def f(x):
return 4*x**3+x**2+2*x-1
a, b = -1, 2
I_eksakt = 18 # vi regner ut integralet
for n in [1,2,4,8,16,32,64]:
(n, R) = rektangel(f, a, b, n=n) # numerisk løsning
err = abs(I_eksakt-R) # feil
if n == 1:
print('n = {:3d}, error = {:.3e}'.format(n, err))
else:
print('n = {:3d}, error = {:.3e}, reduction factor = {:.3e}'.format(n, err, err/err_prev))
err_prev=err
n = 1, error = 3.600e+01
n = 2, error = 2.588e+01, reduction factor = 7.188e-01
n = 4, error = 1.491e+01, reduction factor = 5.761e-01
n = 8, error = 7.945e+00, reduction factor = 5.330e-01
n = 16, error = 4.096e+00, reduction factor = 5.155e-01
n = 32, error = 2.079e+00, reduction factor = 5.075e-01
n = 64, error = 1.047e+00, reduction factor = 5.037e-01
Vi ser at feilen er redusert med en faktor \(0.5\) når antall delintervall øker med en faktor \(2\). Dette stemmer ganske bra med hva vi forventer:
Trapesmetoden#
Hvis vi nå lar \(l_i(x)\) være polynomer med orden lik 1, altså de lineære funksjonene
får vi
Dette gir at
import numpy as np
def trapes(f, a, b, n):
# vi finner en approksimasjon av integralet ved trapesmetoden
# Input:
# f: integranden
# a, b: integrasjonsintervallet
# n: antall delintervall
# Output: approksimasjonen av integralet
x_noder = np.linspace(a, b, n+1) # jevnt fordelte noder fra a til b
h = (b-a)/n # steglengden
T1 = f(x_noder[0]) # T1 = f(x_0)
T2 = f(x_noder[n]) # T2 = f(x_n)
T3 = sum(f(x_noder[1:n])) # T3 = f(x_1)+f(x_2)+...+f(x_{n-1})
T = (h/2)*(T1 + 2*T3 + T2)
return (n, T)
Eksempel#
Test koden på følgende eksempel:
Det eksakte svaret er 18.
def f(x): # integranden
return 4*x**3+x**2+2*x-1
a, b = -1, 2 # integrasjonsintervallet
n = 5 # antall delintervaller
(n, T) = trapes(f, a, b, n) # numerisk løsning
print('n = {:3d}, Approksimasjon = {:.8f}'.format(n,T))
n = 5, Approksimasjon = 19.26000000
Prøv gjerne med \(2x-1\). Hva skjer da?
La oss nå illustrere hvordan dette ser ut grafisk.
import matplotlib.pyplot as plt
x = np.linspace(a, b, n+1)
y = f(x)
h = (b - a)/n
x_plot = np.linspace(a , b, 200)
fig, ax2 = plt.subplots(figsize=(8,4))
ax2.plot(x_plot, f(x_plot),color="black",linewidth=2.0)
ax2.plot(x, y, color="red",linewidth=0.5)
ax2.fill_between(x, y, facecolor='orange')
for i in range(0,n+1):
plt.plot([x[i],x[i]],[0,y[i]],color="red",linewidth=0.5)
plt.xlabel("x-akse")
plt.ylabel("y-akse")
plt.title("Trapesmetoden")
plt.show()
Feilanalyse for trapesmetoden#
Nå lar vi feilen være gitt som
Teorem. Anta at \(f(x)\) og dens første- og andrederiverte, \(f'(x)\) og \(f''(x)\), er kontinuerlige for \(x\in[a,b]\), og at \(|f''(x)|\leq K\) for alle \(x\in[a,b]\). Da har vi at