9.3 Programmering med følger og rekker
Python-implementasjon av følger og rekker, iterasjon og visualisering.
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 tre 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 ")
Vi bruker matplotlib for plotting og math for matematiske funksjonar.
# 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 = 50Delsummar 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):
S += 1 / n**2 # Legg til neste ledd
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 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"Første n med a_n < 1: n = {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} (etter {n} iterasjoner)")
print(f"math.sqrt(3) = {math.sqrt(3):.12f}")Newton-metoden konvergerer ekstremt raskt (kvadratisk konvergens): talet på korrekte desimalar blir omtrent fordobla per iterasjon.
- plt.plot(x, y) - linjeplott (bra for delsummar og trendar)
- plt.stem(x, y) - stemmeplott (bra for diskrete følgjer)
- plt.axhline(y=L) - horisontal linje (bra for grenseverdiar)
- plt.yscale('log') - logaritmisk skala (bra for eksponentiell vekst)
GeoGebra er òg eit godt verktøy:
- Bruk Sekvens()-kommandoen for å generere følgjer
- Sekvens(k^2, k, 1, 10) gir
- Sum(Sekvens(1/k^2, k, 1, 100)) reknar ut delsummen
Begge verktøya lèt deg raskt eksperimentere med parametrar og visuelt oppdage mønster før du bevis dei analytisk.
Du tek opp eit lån på 500 000 kr med 5 % nominell årleg rente. Du betaler 35 000 kr per år. Lat vere restgjelda etter år.
a) Set opp ein rekursiv formel for .
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).
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)
gjeld.append(max(a, 0)) # Ikke vis negativ gjeld
plt.figure(figsize=(10, 5))
plt.plot(år, gjeld, "b-o", markersize=4)
plt.axhline(y=0, color="red", linestyle="--")
plt.xlabel("Aar")
plt.ylabel("Restgjeld (kr)")
plt.title("Lånamortisering: 500 000 kr til 5 % rente")
plt.grid(True)
plt.show()
print(f"Lånet er nedbetalt etter {n} år.")c) Resultat:
Programmet viser at lånet er nedbetalt etter ca. 24 år. Vi kan verifisere analytisk: For treng vi , dvs. restgjelda må vere over kr for at gjelda skal vekse. Sidan startlånet er lågare, vil det alltid bli nedbetalt.
Bruk Python til å undersøkje konvergensen av rekkja for ulike verdiar av .
a) Rekn ut delsummen for , , og .
b) Plott delsummane som funksjon av for desse fire verdiane av .
c) Kommenter kva verdiar av som gir konvergens.
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 = {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:
- : (divergerer)
- : (divergerer, men sakte)
- : (konvergerer mot )
- : (konvergerer mot )
c) Konklusjon: Rekkja konvergerer når og divergerer når .
der er vekstraten og er bæreevna. Startpopulasjonen er .
a) Skriv eit Python-program som reknar ut dei 50 første ledda og plottar dei.
b) Kva skjer med populasjonen på lang sikt?
import matplotlib.pyplot as plt
r = 2.8
K = 1000
P = 100 # Startpopulasjon P_0
N = 50
n_verdier = [0]
p_verdier = [P]
for n in range(N):
P = r * P * (1 - P / K)
n_verdier.append(n + 1)
p_verdier.append(P)
plt.figure(figsize=(10, 5))
plt.plot(n_verdier, p_verdier, "b-o", markersize=3)
plt.axhline(y=K * (1 - 1/r), color="red", linestyle="--",
label=f"Likevekt = {K*(1-1/r):.0f}")
plt.xlabel("Generasjon $n$")
plt.ylabel("Populasjon $P_n$")
plt.title("Logistisk populasjonsmodell ($r = 2.8$, $K = 1000$)")
plt.legend()
plt.grid(True)
plt.show()b) Analyse:
For stabiliserer populasjonen seg rundt likevekta:
Plottet viser at populasjonen oscillerer rundt og konvergerer mot denne verdien. For høgare verdiar av (t.d. ) oppstår kaotisk åtferd - eit fascinerande resultat frå dynamiske system.
# a_n = n^2 + 3n for n = 1, ..., 20
a = [n**2 + 3*n for n in range(1, 21)]sum() med generatoruttrykk for raske summar utan å lagre alle ledd:
S = sum(1/n**2 for n in range(1, 10001)) # Sum av 10 000 leddenumerate() gir både indeks og verdi:
for i, verdi in enumerate(a, 1):
print(f"a_{i} = {verdi}")Logaritmisk skala for følgjer som veks raskt:
plt.yscale('log') # Y-aksen i logaritmisk skalaplt.stem() passar for diskrete følgjer (enkeltpunkt med loddrette linjer), plt.plot() for trendar og delsummar.
- Indeksfeil: Python bruker 0-indeksering, men matematiske følgjer startar gjerne på . Pass på range(1, N+1) vs. range(N).
- Overskriving av variabel: I rekursive følgjer må du oppdatere variabelen etter at du har brukt den gamle verdien. Skriv a_ny = f(a) først, deretter a = a_ny.
- Flyttalsfeil: Python bruker flyttal med avgrensa presisjon (~15 desimalar). For veldig mange iterasjonar kan avrundingsfeil hope seg opp.
- Uendeleg løkke: Ei while-løkke utan korrekt stoppvilkår køyrer for alltid. Legg alltid inn ei maksimumsgrense: while a >= 1 and n < 10000:.
Grunnleggjande programmering av følgjer
Skriv eit Python-program som bruker ei for-løkke til å skrive ut dei 15 første ledda i den aritmetiske følgja og reknar ut summen . Verifiser summen analytisk med formelen .
Skriv eit Python-program som genererer dei 20 første ledda i den rekursive følgja , og plottar dei med matplotlib. Legg inn ei stipla linje for grenseverdien.
Bruk ei while-løkke til å finne det første leddet i følgja som er mindre enn .
Delsummar og konvergens
Skriv eit Python-program som reknar ut delsummane for . Samanlikn med Aperys konstant .
Plott delsummane for (den alternerande harmoniske rekkja). Kva er grenseverdien?
Figurtal med programmering
Skriv eit Python-program som reknar ut og plottar dei 20 første trekanttala og dei 20 første kvadrattala i same figur.
Verifiser med Python at for ved å sjekke at differansen er null for alle .
Praktisk modellering og tilnærmingar
Du investerer 5 000 kr ved starten av kvart år i eit fond med 7 % avkastning per år. Skriv eit Python-program som reknar ut og plottar formuen for tre ulike renter: 3 %, 7 % og 10 % over 30 år. Kommenter effekten av renteforskjellen.
Skriv eit Python-program som bruker Newtons metode () til å rekne ut for . Start med og køyr til . Skriv ut kvart ledd og talet på korrekte desimalar.
Bruk Python til å estimere ved hjelp av Leibniz-formelen: . Plott feilen som funksjon av i logaritmisk skala. Kor mange ledd treng du for 6 korrekte desimalar?
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 blir rekna ut ved å akkumulere ledd i ein sumvariabel — og kan brukast til å utforske konvergens numerisk.
- Numeriske metodar som Newtons metode ( for ) er rekursive følgjer som konvergerer raskt.
- Leibniz-rekkja konvergerer svært langsamt — val av algoritme tyder mykje.
| Nøkkelomgrep | Forklaring |
|---|---|
| For-løkke | Gjentek eit kjent tal gonger |
| While-løkke | Gjentek til ein vilkår blir broten |
| Akkumulator | Variabel som samlar opp ein sum |
| Newtons metode | Rekursiv tilnærming til røter/nullpunkt |
| Konvergenshastigheit | Kor raskt ein metode nærmar seg svaret |
Viktige formlar:
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.