10  Integrasjon

10.1 Approksimering av integral

Det er fleire måtar me kan approksimera bestemte integral numerisk. I GeoGebra finn me funksjonane SumUnder og SumOver som gjev oss summen av arealet til \(n\) rektangel mellom \(a\) og \(b\)\(x\)-aksen. Rektangla er litt for store eller litt for små, som følgje av at den øverste sida ligg under eller over funksjonen. SumUnder vil dermed gje eit resultat som er litt mindre enn det faktiske resultatet, medan SumOver vil gje eit litt for stort resultat.

Animasjonen under viser korleis nøyaktigheita til SumUnder aukar etter kvart som antall rektangel vert større. Med fleire rektangel vert arealet som ikkje vert dekka mindre og mindre.

Figur 10.1: Animasjon av venstresum

Den enklaste approksimasjonen er å finna venstre- eller høgresum. Med venstresum skal kvar av rektangla ha høgde slik at hjørnet øverst til venstre ligg på funksjonen. Høgresum finn me på same måte, men med hjørnet øverst til høgre på funksjonen. Algoritmen vert ganske lik for begge. Me ser på venstresum først.

10.1.1 Venstresum

Me skal finna summen av \(n\) rektangel mellom \(a\) og \(b\) som er slik at hjørnet øverst til venstre på kvart rektangel ligg på funksjonen. Breidda til rektangla kallar me \(dx\) (\(\Delta x\) på figuren).

Figur 10.2: Venstresum
def venstresum(f, a, b, n):
    # finn bredden
    dx = (b-a)/n

    # startverdiar
    x = a
    sum_venstre = 0 

    # finn arealet av kvart rektangel og legg arealet til totalen
    for i in range(n):
        rektangel = f(x)*dx
        sum_venstre += rektangel
        x += dx

    # returnerer totalverdien
    return sum_venstre

Tester algoritmen på funksjonen \[f(x)=x^3+2x+3\]

Prøver å finna ein omtrentleg verdi for arealet under \(f(x)\) mellom \(x=2\) og \(x=5\). Prøver med \(n=100\).

def f(x):
    return x**3 + 2*x + 3


print(f"Venstresum: {venstresum(f, 2, 5, 100):.3f}")
Venstresum: 180.410

10.1.2 Høgresum

Me skal finna summen av \(n\) rektangel mellom \(a\) og \(b\) som er slik at hjørnet øverst til høgre på kvart rektangel ligg på funksjonen. Breidda til rektangla kallar me \(dx\). Funksjonen er heilt lik som i venstresum() men me endrar rektangel til f(x+dx)*dx slik at me reknar høgda på høgresida av rektangelet. Sjå Figur 10.2

def høgresum(f, a, b, n):
    dx = (b-a)/n

    x = a
    sum_høgre = 0 

    for i in range(n):
        rektangel = f(x+dx)*dx
        sum_høgre += rektangel
        x += dx

    return sum_høgre

Testar på samme funksjon og intervall som tidlegare:

print(f"Høgresum: {høgresum(f, 2, 5, 100):.3f}")
Høgresum: 184.100

Med det kan me anta at arealet ligg ein stad mellom 180,41 og 184,10. Med andre ord \[180.41 \leq \int_2^5 f(x)\,dx \leq 184.10\]

Om me aukar talet på rektangel vil me få ein betre approksimasjon:

print(f"Venstresum: {venstresum(f, 2, 5, 1000):.3f}")
print(f"Høgresum: {høgresum(f, 2, 5, 1000):.3f}")
Venstresum: 182.066
Høgresum: 182.435

10.1.3 Sum under og sum over

Me kan laga algoritmar som fungerer på same måte som GeoGebra sine tidlegare nemnde SumUnder og SumOver. Me tek utgangspunkt i samme algoritme som tidlegare, men no må me sjekka kva for ei av sidene som er kortast (for SumUnder) eller lengst (for SumOver).

Sum under først:

def sumunder(f, a, b, n):
    dx = (b-a)/n

    x = a
    sum_under = 0 

    # finn den kortaste sida og bruker den som høgde
    for i in range(n):
        if f(x) <= f(x+dx):
            rektangel = f(x)*dx
        else:
            rektangel = f(x+dx)*dx

        sum_under += rektangel
        x += dx

    return sum_under

Sum over blir heilt anaalogt, men me snur ulikskapen:

def sumover(f, a, b, n):
    dx = (b-a)/n

    x = a
    sum_over = 0 

    for i in range(n):
        if f(x) >= f(x+dx):
            rektangel = f(x)*dx
        else:
            rektangel = f(x+dx)*dx

        sum_over += rektangel
        x += dx

    return sum_over

Tester på funksjonen og intervallet frå tidlegare:

print(f"Sum under: {sumunder(f, 2, 5, 100):.3f}")
print(f"Sum over: {sumover(f, 2, 5, 100):.3f}")
Sum under: 180.410
Sum over: 184.100

Kva for ein av desse som fungerer best vil avhenga av funksjonen. Tenk gjerne litt på kva type funksjonar dei ulike passar godt eller dårleg til.

10.1.4 Trapesmetoden

Ein veldig effektiv måte å approksimera arealet under grafen på er å laga trapes framfor rektangel. Høgda på trapeset vert dx medan dei to parallelle sidene vert f(x)og f(x+dx).

Figur 10.3: Trapesmetoden
def trapesmetoden(f, a, b, n):
    dx = (b-a)/n

    x = a
    sum_trapes = 0 

    for i in range(n):
        trapes = ((f(x)+f(x+dx))*dx)/2
        sum_trapes += trapes
        x += dx

    return sum_trapes

# tester med n=100
print(f"Trapesmetode: {trapesmetoden(f, 2, 5, 100):.3f}")
Trapesmetode: 182.255

Me reknar ut det bestemte integralet \[\int_2^5 x^3 +2x +3 \, dx = \frac{729}{4} = 182.25\]

Her ser me at me kjem nærare svaret med 100 trapes enn med 1000 rektangel, så trapesmetoden er mykje meir nøyaktig.

10.2 Symbolsk integrasjon med SymPy

(her kjem litt om korleis ein kan integrera symbolsk med sympy / CAS i python)