9.3 Programmering med følger og rekker
Python-implementasjon av følger og rekker, iterasjon og visualisering.
Programmering er et kraftig supplement til analytisk matematikk. Når vi studerer følger og rekker, gir Python oss muligheten til å:
- Generere hundrevis av ledd umiddelbart, selv for kompliserte rekursive formler
- Visualisere konvergens og divergens grafisk
- Eksperimentere med parametre og se effekten umiddelbart
- Modellere praktiske situasjoner der analytiske formler er kompliserte
I dette kapitlet bruker vi tre typer løkker:
- for-løkke: Når vi vet nøyaktig hvor mange iterasjoner vi trenger (f.eks. "beregn de første 50 leddene")
- while-løkke: Når vi itererer til en betingelse er oppfylt (f.eks. "kjør til feilen er under ")
Vi bruker matplotlib for plotting og math for matematiske funksjoner.
# 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ølger oppdaterer variabelen i hver 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 = 50Delsummer beregnes med en akkumulerende 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()En while-løkke er nyttig når vi ikke vet på forhånd hvor mange iterasjoner vi trenger. Et typisk brukstilfelle er å iterere til en følge har konvergert til ønsket presisjon.
Eksempel: Finne antall 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): antall korrekte desimaler omtrent fordobles per iterasjon.
- plt.plot(x, y) - linjeplott (bra for delsummer og trender)
- plt.stem(x, y) - stemmeplott (bra for diskrete følger)
- plt.axhline(y=L) - horisontal linje (bra for grenseverdier)
- plt.yscale('log') - logaritmisk skala (bra for eksponentiell vekst)
GeoGebra er også et godt verktoy:
- Bruk Sekvens()-kommandoen for å generere følger
- Sekvens(k^2, k, 1, 10) gir
- Sum(Sekvens(1/k^2, k, 1, 100)) beregner delsummen
Begge verktoyene lar deg raskt eksperimentere med parametre og visuelt oppdage mønstre før du beviser dem analytisk.
Du tar opp et lån på 500 000 kr med 5 % nominell årlig rente. Du betaler 35 000 kr per år. La være restgjelden etter år.
a) Sett opp en rekursiv formel for .
b) Skriv et Python-program som beregner restgjelden for hvert år og plotter utviklingen.
c) Finn det første året der restgjelden er nedbetalt (under 0 kr).
Restgjelden vokser med 5 % rente, men reduseres med årsbetalingen.
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 trenger vi , dvs. restgjelden må være over kr for at gjelden skal vokse. Siden startlånet er lavere, vil det alltid bli nedbetalt.
Bruk Python til å undersoke konvergensen av rekken for ulike verdier av .
a) Beregn delsummen for , , og .
b) Plott delsummene som funksjon av for disse fire verdiene av .
c) Kommenter hvilke verdier 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()Resultater:
- : (divergerer)
- : (divergerer, men sakte)
- : (konvergerer mot )
- : (konvergerer mot )
c) Konklusjon: Rekken konvergerer når og divergerer når .
der er vekstraten og er bæreevnen. Startpopulasjonen er .
a) Skriv et Python-program som beregner de 50 første leddene og plotter dem.
b) Hva 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 likevekten:
Plottet viser at populasjonen oscillerer rundt og konvergerer mot denne verdien. For høyere verdier av (f.eks. ) oppstår kaotisk atferd - et fascinerende resultat fra dynamiske systemer.
# 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 summer uten å 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ølger som vokser raskt:
plt.yscale('log') # Y-aksen i logaritmisk skalaplt.stem() passer for diskrete følger (enkeltpunkter med loddrette linjer), plt.plot() for trender og delsummer.
- Indeksfeil: Python bruker 0-indeksering, men matematiske følger starter gjerne på . Pass på range(1, N+1) vs. range(N).
- Overskriving av variabel: I rekursive følger må du oppdatere variabelen etter at du har brukt den gamle verdien. Skriv a_ny = f(a) først, deretter a = a_ny.
- Flyttallsfeil: Python bruker flyttall med begrenset presisjon (~15 desimaler). For veldig mange iterasjoner kan avrundingsfeil hope seg opp.
- Uendelig løkke: En while-løkke uten korrekt stoppbetingelse kjører for alltid. Legg alltid inn en maksimumsgrense: while a >= 1 and n < 10000:.
Grunnleggende programmering av følger
Skriv et Python-program som bruker en for-løkke til å skrive ut de 15 første leddene i den aritmetiske følgen og beregner summen . Verifiser summen analytisk med formelen .
Skriv et Python-program som genererer de 20 første leddene i den rekursive følgen , og plotter dem med matplotlib. Legg inn en stiplet linje for grenseverdien.
Bruk en while-løkke til å finne det første leddet i følgen som er mindre enn .
Delsummer og konvergens
Skriv et Python-program som beregner delsummene for . Sammenlign med Aperys konstant .
Plott delsummene for (den alternerende harmoniske rekken). Hva er grenseverdien?
Figurtall med programmering
Skriv et Python-program som beregner og plotter de 20 første trekantallene og de 20 første kvadrattallene i samme figur.
Verifiser med Python at for ved å sjekke at differansen er null for alle .
Praktisk modellering og tilnærminger
Du investerer 5 000 kr ved starten av hvert år i et fond med 7 % avkastning per år. Skriv et Python-program som beregner og plotter formuen for tre ulike renter: 3 %, 7 % og 10 % over 30 år. Kommenter effekten av renteforskjellen.
Skriv et Python-program som bruker Newtons metode () til å beregne for . Start med og kjør til . Skriv ut hvert ledd og antall korrekte desimaler.
Bruk Python til å estimere ved hjelp av Leibniz-formelen: . Plott feilen som funksjon av i logaritmisk skala. Hvor mange ledd trenger du for 6 korrekte desimaler?
Oppsummering
Læringspunkter:
- For-løkker passer når antall iterasjoner er kjent; while-løkker når man itererer til en betingelse er oppfylt (f.eks. «første ledd under 200»).
- Rekursive følger programmeres ved å oppdatere en variabel: a = p*a + q inne i løkka.
- Delsummer beregnes ved å akkumulere ledd i en sumvariabel — og kan brukes til å utforske konvergens numerisk.
- Numeriske metoder som Newtons metode ( for ) er rekursive følger som konvergerer raskt.
- Leibniz-rekken konvergerer svært langsomt — valg av algoritme betyr mye.
| Nøkkelbegrep | Forklaring |
|---|---|
| For-løkke | Gjentar et kjent antall ganger |
| While-løkke | Gjentar til en betingelse brytes |
| Akkumulator | Variabel som samler opp en sum |
| Newtons metode | Rekursiv tilnærming til røtter/nullpunkter |
| Konvergenshastighet | Hvor raskt en metode nærmer seg svaret |
Viktige formler:
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.