Tilbake
6.1

6.1 Numerisk derivasjon, integrasjon og nullpunkt

De korte numeriske byggeoppgavene: forlengs/sentrert differanse, trapesmetoden, og nullpunkt med Newton/secant + `scipy.optimize.root`.

55 min
9 oppgaver
Numerisk derivasjonintegrasjonnullpunkt
Din fremgang i kapitlet
0 / 9 oppgaver

Sist du var her

Del 6 kommer et godt stykke inn i boka, så her er de tre tingene fra tidligere kapitler som dette kapitlet bygger rett på — friskt oppfrisket med kode.

1) En funksjon kan sendes inn som argument (kap. 1.6). Alle metodene i kapitlet tar funksjonen som skal behandles, som argument:

from math import sin

def verdi_i(f, x):
    return f(x)

print(verdi_i(sin, 0.0))
print(verdi_i(lambda x: x**2 - 2, 3.0))

Utskrift:

0.0
7.0

2) Default-argumenter (kap. 1.6). Steglengden får en fornuftig standardverdi, slik at den kan utelates i kallet:

def demo(x, h=1e-5):
    return x + h

print(demo(1.0))
print(demo(1.0, 0.5))

Utskrift:

1.00001
1.5

3) Testfunksjonen med toleranse (kap. 3.1). Aldri == på flyttall — alltid abs(...) < tol:

def test_kvadrat():
    expected = 4.0
    computed = 2.0**2
    tol = 1e-10
    assert abs(expected - computed) < tol, 'kvadrering feiler'

test_kvadrat()
print('testen passerte')

Utskrift:

testen passerte

Forkunnskaper

- Funksjoner, default-argumenter og lambda: kap. 1.6.
- Løkker og while: kap. 1.3.
- NumPy-tabeller: kap. 4.1.
- Testfunksjoner: kap. 3.1.
- Klasser med __init__ og __call__: kap. 5.1, til den ene varianten der den deriverte pakkes i en klasse.

Matematikken bak metodene er ikke pensum her, men den ligger tilgjengelig hvis du vil se hvor formlene kommer fra: grensedefinisjonen av den deriverte i Deriverbarhet: grensedefinisjonen, summen bak trapesmetoden i Riemann-integralet og integrerbarhet, og Newtons metode i flere variable i Kontraksjon, fikspunkt og Newtons metode i flere variable. En mykere innføring på lavere nivå finnes i Numeriske metoder og programmering og Programmering av integrasjon.

Kapitlet er delt i tre løkker med tidsanslag.

Løkke 1 — den deriverte som differanse (~20 min)

En bevegelsessensor logger posisjonen til en isbre hver dag. Du vil vite hvor fort breen beveger seg, altså den deriverte av posisjonen — men du har bare tall, ingen formel å derivere.

Løsningen er den samme som definisjonen av den deriverte, bare uten grenseovergangen: regn stigningen mellom to punkter som ligger tett. Det gir to formler, og forskjellen mellom dem er hele poenget i dette delkapitlet.

Den deriverte i punktet xx er

f(x)=limh0f(x+h)f(x)hf'(x) = \lim_{h \to 0} \frac{f(x+h) - f(x)}{h}

Setter vi inn en liten, men endelig hh, får vi den forlengs differansen. Bruker vi i stedet punkter på hver side av xx, får vi den sentrerte differansen — og den er langt mer nøyaktig, som tallene straks skal vise.

Forlengs differanse
Tilnærmingen

f(x)f(x+h)f(x)hf'(x) \approx \frac{f(x+h) - f(x)}{h}

med en liten, fast hh. Nevneren er h, og de to funksjonsverdiene er i x og x+h. Feilen er omtrent proporsjonal med hh: halverer du hh, halveres feilen. Metoden kalles førsteordens av samme grunn.

from math import sin, cos, pi

h = 1e-4
x = pi/3
print((sin(x+h) - sin(x))/h)
print(cos(x))

Utskrift:

0.4999566978958203
0.5000000000000001
Sentrert differanse
Tilnærmingen

f(x)f(x+h)f(xh)2hf'(x) \approx \frac{f(x+h) - f(x-h)}{2h}

med funksjonsverdier på hver side av xx. Nevneren er 2h2h, ikke hh — det er den vanligste feilen i formelen. Feilen er omtrent proporsjonal med h2h^2: tideler du hh, blir feilen hundre ganger mindre. Metoden er andreordens, og den er derfor standardvalget i faget når oppgaven ikke sier noe annet.

from math import sin, cos, pi

h = 1e-4
x = pi/3
print((sin(x+h) - sin(x-h))/(2*h))
print(cos(x))

Utskrift:

0.49999999916616744
0.5000000000000001
✏️Eksempel 1: hvor god er tilnærmingen? En konvergenstabell

Bruk begge formlene på f(x)=sinxf(x) = \sin x i punktet x=π/3x = \pi/3, der den eksakte deriverte er cos(π/3)=0,5\cos(\pi/3) = 0{,}5. Regn ut feilen for h=101,102,,106h = 10^{-1}, 10^{-2}, \ldots, 10^{-6}, og vis hvor mange ganger mindre feilen blir for hvert steg.


Et numerisk resultat uten sammenligning er halvt arbeid. Her har vi det eksakte svaret, så vi kan regne ut feilen direkte — og faktoren mellom radene forteller hvilken orden metoden har.

from math import sin, cos, pi

x = pi/3
eksakt = cos(x)

print('       h     forlengs         feil    faktor')
forrige = 0.0
for k in range(1, 7):
    h = 10.0**(-k)
    d = (sin(x+h) - sin(x))/h
    feil = abs(d - eksakt)
    faktor = forrige/feil if forrige > 0 else 0.0
    print(f'{h:8.0e} {d:12.8f} {feil:12.2e} {faktor:9.1f}')
    forrige = feil

Utskrift:

       h     forlengs         feil    faktor
   1e-01   0.45590189     4.41e-02       0.0
   1e-02   0.49566158     4.34e-03      10.2
   1e-03   0.49956690     4.33e-04      10.0
   1e-04   0.49995670     4.33e-05      10.0
   1e-05   0.49999567     4.33e-06      10.0
   1e-06   0.49999957     4.33e-07      10.0

Faktoren er 10 hele veien: feilen skrumper like mye som h. Det er signaturen til en førsteordens metode.

Nå den sentrerte:

from math import sin, cos, pi

x = pi/3
eksakt = cos(x)

print('       h     sentrert         feil    faktor')
forrige = 0.0
for k in range(1, 7):
    h = 10.0**(-k)
    d = (sin(x+h) - sin(x-h))/(2*h)
    feil = abs(d - eksakt)
    faktor = forrige/feil if forrige > 0 else 0.0
    print(f'{h:8.0e} {d:12.8f} {feil:12.2e} {faktor:9.1f}')
    forrige = feil

Utskrift:

       h     sentrert         feil    faktor
   1e-01   0.49916708     8.33e-04       0.0
   1e-02   0.49999167     8.33e-06     100.0
   1e-03   0.49999992     8.33e-08     100.0
   1e-04   0.50000000     8.34e-10      99.9
   1e-05   0.50000000     7.83e-12     106.5
   1e-06   0.50000000     4.11e-11       0.2

Faktoren er nær 100 for de første radene: feilen skrumper som h2h^2. Med h=103h = 10^{-3} er den sentrerte formelen alt fem tierpotenser bedre enn den forlengse.

Men se på siste rad: faktoren faller til 0,2, altså feilen vokser når hh blir for liten. Det er ikke en trykkfeil, og det er ingen feil i koden — det er avrundingsfeil i flyttallene. Når f(x+h)f(x+h) og f(xh)f(x-h) er nesten like, mister differansen mellom dem gyldige siffer, og til slutt dominerer den effekten. Derfor er h = 1e-5 bokas standardvalg: liten nok til å være nøyaktig, stor nok til at avrundingen ikke tar over.

`diff(f, x, h=1e-5)`

Bokas standardform for den numeriske deriverte som funksjon: den tar funksjonen f som argument, punktet x, og en steglengde med standardverdi. Kroppen er én linje med den sentrerte formelen, og funksjonen returnerer ett tall.

from math import sin, pi

def diff(f, x, h=1e-5):
    return (f(x+h) - f(x-h))/(2*h)

print(diff(sin, pi/3))
print(diff(lambda x: x**3, 2.0))

Utskrift:

0.4999999999921733
12.00000000021184

📝Oppgave 1

(Innstegsoppgave, sjanger N — numerisk byggeoppgave.) Funksjonen f(x)=x2f(x) = x^2 har den eksakte deriverte f(x)=2xf'(x) = 2x.

a) Skriv diff(f, x, h=1e-5) med sentrert differanse.

b) Hva blir diff(f, 3.0) omtrent, og hva er det eksakte svaret?

c) Hvorfor er svaret i b) nesten, men ikke helt, eksakt?

Den deriverte som klasse

Samme formel pakket i en klasse, slik at instansen selv blir en funksjon: __init__ husker funksjonen og steglengden, og __call__ regner ut den deriverte i et punkt. Klasseapparatet står i kap. 5.1; her er poenget bare at eksamen har brukt begge formene, og at de gir samme tall.

En instans er ett konkret objekt laget av klassen, og en instans er kallbar når den kan brukes med parenteser som en funksjon — det er __call__ som gjør den kallbar.

from math import sin, pi

class Diff:
    def __init__(self, f, h=1e-5):
        self.f = f
        self.h = h

    def __call__(self, x):
        f, h = self.f, self.h
        return (f(x+h) - f(x-h))/(2*h)

dsin = Diff(sin)
print(dsin(pi/3))

Utskrift:

0.4999999999921733

📝Oppgave 2
Eksamensnivå, sjanger N…

Skriv diff(f, x, h=1e-5) med sentrert differanse, og en testfunksjon som kontrollerer den mot en funksjon du kjenner den eksakte deriverte til. Bruk toleransen 10610^{-6}.

Løkke 2 — trapesmetoden (~12 min)

— naturlig pausepunkt —

Motstykket til å derivere numerisk er å integrere numerisk: å regne ut arealet under en kurve når du bare har funksjonsverdier. Trapesmetoden deler intervallet i NN biter og erstatter kurven med en rett linje over hver bit, slik at hvert stykke blir et trapes.

Dette er lavfrekvent stoff (1 av 8 sett, 13 %), og da nesten bare som et flervalgsspørsmål om hva et kall gjør. Delkapitlet er derfor kort: én formel, én konvergenstabell, én oppgave.

Trapesmetoden
Tilnærmingen

abf(x)dxΔx(f(a)2+f(b)2+k=1N1f(a+kΔx)),Δx=baN\int_a^b f(x)\,dx \approx \Delta x\left(\frac{f(a)}{2} + \frac{f(b)}{2} + \sum_{k=1}^{N-1} f(a + k\,\Delta x)\right), \qquad \Delta x = \frac{b-a}{N}

Endepunktene teller halvt, alle de indre punktene teller helt. Legg merke til grensene i summen: range(1, N) — den går fra 1 til N1N-1, altså bare de indre punktene. Feilen er proporsjonal med Δx2\Delta x^2, så en dobling av NN firedobler nøyaktigheten.

def trapes(f, a, b, N):
    dx = (b - a)/N
    s = 0.5*f(a) + 0.5*f(b)
    for k in range(1, N):
        s += f(a + k*dx)
    return s*dx

print(trapes(lambda x: x**2, 0.0, 1.0, 10))

Utskrift:

0.3350000000000001
✏️Eksempel 2: konvergens mot det eksakte integralet

Regn ut 01x2dx\int_0^1 x^2\,dx med trapesmetoden for N=5,10,20,40,80N = 5, 10, 20, 40, 80. Det eksakte svaret er 1/31/3. Vis feilen og faktoren mellom radene.


Her kjenner vi svaret eksakt, så feilen kan regnes ut direkte.

def trapes(f, a, b, N):
    dx = (b - a)/N
    s = 0.5*f(a) + 0.5*f(b)
    for k in range(1, N):
        s += f(a + k*dx)
    return s*dx

eksakt = 1/3
print('   N       trapes          feil   faktor')
forrige = 0.0
for N in [5, 10, 20, 40, 80]:
    T = trapes(lambda x: x**2, 0.0, 1.0, N)
    feil = abs(T - eksakt)
    faktor = forrige/feil if forrige > 0 else 0.0
    print(f'{N:4d} {T:12.10f} {feil:12.3e} {faktor:8.2f}')
    forrige = feil

Utskrift:

   N       trapes          feil   faktor
   5 0.3400000000    6.667e-03     0.00
  10 0.3350000000    1.667e-03     4.00
  20 0.3337500000    4.167e-04     4.00
  40 0.3334375000    1.042e-04     4.00
  80 0.3333593750    2.604e-05     4.00

Faktoren er nøyaktig 4,00 for hver dobling av NN: feilen skrumper som Δx2\Delta x^2. Det er slik du viser at en metode er andreordens uten å bevise noe — du dobler oppløsningen og ser at feilen firedeles.

Legg også merke til at alle tilnærmingene ligger over det eksakte svaret. Det er fordi x2x^2 krummer oppover, så et rett linjestykke mellom to punkter på kurven ligger over kurven, og trapeset blir litt for stort.

📝Oppgave 3
Eksamensnivå, sjanger N

Trapesmetoden skal brukes på 0πsinxdx\int_0^{\pi} \sin x\,dx, der det eksakte svaret er 2.

a) Skriv trapes(f, a, b, N).

b) Hva blir tilnærmingen for N=10N = 10 og N=20N = 20, og hvor stor er feilen i hvert tilfelle?

c) Stemmer faktoren mellom de to feilene med at metoden er andreordens?

Løkke 3 — finne nullpunkt (~23 min)

Nå til nivå 3-stoffet, det som skiller de beste besvarelsene. Oppgaven er: gitt en funksjon ff, finn et xx slik at f(x)=0f(x) = 0.

Slike likninger dukker opp overalt i vitenskapelig programmering. Skal du finne likevektstemperaturen i en varmemodell, tidspunktet der to bestander er like store, eller den implisitte oppdateringen i baklengs Euler (kap. 7.4), er svaret et nullpunkt i en funksjon du ikke kan løse for hånd.

Tre verktøy dekker alt eksamen har spurt om: Newtons metode (krever den deriverte), sekantmetoden (krever den ikke), og root fra scipy.optimize (biblioteksfunksjonen, som dessuten takler systemer med flere ukjente).

Newtons metode
Gjentatt forbedring av en gjetning ved å følge tangenten ned til nullnivået:

xny=xf(x)f(x)x_{\text{ny}} = x - \frac{f(x)}{f'(x)}

Løkka kjører til funksjonsverdien er liten nok: while abs(f(x)) > eps:. Metoden er svært rask når startgjetningen er brukbar — antall riktige siffer omtrent dobles per runde. Den krever at du kan gi den deriverte som en egen funksjon, og den kan bomme helt hvis f(x)f'(x) er nær null.

def newton(f, df, x, eps=1e-12):
    while abs(f(x)) > eps:
        x = x - f(x)/df(x)
    return x

print(newton(lambda x: x**2 - 2, lambda x: 2*x, 1.0))

Utskrift:

1.4142135623730951
✏️Eksempel 3: Newtons metode mot det eksakte svaret

Finn den positive løsningen av x22=0x^2 - 2 = 0 med Newtons metode fra x0=1x_0 = 1. Skriv ut hver runde, og sammenlign med sqrt(2) fra math.


Her kjenner vi svaret: 2\sqrt{2}. Da kan vi se hvordan feilen utvikler seg fra runde til runde.

from math import sqrt

def f(x):
    return x**2 - 2

def df(x):
    return 2*x

x = 1.0
n = 0
print('runde                 x            feil')
while abs(f(x)) > 1e-12:
    x = x - f(x)/df(x)
    n += 1
    print(f'{n:5d} {x:17.15f} {abs(x - sqrt(2)):15.3e}')

print('sqrt(2) fra math:', sqrt(2))

Utskrift:

runde                 x            feil
    1 1.500000000000000       8.579e-02
    2 1.416666666666667       2.453e-03
    3 1.414215686274510       2.124e-06
    4 1.414213562374690       1.595e-12
    5 1.414213562373095       0.000e+00
sqrt(2) fra math: 1.4142135623730951

Se på feilkolonnen: 91029 \cdot 10^{-2}, 21032 \cdot 10^{-3}, 21062 \cdot 10^{-6}, 210122 \cdot 10^{-12}. Antall riktige siffer dobles for hver runde — det kalles kvadratisk konvergens, og det er derfor Newtons metode trenger så få runder. Etter fem runder er svaret identisk med sqrt(2) til siste siffer.

Sammenlign med trapesmetoden, der en dobling av arbeidet ga fire ganger bedre svar. Her gir én ekstra runde kvadratet av forbedringen. Det er en helt annen skala.

Sekantmetoden
Newtons metode uten den deriverte: erstatt tangenten med linjen gjennom de to siste punktene.

xny=x1f(x1)x1x0f(x1)f(x0)x_{\text{ny}} = x_1 - f(x_1)\,\frac{x_1 - x_0}{f(x_1) - f(x_0)}

Metoden trenger to startverdier og ingen derivert, og den er nesten like rask som Newton. Legg merke til at oppdateringen bare bruker de to siste verdiene — dette er samme mønster som en differenslikning (kap. 6.2), og det løses med en løkke som skyver verdiene videre.

def sekant(f, x0, x1, eps=1e-12, maks=100):
    n = 0
    while abs(f(x1)) > eps and n < maks:
        x_ny = x1 - f(x1)*(x1 - x0)/(f(x1) - f(x0))
        x0, x1 = x1, x_ny
        n += 1
    return x1

print(sekant(lambda x: x**2 - 2, 1.0, 2.0))

Utskrift:

1.4142135623730954
📝Oppgave 4
Eksamensnivå, sjanger N

Sekantmetoden skal brukes på f(x)=x22f(x) = x^2 - 2 med startverdiene x0=1x_0 = 1 og x1=2x_1 = 2.

a) Skriv sekant(f, x0, x1, eps=1e-12, maks=100).

b) Skriv ut hver runde med feilen mot sqrt(2), og si hvor mange runder som trengs.

c) Hvilken fordel har sekantmetoden framfor Newtons metode, og hvilken ulempe?

`root` fra `scipy.optimize`

Biblioteksfunksjonen som løser f(x)=0f(x) = 0, også når xx har flere komponenter. Tre ting må sitte:

- fun tar ett array-argument og returnerer ett array — én komponent per likning.
- Startgjetningen x0 er også et array.
- Løsningen ligger i sol.x, som er et array. sol.success sier om metoden lyktes.

Dokumentasjonen for root leveres alltid som vedlegg på eksamen, så du trenger ikke pugge signaturen — men du må kunne pakke funksjonen din riktig, altså array inn og array ut. Det er nettopp det oppgavene tester.

import numpy as np
from scipy.optimize import root

def fun(x):
    return np.array([x[0]**2 - 2])

sol = root(fun, np.array([1.0]))
print(sol.x, sol.success)

Utskrift:

[1.41421356] True

📝Oppgave 5
Eksamensnivå, sjanger…

To bestander utvikler seg slik at antallet er B(t)=80e0,3tB(t) = 80e^{-0{,}3t} og R(t)=5+2tR(t) = 5 + 2t. Du skal finne tidspunktet der de to er like store.

a) Sett opp funksjonen som skal ha nullpunkt.

b) Løs likningen med root, med startgjetning t0=5t_0 = 5.

c) Kontroller svaret ved å regne ut begge bestandene i det tidspunktet du fant.

📝Oppgave 6
Eksamensnivå, sjanger O

Programmet skal finne nullpunktet til f(x)=x35f(x) = x^3 - 5 med Newtons metode. Finn de tre feilene, og forklar hva hver av dem fører til.

import sqrt from math

def f(x):
    return x**3 - 5

def df(x):
    return 3*x

x = 1.0
while abs(f(x)) > 1e-16:
    x = x + f(x)/df(x)
print(x)

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 N

Eksamensoppgaven «skriv en kort funksjon som regner ut noe tilnærmet, og bruk den»: numerisk derivert, integral eller nullpunkt. Vekten er 2 til 8 poeng. Derivasjon er i 4 av 8 sett (50 %), nullpunkt i 3 av 8 (38 %, voksende), og integrasjon i 1 av 8 (13 %).

Førsteordens og andreordens metode

En førsteordens metode har feil omtrent proporsjonal med steglengden: halverer du steget, halveres feilen. En andreordens metode har feil proporsjonal med steget i annen: halverer du steget, blir feilen en firedel. Forlengs differanse er førsteordens, sentrert differanse og trapesmetoden er andreordens.

Konvergenstabell

Standardmåten å vise at en metode virker: kjør den for flere steglengder, regn feilen mot det eksakte svaret, og se på faktoren mellom radene. Faktor 10 per tideling av hh betyr førsteordens, faktor 100 betyr andreordens. Har du ikke noe eksakt svar, halverer du steget og viser at svaret slutter å endre seg i de sifrene du bryr deg om.

Avrundingsgrensen for h

Feilen i en differanseformel synker med h bare til et punkt. Når f(x+h) og f(x-h) blir nesten like, mister differansen gyldige siffer, og feilen begynner å vokse igjen. For sentrert differanse ligger vendepunktet rundt h=106h = 10^{-6}, og derfor er h = 1e-5 bokas standardvalg.

Default-argumentet `h=1e-5`

Standardverdien gjør at diff(f, x) kan kalles uten å oppgi steglengden, men at diff(f, x, 1e-3) fortsatt virker. Default-argumenter står etter de vanlige argumentene i signaturen. Merk feil #21 i feilkatalogen: en default-verdi må ikke være en liste eller annen muterbar verdi.

Trapesmetodens vekter

Endepunktene teller halvt, alle indre punkter helt, og hele summen ganges med Δx\Delta x. I kode: s = 0.5*f(a) + 0.5*f(b), deretter for k in range(1, N): s += f(a + k*dx), til slutt return s*dx. Grensen range(1, N) treffer nøyaktig de indre punktene.

Newtons metode
x = x - f(x)/df(x), gjentatt til abs(f(x)) er under en toleranse. Krever den deriverte som egen funksjon, og konvergerer kvadratisk: antall riktige siffer dobles per runde. Feilen som ødelegger den er pluss i stedet for minus, eller manglende grense på antall runder.
Sekantmetoden

Newton uten derivert: linjen gjennom de to siste punktene brukes i stedet for tangenten. Trenger to startverdier, og oppdateringen er x1 - f(x1)*(x1 - x0)/(f(x1) - f(x0)). De to verdiene skyves videre med x0, x1 = x1, x_ny. Nesten like rask som Newton, og uunnværlig når den deriverte ikke finnes på formel.

Stoppkriterium
while abs(f(x)) > eps sammen med en teller og en grense n < maks. Toleransen eps bør ligge mellom 101010^{-10} og 101210^{-12}: er den strammere, kan avrunding gjøre at den aldri nås, og løkka går evig. Grensen på antall runder er billig forsikring, og den nevnes eksplisitt i løsningsforslag.
`root` — array inn, array ut
fun tar ett array-argument og returnerer ett array med én komponent per likning; x0 er også et array. sol = root(fun, x0) gir løsningen i sol.x (et array) og statusen i sol.success. Ett tall hentes med sol.x[0]. Dokumentasjonen leveres på eksamen, men innpakningen må du kunne selv.
Nullpunkt for «når er to størrelser like»

Skal du finne når A(t)=B(t)A(t) = B(t), setter du opp differansen g(t)=A(t)B(t)g(t) = A(t) - B(t) og finner nullpunktet til gg. Alle tre metodene i kapitlet gjør det samme med gg; det eneste du gjør, er å sette opp differansen riktig.

Kontrollregning etter en numerisk løsning

Sett løsningen tilbake i den opprinnelige likningen og se om venstre side blir null (eller at de to størrelsene blir like). Dette er den eneste måten å oppdage at en løser har konvergert mot et annet nullpunkt enn du var ute etter, og det gir poeng i seg selv i løsningsforslag.

Funksjon som argument

Alle metodene i kapitlet tar funksjonen som skal behandles, som argument: diff(f, x), trapes(f, a, b, N), newton(f, df, x). Da må du sende inn selve funksjonen (f, sin eller en lambda), ikke et funksjonskall og ikke et uttrykk. Å sende f(x) i stedet for f er å sende ett tall — en klassisk flervalgsfelle.

Toleransen i en testfunksjon skal passe metoden

En grov metode krever slakk toleranse. Sentrert differanse med h = 1e-5 treffer på rundt 101110^{-11}, så tol = 1e-6 er trygt. Forlengs differanse med samme h treffer bare på rundt 10510^{-5}, og da vil tol = 1e-6 få testen til å feile selv om koden er riktig.

Repetisjonsoppgaver
Din fremgang
0 / 3 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.

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