9.3

9.3 Programmering med følgjer og rekkjer

Python-implementasjon av følgjer og rekkjer, iterasjon og visualisering.

50 min
12 oppgaver
PythonFor-løkkerKonvergensMatplotlibVisualisering
Du leser den tradisjonelle versjonen
Din fremgang i kapitlet
0 / 12 oppgaver
Kapitlets plass i kurset

Programmering er eit kraftig supplement til analytisk matematikk. Når vi studerer følgjer og rekkjer, gir Python oss høve til å:

- Generere hundrevis av ledd med ein gong, sjølv for kompliserte rekursive formlar
- Visualisere konvergens og divergens grafisk
- Eksperimentere med parametrar og sjå effekten med ein gong
- Modellere praktiske situasjonar der analytiske formlar er kompliserte

I dette kapittelet bruker vi to typar løkker:
- for-løkke: Når vi veit nøyaktig kor mange iterasjonar vi treng (t.d. "rekn ut dei første 50 ledda")
- while-løkke: Når vi itererer til ein vilkår er oppfylt (t.d. "køyr til feilen er under 10−610^{-6}")

Vi bruker matplotlib for plotting og math for matematiske funksjonar.

Lese eit program

På eksamen skal du ofte forklare kva eit program reknar ut, eller finne kva det skriv ut. Då følgjer vi variablane gjennom løkka i ein sporingstabell: éi rad per runde, med verdiane etter at linjene i løkka er utførte. Vilkåret i while blir sjekka før kvar runde.

✏️Sporingstabell for ei while-løkke
a = 200
n = 0
while a > 100:
    a = 0.8*a + 10
    n = n + 1
print(n, round(a, 2))

a) Kva skriv programmet ut?

b) Forklar kva programmet finn ut.

a)

nnaaa>100a > 100?
0200200ja
10,8⋅200+10=1700{,}8 \cdot 200 + 10 = 170ja
20,8⋅170+10=1460{,}8 \cdot 170 + 10 = 146ja
30,8⋅146+10=126,80{,}8 \cdot 146 + 10 = 126{,}8ja
40,8⋅126,8+10=111,440{,}8 \cdot 126{,}8 + 10 = 111{,}44ja
50,8⋅111,44+10=99,1520{,}8 \cdot 111{,}44 + 10 = 99{,}152nei

Løkka stoppar etter runde 5.
Svar: Programmet skriv ut 5 99.15.
b)
Programmet reknar ut ledda i følgja a0=200a_0 = 200, an=0,8 an−1+10a_n = 0{,}8\,a_{n-1} + 10 til eit ledd er 100 eller mindre.
Svar: Programmet finn at a5≈99,15a_5 \approx 99{,}15 er det første leddet som ikkje er større enn 100.

Eksplisitte følgjer blir rekna ut direkte:

# Geometrisk følge: a_n = 100 *
# 0.85^(n-1)
a1 = 100
k = 0.85
for n in range(1, 21):
    a_n = a1 * k ** (n - 1)
    print(f"a_{n:>2} = {a_n:.4f}")

Rekursive følgjer oppdaterer variabelen i kvar iterasjon:

# Rekursiv: a_{n+1} = 0.7 * a_n +
# 15, a_1 = 200
a = 200
print(f"a_1 = {a:.4f}")
for n in range(2, 21):
    a = 0.7 * a + 15
    print(f"a_{n:>2} = {a:.4f}")
# Grenseverdi: L = 0.7L + 15 => L
# = 50

Delsummar blir rekna ut med ein akkumulerande variabel:

import matplotlib.pyplot as plt

N = 100
S = 0
n_verdier = []
s_verdier = []

for n in range(1, N + 1):
    # Legg til neste ledd
    S += 1 / n**2
    n_verdier.append(n)
    s_verdier.append(S)

plt.plot(
    n_verdier,
    s_verdier,
    "b-",
    linewidth=1.5,
)
plt.axhline(
    y=3.14159**2 / 6,
    color="red",
    linestyle="--",
    label=(
        r"$\pi^2/6 \approx"
        r" 1.6449$"
    ),
)
plt.xlabel("n")
plt.ylabel("$S_n$")
plt.title(
    "Delsummer av $\\sum 1/n^2$"
)
plt.legend()
plt.grid(True)
plt.show()

Ei while-løkke er nyttig når vi ikkje veit på førehand kor mange iterasjonar vi treng. Eit typisk brukstilfelle er å iterere til ei følgje har konvergert til ønskt presisjon.

Eksempel: Finne talet på ledd til grenseverdien er nådd

# Geometrisk følge a_n = 500 *
# 0.9^(n-1)
# Finn første n slik at a_n < 1
a = 500
n = 1
while a >= 1:
    a = a * 0.9
    n += 1
print(
    "Første n med a_n < 1: n ="
    f" {n}, a_n = {a:.6f}"
)

Eksempel: Iterasjon til konvergens

# Rekursiv: a_{n+1} = (a_n +
# 3/a_n) / 2  (kvadratrot av 3 med
# Newton-metoden)
import math

a = 2.0  # Startgjetning
toleranse = 1e-10
n = 0

while True:
    a_ny = (a + 3 / a) / 2
    n += 1
    if abs(a_ny - a) < toleranse:
        break
    a = a_ny

print(
    f"sqrt(3) = {a_ny:.12f} "
    f" (etter {n} iterasjoner)"
)
print(
    "math.sqrt(3) ="
    f" {math.sqrt(3):.12f}"
)

Newton-metoden konvergerer ekstremt raskt (kvadratisk konvergens): talet på korrekte desimalar blir omtrent fordobla per iterasjon.

✏️Lånamortisering med Python

Du tek opp eit lån på 500 000 kr med 5 % nominell årleg rente. Du betaler 35 000 kr per år. Lat ana_n vere restgjelda etter nn år.

a) Set opp ein rekursiv formel for ana_n.
b) Skriv eit Python-program som reknar ut restgjelda for kvart år og plottar utviklinga.
c) Finn det første året der restgjelda er nedbetalt (under 0 kr).

a) Rekursiv formel:

an+1=an⋅1,05−35 000,a0=500 000a_{n+1} = a_n \cdot 1{,}05 - 35\,000, \quad a_0 = 500\,000

Restgjelda veks med 5 % rente, men blir redusert med årsbetalinga.

b) Python-program:

import matplotlib.pyplot as plt

a = 500_000  # Startlån
rente = 1.05
betaling = 35_000

år = [0]
gjeld = [a]

n = 0
while a > 0:
    a = a * rente - betaling
    n += 1
    år.append(n)
    # Ikke vis negativ gjeld
    gjeld.append(max(a, 0))

plt.figure(figsize=(10, 5))
plt.plot(
    år, gjeld, "b-o", markersize=4
)
plt.axhline(
    y=0,
    color="red",
    linestyle="--",
)
plt.xlabel("År")
plt.ylabel("Restgjeld (kr)")
plt.title(
    "Lånamortisering: 500 000 kr"
    " til 5 % rente"
)
plt.grid(True)
plt.show()
print(
    "Lånet er nedbetalt etter"
    f" {n} år."
)

c) Resultat:

Programmet skriv ut «Lånet er nedbetalt etter 26 år.» Etter 25 år er restgjelda om lag 22 729 kr, og i år 26 blir ho negativ.

Kontroll: Gjelda veks berre dersom rentene 0,05⋅an0{,}05 \cdot a_n er større enn betalinga på 35 000 kr, altså dersom an>700 000a_n > 700\,000 kr. Sidan 500 000<700 000500\,000 < 700\,000, minkar gjelda kvart år.

Eksplisitt formel: an=700 000−200 000⋅1,05na_n = 700\,000 - 200\,000 \cdot 1{,}05^n. Då gir an≤0a_n \leq 0 at 1,05n≥3,51{,}05^n \geq 3{,}5, altså n≥ln⁡3,5ln⁡1,05≈25,7\displaystyle n \geq \frac{\ln 3{,}5}{\ln 1{,}05} \approx 25{,}7.

Svar: a) an+1=1,05⋅an−35 000a_{n+1} = 1{,}05 \cdot a_n - 35\,000 med a0=500 000a_0 = 500\,000. c) Lånet er nedbetalt i løpet av år 26.

✏️Numerisk utforsking av konvergens

Bruk Python til å undersøkje konvergensen av rekkja ∑n=1∞1np\displaystyle \sum_{n=1}^{\infty} \frac{1}{n^p} for ulike verdiar av pp.

a) Rekn ut delsummen S10 000S_{10\,000} for p=0,5p = 0{,}5, p=1p = 1, p=1,5p = 1{,}5 og p=2p = 2.
b) Plott delsummane som funksjon av NN for desse fire verdiane av pp.
c) Kommenter kva verdiar av pp som gir konvergens.

a) og b) Python-program:

import matplotlib.pyplot as plt

N_max = 10000
p_verdier = [0.5, 1.0, 1.5, 2.0]

plt.figure(figsize=(10, 6))

for p in p_verdier:
    S = 0
    n_list = []
    s_list = []
    for n in range(1, N_max + 1):
        S += 1 / n**p
        if (
            n % 100 == 0
            or n <= 50
        ):
            n_list.append(n)
            s_list.append(S)
    print(
        f"p = {p}: S_10000 ="
        f" {S:.6f}"
    )
    plt.plot(
        n_list,
        s_list,
        label=f"p = {p}",
    )

plt.xlabel("N")
plt.ylabel("$S_N$")
plt.title(
    "Delsummer av $\\sum 1/n^p$"
)
plt.legend()
plt.grid(True)
plt.show()

Resultat:
- p=0,5p = 0{,}5: S10 000≈198,5S_{10\,000} \approx 198{,}5 (divergerer)
- p=1p = 1: S10 000≈9,79S_{10\,000} \approx 9{,}79 (divergerer, men sakte)
- p=1,5p = 1{,}5: S10 000≈2,592S_{10\,000} \approx 2{,}592 (konvergerer langsamt mot ζ(1,5)≈2,612\zeta(1{,}5) \approx 2{,}612)
- p=2p = 2: S10 000≈1,6448S_{10\,000} \approx 1{,}6448 (konvergerer mot π2/6≈1,6449\pi^2/6 \approx 1{,}6449)

Svar: c) Rekkja ∑1/np\sum 1/n^p konvergerer når p>1p > 1 og divergerer når p≤1p \leq 1.

✏️Populasjonsmodell med logistisk vekst
Ein populasjon blir modellert med den logistiske rekursive formelen
Pn+1=Pn+r⋅Pn(1−PnK)P_{n+1} = P_n + r \cdot P_n \left(1 - \frac{P_n}{K}\right)

der r=0,8r = 0{,}8 er vekstraten og K=1000K = 1000 er bereevna. Startpopulasjonen er P0=100P_0 = 100.

a) Skriv eit Python-program som reknar ut dei 30 første ledda og plottar dei.
b) Kva skjer med populasjonen på lang sikt?
c) Køyr programmet med r=1,8r = 1{,}8. Korleis endrar forløpet seg?

a) Python-program:

import matplotlib.pyplot as plt

r = 0.8
K = 1000
# Startpopulasjon P_0
P = 100
N = 30

n_verdier = [0]
p_verdier = [P]
for n in range(1, N + 1):
    P = P + r * P * (1 - P / K)
    n_verdier.append(n)
    p_verdier.append(P)

for n in range(11):
    print(
        f"P_{n:>2} ="
        f" {p_verdier[n]:.1f}"
    )

plt.figure(figsize=(10, 5))
plt.plot(
    n_verdier,
    p_verdier,
    "b-o",
    markersize=3,
)
plt.axhline(
    y=K,
    color="red",
    linestyle="--",
    label="Bæreevne K = 1000",
)
plt.xlabel("Generasjon n")
plt.ylabel("Populasjon P_n")
plt.title(
    "Logistisk populasjonsmodell"
    " (r = 0,8, K = 1000)"
)
plt.legend()
plt.grid(True)
plt.show()

b) Analyse:

Programmet skriv ut P0=100P_0 = 100, P1=172,0P_1 = 172{,}0, P2=285,9P_2 = 285{,}9, P3=449,3P_3 = 449{,}3, P4=647,2P_4 = 647{,}2, P5=829,9P_5 = 829{,}9, P6=942,8P_6 = 942{,}8, P7=985,9P_7 = 985{,}9, P8=997,0P_8 = 997{,}0, P9=999,4P_9 = 999{,}4 og P10=999,9P_{10} = 999{,}9.

Likevekt: P∗=P∗+rP∗(1−P∗K)\displaystyle P^* = P^* + rP^*\left(1 - \frac{P^*}{K}\right) gir rP∗(1−P∗K)=0\displaystyle rP^*\left(1 - \frac{P^*}{K}\right) = 0, altså P∗=0P^* = 0 eller P∗=KP^* = K.

Populasjonen veks først nesten eksponentielt, så bremsar veksten, og følgja nærmar seg bereevna K=1000K = 1000 utan å gå over.

c) r=1,8r = 1{,}8:

Programmet gir P1=262,0P_1 = 262{,}0, P2=610,0P_2 = 610{,}0, P3=1038,2P_3 = 1038{,}2, P4=966,8P_4 = 966{,}8, P5=1024,6P_5 = 1024{,}6 og P6=979,2P_6 = 979{,}2.

Populasjonen går over bereevna og svingar rundt 1000 med stadig mindre utslag. For 0<r<20 < r < 2 nærmar følgja seg KK.

Svar: b) Populasjonen nærmar seg bereevna K=1000K = 1000. c) Med r=1,8r = 1{,}8 svingar populasjonen rundt 1000 med minkande utslag, men nærmar seg framleis 1000.

📝Oppgave 1

Grunnleggjande programmering av følgjer

a

Skriv eit Python-program som bruker ei for-løkke til å skrive ut dei 15 første ledda i den aritmetiske følgja an=7+4(n−1)a_n = 7 + 4(n-1) og reknar ut summen S15S_{15}. Verifiser summen analytisk med formelen Sn=n2(2a1+(n−1)d)\displaystyle S_n = \frac{n}{2}(2a_1 + (n-1)d).

b

Skriv eit Python-program som genererer dei 20 første ledda i den rekursive følgja a1=1000a_1 = 1000, an+1=0,85⋅ana_{n+1} = 0{,}85 \cdot a_n og plottar dei med matplotlib. Legg inn ei stipla linje for grenseverdien.

c

Bruk ei while-løkke til å finne det første leddet i følgja an=1000⋅0,85n−1a_n = 1000 \cdot 0{,}85^{n-1} som er mindre enn 11.

Løs oppgaven
📝Oppgave 2

Delsummar og konvergens

a

Skriv eit Python-program som reknar ut delsummane SN=∑n=1N1n3\displaystyle S_N = \sum_{n=1}^{N} \frac{1}{n^3} for N=10,100,1000,10 000N = 10, 100, 1000, 10\,000. Samanlikn med Aperys konstant ζ(3)≈1,202056903\zeta(3) \approx 1{,}202056903.

b

Plott delsummane Sn=∑k=1n(−1)k+1k\displaystyle S_n = \sum_{k=1}^{n} \frac{(-1)^{k+1}}{k} for n=1,2,…,200n = 1, 2, \ldots, 200 (den alternerande harmoniske rekkja). Kva er grenseverdien?

Løs oppgaven
📝Oppgave 3

Figurtal med programmering

a

Skriv eit Python-program som reknar ut og plottar dei 20 første trekanttala Tn=n(n+1)2\displaystyle T_n = \frac{n(n+1)}{2} og dei 20 første kvadrattala Kn=n2K_n = n^2 i same figur.

b

Verifiser med Python at Tn+Tn−1=n2T_n + T_{n-1} = n^2 for n=2,3,…,100n = 2, 3, \ldots, 100 ved å sjekke at differansen er null for alle nn.

📝Oppgave 4

Praktisk modellering og tilnærmingar

a

Du investerer 5 000 kr ved starten av kvart år i eit fond med fast årleg avkastning. Skriv eit Python-program som reknar ut og plottar formuen for tre ulike avkastingar: 3 %, 7 % og 10 % over 30 år. Kommenter effekten av renteforskjellen.

b

Skriv eit Python-program som bruker Newtons metode (an+1=12(an+can)\displaystyle a_{n+1} = \frac{1}{2}(a_n + \frac{c}{a_n})) til å rekne ut c\sqrt{c} for c=7c = 7. Start med a0=3a_0 = 3 og køyr til ∣an+1−an∣<10−12|a_{n+1} - a_n| < 10^{-12}. Skriv ut kvart ledd og talet på korrekte desimalar.

c

Bruk Python til å estimere π\pi ved hjelp av Leibniz-formelen: π4=1−13+15−17+⋯\displaystyle \frac{\pi}{4} = 1 - \frac{1}{3} + \frac{1}{5} - \frac{1}{7} + \cdots. Plott feilen ∣Sn⋅4−π∣|S_n \cdot 4 - \pi| som funksjon av nn i logaritmisk skala. Kor mange ledd treng du for 6 korrekte desimalar?

📝Oppgave 5

Sjå på programmet.

S = 0
for n in range(1, 6):
    S = S + 3*n + 1
print(S)

a

Lag ein sporingstabell og finn kva programmet skriv ut.

b

Forklar kva programmet reknar ut.

Løs oppgaven
📝Oppgave 6

Sjå på programmet.

S = 0
n = 0
while S < 1000:
    n = n + 1
    S = S + 3*n + 1
print(n, S)

a

Forklar kva programmet finn ut.

b

Summen av dei nn første ledda er Sn=n(3n+5)2S_n = \dfrac{n(3n + 5)}{2}. Bruk dette til å finne kva programmet skriv ut.

Løs oppgaven
📝Oppgave 7

Sjå på programmet.

saldo = 10000
ar = 0
while saldo < 20000:
    saldo = saldo * 1.05 + 1000
    ar = ar + 1
print(ar, round(saldo))

a

Forklar kva programmet reknar ut.

b

Lag ein sporingstabell og finn kva programmet skriv ut.

Løs oppgaven

Oppsummering

Læringspunkt:
- For-løkker passar når talet på iterasjonar er kjent; while-løkker når ein itererer til ein vilkår er oppfylt (t.d. «første ledd under 200»).
- Rekursive følgjer blir programmerte ved å oppdatere ein variabel: a = p*a + q inne i løkka.
- Delsummar SNS_N blir rekna ut ved å akkumulere ledd i ein sumvariabel — og kan brukast til å utforske konvergens numerisk.
- Numeriske metodar som Newtons metode (an+1=12(an+can)\displaystyle a_{n+1} = \frac{1}{2}(a_n + \frac{c}{a_n}) for c\sqrt{c}) er rekursive følgjer som konvergerer raskt.
- Leibniz-rekkja π4=1−13+15−⋯\displaystyle \frac{\pi}{4} = 1 - \frac{1}{3} + \frac{1}{5} - \cdots konvergerer svært langsamt — val av algoritme tyder mykje.

NøkkelomgrepForklaring
For-løkkeGjentek eit kjent tal gonger
While-løkkeGjentek til ein vilkår blir broten
AkkumulatorVariabel som samlar opp ein sum
Newtons metodeRekursiv tilnærming til røter/nullpunkt
KonvergenshastigheitKor raskt ein metode nærmar seg svaret

Viktige formlar:
an+1=12(an+can)→c,π4=∑k=0∞(−1)k2k+1a_{n+1} = \tfrac{1}{2}\Big(a_n + \tfrac{c}{a_n}\Big) \to \sqrt{c}, \qquad \frac{\pi}{4} = \sum_{k=0}^{\infty}\frac{(-1)^k}{2k+1}
Repetisjonsoppgåver
Din fremgang
0deloppgaver0 / 5 oppgaver

Dette kapitlet er skrevet av Anthropics toppmodeller (Claude Opus og Claude Fable) og er foreløpig ikke manuelt gjennomgått — kvalitetskontrollen gjøres av uavhengige KI-agenter, og innmeldte feil rettes fortløpende. Funnet en feil? Meld fra, så retter vi den. Les mer om hvordan innholdet lages.