Tilbake
7.5

7.5 DRILL — ODE-oppgaver med roterende innpakning

Full drill på I/J/K-sjangrene: samme ODE-øvelse under skiftende vitenskapelig innpakning, slik at mønsteret gjenkjennes uansett kontekst.

90 min
10 oppgaver
DRILLODE-oppgaver med roterende innpakning
Din fremgang i kapitlet
0 / 10 oppgaver

Sist du var her

Drillen forutsetter hele Del 7: kap. 7.1 (egen forlengs-Euler-funksjon), kap. 7.2 (bruk av hierarkiet), kap. 7.3 (systemer) og kap. 7.4 (subklasser). Her er de tre grepene du kommer til å bruke i hver eneste oppgave, oppfrisket med kjørt utskrift.

1. Egen løser som funksjon (sjanger I). N skritt, N+1 punkter, startverdien før løkka.

import numpy as np

def forward_euler(f, T, N, u0):
    t = np.linspace(0, T, N+1)
    u = np.zeros_like(t)
    u[0] = u0
    dt = t[1] - t[0]
    for n in range(N):
        u[n+1] = u[n] + dt*f(t[n], u[n])
    return t, u

def f(t, u):
    return -0.5*u

t, u = forward_euler(f, 4.0, 40, 3.0)
print(len(t), f'{u[-1]:.6f}', f'{3*np.exp(-2):.6f}')

Utskrift:

41 0.385536 0.406006

Med bare 40 skritt er forlengs Euler nesten fem prosent unna. Det er metodens feil, ikke kodens.

2. Det utleverte hierarkiet (sjanger J). Tre kall: konstruktør, startbetingelse, solve.

import numpy as np
from ODESolver import RungeKutta4

def f(t, u):
    return -0.5*u

solver = RungeKutta4(f)
solver.set_initial_condition(3.0)
t, u = solver.solve((0, 4), 40)
print(len(t), f'{u[-1]:.6f}', f'{3*np.exp(-2):.6f}')

Utskrift:

41 0.406006 0.406006

Samme antall skritt, seks riktige desimaler. Det er derfor RungeKutta4 er standardvalget når oppgaven ikke sier noe annet.

3. Systemer. Pakk ut u i høyresiden, returner en liste, og pakk ut kolonnene etterpå.

import numpy as np
from ODESolver import RungeKutta4

def f(t, u):
    x, y = u
    return [y, -x]

solver = RungeKutta4(f)
solver.set_initial_condition([1.0, 0.0])
t, u = solver.solve((0, 6), 600)
x, y = u[:, 0], u[:, 1]
print(u.shape)
print(f'{x[-1]:.6f} {np.cos(6):.6f}')

Utskrift:

(601, 2)
0.960170 0.960170

Formen (601, 2) sier alt: 601 tidspunkter i radene, 2 komponenter i kolonnene. Er noe av dette uklart, les kap. 7.3 først — drillen forklarer ikke konstruksjonene på nytt.

Forkunnskaper

- Egen forlengs-Euler-løser som funksjon (sjanger I): kap. 7.1.
- Det utleverte ODESolver-hierarkiet og de tre kallene: kap. 7.2.
- ODE-systemer: høyresiden f(t, u) og utpakking av kolonnene: kap. 7.3.
- Subklasse av ODESolver med advance (sjanger K): kap. 7.4.
- NumPy-tabeller, np.zeros og np.linspace: kap. 4.1.
- Plotting med label= og plt.legend(): kap. 4.3.

📜Løsningsoppskriften for sjanger J — sju steg

Les modellen i oppgaven, og gjør så dette, i rekkefølge.

1. Identifisér tilstandsvariablene. Hvor mange størrelser endrer seg over tid? Det er antall likninger, antall komponenter i u, og antall kolonner i svaret.
2. Skriv høyresiden def f(t, u): — tiden først. Første linje pakker ut: S, E, I, D = u. Deretter én linje per derivert, og return [dS, dE, dI, dD] som liste, i samme rekkefølge som utpakkingen.
3. Sett parametrene som variabler over funksjonen, eller lagre dem i en klasse med __call__(self, t, u) hvis oppgaven ber om det. Løseren kaller f med bare to argumenter, så parametrene kan ikke sendes inn.
4. Sett u0 som en liste av startverdier, i samme rekkefølge som utpakkingen.
5. De tre kallene: solver = RungeKutta4(f), solver.set_initial_condition(u0), t, u = solver.solve((0, T), N). Merk at t_span er én tuppel, altså ett argument.
6. Pakk ut kolonnene: S, E, I, D = u[:, 0], u[:, 1], u[:, 2], u[:, 3]. u[k] er hele tilstanden ved tidspunkt k — noe helt annet.
7. Plott: ett plt.plot(t, komponent, label='navn') per kurve, aksenavn, plt.legend(), plt.show(). Beskriv figuren i ord hvis oppgaven ber om det.

Skjelettet er alltid dette, og det er verdt å skrive ned først, før du fyller inn modellen:

from ODESolver import RungeKutta4

def f(t, u):
    x, y = u
    dx = 0.0
    dy = 0.0
    return [dx, dy]

solver = RungeKutta4(f)
solver.set_initial_condition([2.0, 5.0])
t, u = solver.solve((0, 10), 100)
print(u.shape, u[-1, 0], u[-1, 1])

Utskrift:

(101, 2) 2.0 5.0

Skjelettet gir uttelling i seg selv — her står begge komponentene stille, fordi de deriverte er null. Fyller du inn modellen feil, mister du ett eller to poeng; glemmer du skjelettet, mister du oppgaven.

Det gjennomarbeidede caset (~20 min)

Under står en komplett sjanger-J-oppgave av samme type og vekt som på et virkelig sett, med sensorkommentar ved hvert steg.

Oppgaven (10 poeng). Et utbrudd i en befolkning på N=50000N = 50\,000 modelleres med fire grupper: mottakelige SS, eksponerte EE (smittet, men ikke smittsomme ennå), smittsomme II og gjennomgått DD. Modellen er

S=βSIN,E=βSINσE,I=σEγI,D=γIS' = -\beta\frac{SI}{N}, \qquad E' = \beta\frac{SI}{N} - \sigma E, \qquad I' = \sigma E - \gamma I, \qquad D' = \gamma I

med β=0,45\beta = 0{,}45, σ=0,2\sigma = 0{,}2 og γ=0,14\gamma = 0{,}14. Ved t=0t = 0 er E=20E = 20, S=49980S = 49\,980 og I=D=0I = D = 0. Tiden måles i døgn. Du har ODESolver-modulen med ForwardEuler og RungeKutta4 tilgjengelig.

a) (4 p) Skriv høyresiden f(t, u).

b) (3 p) Skriv koden som løser systemet fra t=0t = 0 til t=200t = 200 med 2000 skritt ved hjelp av RungeKutta4, og pakker ut de fire komponentene.

c) (3 p) Skriv plottekoden og beskriv figuren.

✏️Modellbesvarelse del (a) og (b): høyresiden og de tre kallene

Del (a), 4 poeng: skriv f(t, u). Del (b), 3 poeng: løs systemet og pakk ut komponentene.

Gå gjennom oppskriften. Fire tilstandsvariabler gir fire likninger, fire komponenter i u og fire kolonner i svaret. Parametrene settes som variabler over funksjonen — løseren kaller f med bare to argumenter, så de kan ikke sendes inn.

Legg merke til navnet N_tot på befolkningsstørrelsen. Bokstaven N er allerede opptatt av antall skritt i solve, og de to må ikke blandes.

N_tot = 50000
beta = 0.45
sigma = 0.2
gamma = 0.14

def f(t, u):
    S, E, I, D = u
    dS = -beta*S*I/N_tot
    dE = beta*S*I/N_tot - sigma*E
    dI = sigma*E - gamma*I
    dD = gamma*I
    return [dS, dE, dI, dD]

print(f(0, [49980, 20, 0, 0]))

Utskrift:

[-0.0, -4.0, 4.0, 0.0]

Kontrollen ved t=0t = 0 er verdt de ti sekundene den tar. Med I=0I = 0 smittes ingen ennå, så den første komponenten er null. De 20 eksponerte blir smittsomme med rate σ=0,2\sigma = 0{,}2, altså 4 personer per døgn — derfor 4-4 i den andre komponenten og +4+4 i den tredje. Og ingen har gjennomgått sykdommen ennå, så den fjerde er null.

Del (b). De tre kallene, og deretter utpakkingen. For et system er u todimensjonalt: rad n er tilstanden ved tidspunkt n, kolonne k er komponent nummer k.

import numpy as np
from ODESolver import RungeKutta4

N_tot = 50000
beta = 0.45
sigma = 0.2
gamma = 0.14

def f(t, u):
    S, E, I, D = u
    return [-beta*S*I/N_tot, beta*S*I/N_tot - sigma*E, sigma*E - gamma*I, gamma*I]

solver = RungeKutta4(f)
solver.set_initial_condition([49980, 20, 0, 0])
t, u = solver.solve((0, 200), 2000)
S, E, I, D = u[:, 0], u[:, 1], u[:, 2], u[:, 3]

print('u.shape =', u.shape)
print(f'maks I = {I.max():.1f} paa dag {t[I.argmax()]:.1f}')
print(f'slutt: S = {S[-1]:.1f}  E = {E[-1]:.1f}  I = {I[-1]:.1f}  D = {D[-1]:.1f}')
print(f'sum = {S[-1]+E[-1]+I[-1]+D[-1]:.1f}')

Utskrift:

u.shape = (2001, 4)
maks I = 9339.2 paa dag 67.8
slutt: S = 2333.5  E = 0.0  I = 0.1  D = 47666.4
sum = 50000.0

Tre kontroller verdt å gjøre på eksamen. Formen er (2001, 4): 2000 skritt gir 2001 punkter, og fire kolonner fordi systemet har fire likninger. Summen av komponentene er 50 000 hele veien, som den skal være når ingen forsvinner ut av modellen. Og toppen i I kommer rundt dag 68.

Sensorkommentar del (a), steg for steg:

- Signaturen def f(t, u): med tiden først1 p. Dette er stedet API-forvekslingen (#14) slår til.
- Utpakkingen S, E, I, D = u som første linje — 1 p.
- De fire uttrykkene — 1 p. Bommer du på ett ledd, får du halve.
- return [dS, dE, dI, dD] som liste, i samme rekkefølge som utpakkingen — 1 p. Returnerer du et tall eller en tuppel av feil lengde, faller hele oppgaven.

Sensorkommentar del (b):

- RungeKutta4(f)1 p.
- set_initial_condition med én liste av fire startverdier — 1 p. Fire separate argumenter gir TypeError.
- solve((0, 200), 2000) med tuppelen som ett argument, og utpakkingen med u[:, k]1 p.

Hva som er godt nok. Skriver du de fire uttrykkene i egne variabler først, som i den øverste blokka, er det like riktig og lettere å lese. Bruker du ForwardEuler i stedet for RungeKutta4 fordi oppgaven ikke sier noe, mister du ingenting — men si i en kommentar hvorfor du valgte.

✏️Modellbesvarelse del (c): plottet, og figuren i ord

Del (c), 3 poeng: plott de fire kurvene i samme figur, med forklaring, og beskriv figuren.

Fire plot-kall med label=, ett legend(). Komponentene kan plottes direkte fra u uten å pakkes ut først:

import matplotlib.pyplot as plt
from ODESolver import RungeKutta4

N_tot = 50000
beta = 0.45
sigma = 0.2
gamma = 0.14

def f(t, u):
    S, E, I, D = u
    return [-beta*S*I/N_tot, beta*S*I/N_tot - sigma*E, sigma*E - gamma*I, gamma*I]

solver = RungeKutta4(f)
solver.set_initial_condition([49980, 20, 0, 0])
t, u = solver.solve((0, 200), 2000)

plt.plot(t, u[:, 0], label='S mottakelige')
plt.plot(t, u[:, 1], label='E eksponerte')
plt.plot(t, u[:, 2], label='I smittsomme')
plt.plot(t, u[:, 3], label='D gjennomgatt')
plt.xlabel('tid (dogn)')
plt.ylabel('antall personer')
plt.legend()
plt.show()
print(f'{len(t)} punkter')

Utskrift:

2001 punkter

Figuren i ord. Førsteaksen viser tid fra 0 til 200 døgn, andreaksen antall personer fra 0 til 50 000. Kurven for mottakelige starter øverst i nesten 50 000, ligger nesten flat de første tretti døgnene, faller deretter bratt gjennom dag 50 til 90, og flater ut rundt 2300. Kurven for eksponerte og kurven for smittsomme er begge klokkeformede: de starter nær null, vokser eksponentielt, og har topper på henholdsvis rundt 7420 (dag 62) og 9340 (dag 68) — der de eksponerte topper seg knapt seks døgn før de smittsomme, siden man må være eksponert før man blir smittsom. Kurven for gjennomgått stiger monotont fra null og flater ut rundt 47 700. Toppen i smittsomme ligger der kurven for mottakelige er brattest. Forklaringen navngir de fire kurvene.

Sensorkommentar del (c): fire plot-kall med riktige kolonner (1 p) · label= på alle fire pluss legend() (1 p) · aksenavn, show() og en figurbeskrivelse med topper og retning (1 p).

Den ene dyre feilen er å skrive plt.plot(t, u[0]) i stedet for plt.plot(t, u[:, 0]). Det første er hele tilstanden ved tidspunkt 0 — fire tall — og plottekallet feiler eller tegner noe meningsløst. Skriv utpakkingen én gang og bruk variabelnavnene etterpå, så unngår du det.

— naturlig pausepunkt —

Oppgaver: samme mønster, ny innpakning (~35 min for oppgave 1–5)

Alle oppgavene under er på eksamensnivå. Innpakningen roterer bevisst mellom biologi, mekanikk, fysiologi og meteorologi. Bruk oppskriftens sju steg på hver oppgave før du skriver en linje kode — det første spørsmålet er alltid «hvor mange tilstandsvariabler?».

📝Oppgave 1
Eksamensnivå, sjanger I
En bakteriekultur vokser logistisk:

u=ru(1uK),u(0)=20u' = ru\left(1 - \frac{u}{K}\right), \qquad u(0) = 20

med r=0,08r = 0{,}08 per time og K=500K = 500.

a) Skriv forward_euler(f, T, N, u0) fra bunnen. Den skal returnere t og u.

b) Løs på [0,60][0, 60] med 600 skritt. Skriv ut antall punkter, steglengden, startverdien, verdien etter 10 timer og sluttverdien.

c) Hvor mange punkter har løsningen, og hvorfor?

📝Oppgave 2
Eksamensnivå, sjanger J
En planet i bane rundt en stjerne beskrives av posisjonen (x,y)(x, y) og farten (vx,vy)(v_x, v_y). Med enheter der tyngdekonstanten og stjernens masse begge er 1, er likningene

x=vx,y=vy,vx=xr3,vy=yr3,r=x2+y2x' = v_x, \qquad y' = v_y, \qquad v_x' = -\frac{x}{r^3}, \qquad v_y' = -\frac{y}{r^3}, \qquad r = \sqrt{x^2+y^2}

Ved t=0t = 0 er planeten i (1,0)(1, 0) med farten (0,1)(0, 1). Da er banen en sirkel med omløpstid 2π2\pi.

a) Skriv høyresiden f(t, u) med fire komponenter.

b) Løs ett helt omløp med RungeKutta4 og 2000 skritt, og skriv ut formen på u, start- og sluttposisjon, og avstanden til stjernen ved slutten.

c) Hva er fornuftssjekken her, og hva ville det betydd om avstanden ikke var 1?

📝Oppgave 3
Eksamensnivå, sjanger J
Fitzhugh–Nagumo-modellen beskriver hvordan en nervecelle fyrer:

v=vv33w+I,w=v+abwτv' = v - \frac{v^3}{3} - w + I, \qquad w' = \frac{v + a - bw}{\tau}

der vv er membranpotensialet, ww er en tilbakestillingsvariabel, og a=0,7a = 0{,}7, b=0,8b = 0{,}8, τ=12,5\tau = 12{,}5 og I=0,5I = 0{,}5 er den ytre strømmen.

a) Skriv høyresiden f(t, u).

b) Løs på [0,200][0, 200] med 4000 skritt fra v(0)=1v(0) = -1, w(0)=0,5w(0) = -0{,}5, og skriv ut formen på u samt største og minste verdi av begge komponentene.

c) Hvorfor kan ikke parameteren II sendes inn som et tredje argument til f, og hva er de to lovlige måtene å håndtere den på?

📝Oppgave 4
Eksamensnivå, sjanger K
Midtpunktsmetoden tar først et halvt prøvesteg og bruker stigningstallet der for hele skrittet:

k1=f(tn,un),k2=f ⁣(tn+Δt2, un+Δt2k1),un+1=un+Δtk2k_1 = f(t_n, u_n), \qquad k_2 = f\!\left(t_n + \frac{\Delta t}{2},\ u_n + \frac{\Delta t}{2}k_1\right), \qquad u_{n+1} = u_n + \Delta t\,k_2

a) Skriv subklassen Midtpunkt(ODESolver) med kun advance.

b) Sammenlign den med ForwardEuleru=0,4uu' = -0{,}4u, u(0)=5u(0) = 5, over [0,5][0, 5] med bare 10 skritt. Den eksakte løsningen er u(t)=5e0,4tu(t) = 5e^{-0{,}4t}.

c) Hvorfor skal du bare skrive advance, og ikke hele klassen?

📝Oppgave 5
Eksamensnivå, sjanger K
En metallplate kjøles svært raskt mot omgivelsene:

u=25(u4),u(0)=30u' = -25(u - 4), \qquad u(0) = 30

Problemet er stivt: forlengs Euler krever ekstremt små skritt for å holde seg i ro.

a) Skriv subklassen BaklengsEuler(ODESolver). Hvert skritt løser likningen vunΔtf(tn+1,v)=0v - u_n - \Delta t\,f(t_{n+1}, v) = 0 for den nye verdien vv, med root fra scipy.optimize.

b) Sammenlign med ForwardEuler over [0,2][0, 2] med bare 10 skritt. Den eksakte løsningen er u(t)=4+26e25tu(t) = 4 + 26e^{-25t}.

c) Hvorfor må tiden i likningen være tn+1t_{n+1} og ikke tnt_n?

Oppgave 6–10: sporing, feilsøking og de fulle settoppgavene (~35 min)

— naturlig pausepunkt —

De neste fem oppgavene dekker de øvrige formene ODE-stoffet tar på et sett: en sporingsoppgave fra flervalgsskallet, en «hvilken linje mangler», en «finn feilen», en påstandstabell, og en full tipoengsoppgave.

📝Oppgave 6

(Midtveisnivå, sjanger A — kodesporing, altså «hva skriver dette programmet ut?».) Hva skriver programmet ut? NumPy skriver tabeller uten komma. Løseren er den utleverte ForwardEuler.

import numpy as np
from ODESolver import ForwardEuler

def f(t, u):
    return t - u

solver = ForwardEuler(f)
solver.set_initial_condition(1.0)
t, u = solver.solve((0, 1), 4)
print(u)
print(len(t), t[1] - t[0])

📝Oppgave 7

(Midtveisnivå, sjanger E — «hvilken linje mangler?». Sjanger E er flervalgstypen der ett kall eller én linje er fjernet fra et ellers riktig program.) Programmet skal løse et system med to likninger. Én linje er fjernet.

from ODESolver import RungeKutta4

def f(t, u):
    x, y = u
    return [y, -4*x]

solver = RungeKutta4(f)
# HER MANGLER ÉN LINJE
t, u = solver.solve((0, 10), 500)
x, y = u[:, 0], u[:, 1]

Hvilken linje hører på plassen?

a) solver.u0 = [1.0, 0.0]
b) solver.set_initial_condition(1.0, 0.0)
c) solver.set_initial_condition([1.0, 0.0])
d) solver.solve([1.0, 0.0])

📝Oppgave 8
Eksamensnivå, sjanger O

Programmet skal løse rovdyr–byttedyr-systemet x=0,4x0,02xyx' = 0{,}4x - 0{,}02xy, y=0,01xy0,3yy' = 0{,}01xy - 0{,}3y fra (40,9)(40, 9) over [0,60][0, 60] med 1200 skritt, og plotte begge bestandene. Det har fire feil.

from ODESolver import RungeKutta4
import matplotlib.pyplot as plt

def f(u, t):
    x, y = u
    return 0.4*x - 0.02*x*y, 0.01*x*y - 0.3*y

solver = RungeKutta4(f)
solver.set_initial_condition(40, 9)
t, u = solver.solve((0, 60), 1200)
plt.plot(t, u[0])
plt.plot(t, u[1])
plt.show()

a) Nevn de fire feilene og si hva hver av dem fører til.

b) Skriv den rettede koden.

📝Oppgave 9

(Midtveisnivå, sjanger D — «hvilke av påstandene er riktige?». Sjanger D er matche-typen der du avgjør om hver påstand holder.) Et system med tre likninger løses med t, u = solver.solve((0, 20), 400).

Avgjør for hver påstand om den er riktig eller gal.

RadPåstand
1t har 401 elementer
2u har formen (401, 3)
3u[:, 1] er komponent nummer 1 gjennom hele tiden
4u[5] er komponent nummer 5 gjennom hele tiden
5Steglengden er 0,05
6solve kan kalles uten set_initial_condition først

📝Oppgave 10
Eksamensnivå, sjanger J
Lorenz-systemet er en sterkt forenklet værmodell:

x=σ(yx),y=x(ρz)y,z=xyβzx' = \sigma(y - x), \qquad y' = x(\rho - z) - y, \qquad z' = xy - \beta z

med σ=10\sigma = 10, ρ=28\rho = 28 og β=8/3\beta = 8/3.

a) (4 p) Skriv høyresiden f(t, u).

b) (3 p) Løs på [0,30][0, 30] med 6000 skritt fra (1,1,1)(1, 1, 1) med RungeKutta4. Skriv ut formen på u og ytterverdiene for xx og zz.

c) (2 p) Kjør på nytt med startverdien x(0)=1,000001x(0) = 1{,}000001 og sammenlign sluttverdien for xx.

d) (1 p) Hva forteller resultatet i c) om værvarsling?

API- og konstruksjonsliste

Begrepsbank

Begrepsbanken er flashcard-/repetisjonsstoff — den gjentar det du nettopp har lest. Hopp trygt over ved førstegangslesing; tidsanslaget for kapitlet gjelder kjernestoffet.

Sjanger J

ODE-system løst med det utleverte hierarkiet. Står i 8 av 8 gjennomgåtte avsluttende sett og teller 9–10 poeng — den tyngste enkeltoppgaven på et typisk sett. Innpakningen roterer mellom epidemi, populasjonsdynamikk, mekanikk, nervecelle og vær; kodemønsteret er identisk.

Sjanger I og K

Sjanger I er å skrive ODE-løseren selv som en funksjon, typisk forlengs Euler, og teller 5 poeng. Sjanger K er å lage en subklasse av ODESolver der du bare skriver advance, og teller 3–5 poeng. Signalordene i oppgaveteksten er «skriv en funksjon som løser» for I og «utvid hierarkiet» for K.

Steg 1 — tell tilstandsvariablene

Antall størrelser som endrer seg over tid er antall likninger, antall komponenter i u, antall elementer i startlista og antall kolonner i svaret. Alt henger sammen, og tellingen gjøres én gang før du skriver noe.

Steg 2 — høyresiden
def f(t, u): med tiden først, utpakking som første linje, én linje per derivert, og return som liste i samme rekkefølge som utpakkingen. Argumentet t skal stå der selv om modellen ikke bruker det.
Steg 3 — hvor parametrene bor

Løseren kaller f med nøyaktig to argumenter, så parametrene kan ikke sendes inn. De to lovlige måtene er variabler over funksjonen, eller en klasse med __init__ som lagrer dem og __call__(self, t, u) som regner.

De tre kallene
RungeKutta4(f), set_initial_condition(u0), solve(t_span, N). Rekkefølgen er fast, t_span er én tuppel, og set_initial_condition tar ett argument — en liste for et system.
`u[:, k]` mot `u[k]`
u[:, k] er komponent k gjennom hele tiden, altså kurven du plotter. u[k] er hele tilstanden ved tidspunkt k, altså like mange tall som systemet har likninger. Å blande dem er den vanligste feilen i sjanger J, og den gir en figur som ser tom ut.
Skritt mot punkter i en ODE
solve((0, T), N) gir N skritt og N+1 punkter, og u.shape er (N+1, antall likninger). Samme telling gjelder i din egen løser: np.linspace(0, T, N+1) og range(N).
API-driften (#14)

Bokstandard er f(t, u) og solve((0, T), N). I eldre sett var det f(u, t) og solve(time_points). Feil argumentrekkefølge gir ofte ingen feilmelding, fordi mange høyresider ikke bruker t — les vedlegget hvert år.

Subklasse-malen

Klasselinja class Ny(ODESolver):, def advance(self): uten andre argumenter, hentelinja med korte lokale navn, og formelen med return. Basisklassen gjør tilordningen til self.u selv — advance skal bare returnere neste verdi.

Implisitt metode med nullpunktsløser

Baklengs Euler bruker stigningstallet ved punktet du skal til, altså f(tn+1,un+1)f(t_{n+1}, u_{n+1}). Siden un+1u_{n+1} er den ukjente, defineres en indre funksjon som er null i løsningen, og root løser den med forrige verdi som startgjetning. Svaret ligger i sol.x, som alltid er et array.

Fornuftssjekker uten fasit

Summen av komponentene i en lukket modell skal være konstant. En sirkelbane skal ha konstant radius. En løsning som skal dø ut, skal nærme seg null. Slike sjekker er alt du har på en hjelpemiddelfri eksamen, og det er verdt et poeng å nevne dem.

Repetisjon: oppskriften på ett kort

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.

Skolesaga er en uavhengig læringsressurs og er ikke tilknyttet eller godkjent av Universitetet i Oslo. Dette er ikke offisielt studiemateriell. Les mer.