4.1 NumPy-arrays: oppretting, vektorisering og 2D
Arrays, elementvise operasjoner, `linspace`/`zeros`, og et kort dykk i 2D-arrays — verktøyet ODE- og differenslikning-oppgavene hviler på.
Kapitlet har prioritet kunne (nivå 2 av tre: må sitte, kunne, kjenne til). Det er ikke fordi NumPy er uviktig, men fordi NumPy sjelden er hele oppgaven — det er byggeklossen inni de store oppgavene:
- Lister mot NumPy-tabeller (sjanger M — «skriv samme tabell først med løkke, så uten løkke») er i 6 av de 8 nyere settene, altså 75 %, og er verdt rundt 5 poeng. Sjangeren drilles i kap. 4.2.
- Plotting er i 7 av 8 sett (88 %), nesten alltid som en del-b: «plott løsningen». Se kap. 4.3.
- Differenslikninger (75 %) og ODE-systemer (100 %) starter alltid med å lage en tabell med NumPy. Uten dette kapitlet stopper du på første linje i de tyngste oppgavene.
- Sporing av tabellkode hører til sjanger A — «hva skriver programmet ut?» — som er i alle sett (100 %) og bærer hele midtveiseksamen, den digitale flervalgseksamenen i oktober som teller 25 %.
- Tabeller med to indekser (2D) er bare i 2 av 8 sett (25 %) og har prioritet kjenne til. Det stoffet står sist i kapitlet og er merket.
Det er én feil du må trene bort her, og den er fagets aller vanligste: å bomme med én på antall punkter i en tabell.
Forkunnskaper
Du trenger tre ting fra Del 1:
- Lister, indeksering og slicing fra kap. 1.2 — hele dette kapitlet er en sammenligning mot lister. «Slicing» betyr å plukke ut et utsnitt, som x[1:3].
- Løkker og range fra kap. 1.3, særlig at stoppverdien i range er eksklusiv.
- Funksjoner fra kap. 1.6, fordi vi skal sende en hel tabell inn i en funksjon du selv har skrevet.
Har du aldri programmert før, er Programmering med Python en mykere inngang til løkker og lister enn dette kapitlet.
Kapitlet er delt i fire løkker med tidsanslag. Ta gjerne en pause mellom løkke 2 og 3.
Løkke 1 — fra liste til tabell (~12 min)
En værstasjon på Blindern måler temperaturen hver time. Med Python-lister lagrer du målingene som [2.1, 3.4, 3.0, 5.2, 4.8]. Skal du så trekke fra en kalibreringsfeil på 0,3 grader i alle fem, må du gå gjennom lista med en løkke og bygge en ny liste.
Med NumPy skriver du i stedet maal - 0.3 og er ferdig. Det er hele poenget: en NumPy-tabell er en rad av tall som regnes på under ett. Å regne på en hel tabell i én operasjon, uten løkke, kalles vektorisering.
Tabellen heter array på engelsk. Vi bruker ordet «array» også på norsk, siden det er ordet du ser i koden og i oppgaveteksten.
Standardlinjen som gjør NumPy tilgjengelig. as np gir biblioteket kallenavnet np, slik at du skriver np.zeros(5) og ikke numpy.zeros(5). Alle NumPy-navn i faget skrives med np.-prefiks, og linjen skal alltid stå øverst i kode som bruker arrays — sensor forventer at nødvendige importer er med.
import numpy as np
print(np.zeros(3))Utskrift:
[0. 0. 0.]Lager et array av en ferdig liste med tall. Lista må inneholde tall (eller nøstede lister av tall), og resultatet er en ny tabell med samme verdier i samme rekkefølge. Legg merke til at Python skriver et array uten komma mellom elementene — [2 4 6], ikke [2, 4, 6]. Det er den sikreste måten å kjenne igjen et array i en utskrift.
import numpy as np
tabell = np.array([2, 4, 6])
print(tabell)Utskrift:
[2 4 6]Tre timesmålinger av temperatur er lagret både som liste og som array. Hva skriver liste + liste, array + array, liste * 2 og array * 2 ut?
Nøkkelen er at
+ og * betyr noe helt annet for en liste enn for et array.import numpy as np
maal_liste = [2.1, 3.4, 3.0]
maal_array = np.array([2.1, 3.4, 3.0])
print(maal_liste + maal_liste)
print(maal_array + maal_array)
print(maal_liste * 2)
print(maal_array * 2)Utskrift:
[2.1, 3.4, 3.0, 2.1, 3.4, 3.0]
[4.2 6.8 6. ]
[2.1, 3.4, 3.0, 2.1, 3.4, 3.0]
[4.2 6.8 6. ]For lista betyr + skjøting: to lister etter hverandre, seks elementer. For arrayet betyr + elementvis addisjon: hvert element legges til seg selv, fortsatt tre elementer. Samme mønster for *: lista gjentas, arrayet skaleres.
Legg også merke til hvordan Python skriver de to: lista med komma, arrayet uten.
For to arrays med like mange elementer regner +, -, *, / og ** element for element. x + y gir et nytt array der element nummer i er x[i] + y[i]. Er den ene siden et vanlig tall, brukes tallet på hvert element: x * 2 dobler alle, x ** 2 kvadrerer alle. Ingen løkke trengs, og resultatet har samme lengde som det som gikk inn.
import numpy as np
x = np.array([1.0, 2.0, 3.0])
print(x ** 2 + x)Utskrift:
[ 2. 6. 12.]Dette er feil #5 i feilkatalogen — å forveksle liste-skjøting med array-addisjon. Den er plantet som svaralternativ i flervalgsspørsmål år etter år, fordi de to uttrykkene ser identiske ut i koden:
- [1, 2] + [3, 4] gir [1, 2, 3, 4] — fire elementer, ingen addisjon.
- np.array([1, 2]) + np.array([3, 4]) gir [4 6] — to elementer, addisjon.
Regelen er enkel: se etter np.array eller np.linspace i linjene over. Har variabelen blitt et array et sted, er + elementvis. Har den ikke det, er + skjøting. Og et array skrives ut uten komma — sjekk alltid hvilket av de to formatene svaralternativene har.
(Midtveisnivå, sjanger A — kodesporing, altså «hva skriver programmet ut?».) Skriv utskriften nøyaktig, med de mellomrommene og hakeparentesene Python bruker.
import numpy as np
a = [5, 10]
b = np.array([5, 10])
print(a + a)
print(b + b)To opplysninger du kan hente ut av et array uten parenteser, fordi de er egenskaper og ikke funksjoner. .size er antall tall i alt, som et helt tall. .shape er formen, gitt som en tuppel: (5,) for en tabell med fem tall på én rad, (3, 4) for tre rader og fire kolonner. Kommaet i (5,) er Pythons måte å skrive en tuppel med bare ett element.
import numpy as np
t = np.array([0.0, 0.5, 1.0, 1.5])
print(t.size, t.shape)Utskrift:
4 (4,)Løkke 2 — lage tabellen før du fyller den (~14 min)
I nesten alle senere oppgaver kjenner du antall verdier før du kjenner verdiene. Skal du simulere en bestand i 20 tidssteg, vet du at du trenger plass til startverdien pluss 20 nye verdier. Da lager du en tabell full av nuller først, og fyller den i en løkke.
Det er derfor np.zeros og np.linspace er de to viktigste NumPy-funksjonene i faget. Den første lager plass, den andre lager et jevnt punktgitter.
Her ligger også fagets vanligste feil, og den er verdt å si i klartekst før du ser koden: et intervall delt i N biter har N+1 delepunkter. Deler du strekningen fra 0 til 6 i 6 biter, er punktene 0, 1, 2, 3, 4, 5, 6 — det er sju tall, ikke seks.
Lager et array med n nuller, klart til å fylles. Nullene er flyttall, så de skrives 0. med punktum. Dette er standard første linje i alle simuleringer i boka: du lager plassen, setter startverdien, og skriver de øvrige verdiene inn i en løkke. Trenger du N+1 punkter, skriver du np.zeros(N+1).
import numpy as np
print(np.zeros(4))Utskrift:
[0. 0. 0. 0.]Lager et nullarray med samme lengde som t. Nyttig når du allerede har et tidsarray og vil ha et løsningsarray som passer til det — da kan du ikke bomme på lengden, fordi du aldri skriver et tall. Det er den sikreste måten å unngå feil #1 (av-én på antall punkter).
import numpy as np
t = np.linspace(0, 1, 5)
print(np.zeros_like(t))Utskrift:
[0. 0. 0. 0. 0.]Som np.zeros, men fylt med ettere. Brukes når startverdien i en modell er 1, eller når du trenger et array du skal multiplisere inn i noe annet. Ettallene er flyttall og skrives 1..
import numpy as np
print(np.ones(3) * 5)Utskrift:
[5. 5. 5.]Lager N+1 jevnt fordelte punkter fra a til b, med begge endepunktene inkludert. Tredje argument er altså antall punkter, ikke antall intervaller. Avstanden mellom nabopunkter blir , og du kan alltid hente den ut som t[1] - t[0].
Dette er den mest presise setningen i hele kapitlet, og den du må kunne i søvne: N intervaller gir N+1 punkter. Vil du ha 101 punkter i intervallet fra 1 til 10, skriver du np.linspace(1, 10, 101).
import numpy as np
t = np.linspace(0, 6, 7)
print(t)
print(t.size, t[1] - t[0])Utskrift:
[0. 1. 2. 3. 4. 5. 6.]
7 1.0Dette er feil #1 i feilkatalogen — av-én i range og i antall punkter — og den hyppigste feilen i hele faget. Den slår inn tre steder:
- np.linspace(0, T, N) når oppgaven ba om N steg. Riktig er np.linspace(0, T, N+1).
- range(N+1) når du skal gjøre N oppdateringer. Riktig er range(N), fordi hver oppdatering fyller ett nytt punkt og punkt nummer 0 var startverdien.
- To tabeller som skal sammenlignes får ulik lengde, fordi den ene ble laget med N og den andre med N+1.
Én god vane fjerner alle tre: skriv alltid ned hva N er før du skriver koden. «N = antall intervaller» gir linspace(a, b, N+1) og range(N). Er du usikker på eksamen, sett og tell punktene på papiret: start, midt, slutt — tre punkter.
En måleserie skal dekke tidsrommet fra til timer med 12 like intervaller. Lag tidsarrayet, og vis at antall punkter og steglengden stemmer.
Tolv intervaller betyr tretten punkter, og steglengden blir .
import numpy as np
N = 12
t = np.linspace(0, 6, N+1)
print(t)
print('Antall punkter:', t.size)
print('Antall intervaller:', t.size - 1)
print('Steglengde:', t[1] - t[0])Utskrift:
[0. 0.5 1. 1.5 2. 2.5 3. 3.5 4. 4.5 5. 5.5 6. ]
Antall punkter: 13
Antall intervaller: 12
Steglengde: 0.5Sensorpoenget: hadde du skrevet np.linspace(0, 6, N), ville steglengden blitt og siste punkt fortsatt 6 — tabellen ser riktig ut, men alle mellomverdiene er feil. Feilen er umulig å se på øyemål, og det er nettopp derfor den er så vanlig.
(Midtveisnivå, sjanger A — kodesporing.) Hva skriver programmet ut?
import numpy as np
x = np.linspace(2, 5, 4)
print(x)
print(x.size, x[-1])Lager et array fra start og oppover i steg av step, og stopper før stop — akkurat som range, men med flyttall tillatt. np.arange(0, 2, 0.5) gir derfor [0. 0.5 1. 1.5]: 2 er ikke med.
Bruk np.linspace når du vet hvor mange punkter du vil ha, og np.arange når du vet steglengden. På eksamen er linspace nesten alltid det riktige valget, fordi oppgaven oppgir antall steg.
import numpy as np
print(np.arange(0, 2, 0.5))Utskrift:
[0. 0.5 1. 1.5](Midtveisnivå, sjanger A — kodesporing.) De to første linjene ser like ut, men gir ulike tabeller. Hva skriver programmet ut?
import numpy as np
a = np.linspace(0, 3, 4)
b = np.arange(0, 3, 1)
print(a)
print(b)
print(a.size - b.size)Løkke 3 — funksjoner som spiser hele tabellen (~13 min)
— naturlig pausepunkt —
Til nå har vi regnet med +, -, * og **. Men de fleste vitenskapelige formler inneholder også kvadratrot, eksponentialfunksjon, sinus eller logaritme. NumPy har egne versjoner av disse som virker på et helt array om gangen.
En slik funksjon kalles en ufunksjon (kort for «universell funksjon»): den tar et array inn og gir et array av samme lengde ut, med funksjonen brukt på hvert element. np.sqrt(x) er ufunksjonen som svarer til math.sqrt, men math.sqrt klarer bare ett tall om gangen.
Det beste med dette er at det også gjelder funksjoner du har skrevet, så lenge de bare bruker aritmetikk og ufunksjoner.
En NumPy-funksjon som virker elementvis på et helt array og returnerer et nytt array av samme lengde. np.exp, np.log (naturlig logaritme), np.sin, np.cos og np.sqrt er de du trenger i faget. De tilsvarer funksjonene i math, men math-versjonene tar bare ett tall: math.sqrt med et array inn gir en feilmelding, mens np.sqrt gir hele tabellen med røtter.
import numpy as np
x = np.array([0.0, 0.25, 1.0])
print(np.sqrt(x))Utskrift:
[0. 0.5 1. ]Høyden til en ball kastet rett opp er målt i meter, med i sekunder. Skriv funksjonen én gang, og bruk den både på ett tidspunkt og på et helt tidsarray.
Funksjonen skrives helt vanlig, uten et eneste NumPy-navn. Den virker likevel på hele tabellen, fordi
*, - og ** er elementvise for arrays.import numpy as np
def hoyde(t):
return 4.0*t - 0.5*t**2
t = np.linspace(0, 4, 5)
print(hoyde(2.0))
print(t)
print(hoyde(t))Utskrift:
6.0
[0. 1. 2. 3. 4.]
[0. 3.5 6. 7.5 8. ]Første kall gir ett tall, fordi argumentet er ett tall. Andre kall gir fem tall, fordi argumentet er en tabell med fem tall. Funksjonen er den samme — det er argumentet som bestemmer om du får et tall eller en tabell tilbake.
Dette er hele grunnlaget for plotting i kap. 4.3: du lager et tett tidsarray, sender det gjennom funksjonen din, og plotter de to tabellene mot hverandre.
Samme bokstav brukes om to ting i dette kapitlet, og forskjellen avgjør hva utskriften blir:
- x som skalar, altså ett enkelt tall: x = 2.0. Da er f(x) ett tall.
- x som array: hele tabellen, for eksempel x = np.linspace(0, 1, 11). Da er f(x) en tabell med 11 tall.
Regelen som holder deg trygg: se på linja der navnet sist ble tilordnet. Står det np. der, er det en tabell. I oppgaveteksten på eksamen står det ofte at «funksjonen skal kunne kalles med et array» — det betyr bare at du ikke får bruke math-funksjoner eller en if-test på x inni funksjonen.
Merk også at math.sqrt(x) med et array som argument ikke gir et rart svar, men en feilmelding: TypeError: only length-1 arrays can be converted to Python scalars. Bruk np.sqrt.
(Midtveisnivå, sjanger A — kodesporing.) Hva skriver programmet ut?
import numpy as np
def g(x):
return 2*x + 1
v = np.linspace(0, 1, 3)
u = g(v)
print(u)
print(u[1] + v[2])Løkke 4 — plukke ut deler av tabellen (~11 min)
Indeksering og slicing virker som for lister: a[0] er første element, a[-1] er siste, og a[1:] er alt fra og med element 1. Forskjellen er at et utsnitt av et array er et array og ikke en liste, så du kan regne elementvis med det.
Det gir et triks du får bruk for i kap. 6.2: a[1:] - a[:-1] er tabellen over endringer fra ett punkt til det neste, regnet ut uten løkke.
a[i] gir ett tall (element nummer i, med 0 som første). a[i:j] gir et array med elementene fra og med i til men ikke med j — sluttindeksen er eksklusiv, som for lister. a[1:] er alt unntatt det første, a[:-1] er alt unntatt det siste, og de to har derfor like mange elementer.Én viktig forskjell fra lister: et utsnitt av et array er et utsyn inn i det samme minnet, ikke en kopi. Endrer du utsnittet, endrer du originalen.
import numpy as np
a = np.array([2.0, 5.0, 9.0, 14.0])
print(a[1:] - a[:-1])Utskrift:
[3. 4. 5.]Dette er feil #23 i feilkatalogen (aliasing — to navn på samme data). For lister gir
b = a[1:] en ny liste, men for arrays gir det et utsyn inn i a. Skriver du i b, endrer du a:import numpy as np
a = np.array([1.0, 2.0, 3.0])
b = a[1:]
b[0] = 99.0
print(a)
c = a.copy()
c[0] = -1.0
print(a)
print(c)Utskrift:
[ 1. 99. 3.]
[ 1. 99. 3.]
[-1. 99. 3.]Trenger du en uavhengig kopi, bruk a.copy(). Dette er ikke en høyfrekvent eksamensfelle, men det er en klassisk grunn til at en simulering «endrer seg selv» mens den kjører.
En sensor logger fem heltallsverdier, og fasitverdiene er kjent fra en kalibrering. Hvor mange av de fem stemmer, og hvilke?
En sammenligning mellom to arrays gir et array av
True/False, ett per element. Siden True teller som 1 i en sum, kan du telle treffene direkte med den innebygde sum.import numpy as np
maalt = np.array([3, 5, 5, 2, 7])
fasit = np.array([3, 4, 5, 2, 8])
print(maalt == fasit)
print(sum(maalt == fasit))Utskrift:
[ True False True True False]
3Legg merke til at maalt == fasit ikke gir én sann/falsk-verdi for hele tabellen, men fem. Det er dette som gjør sum(x == y) til et kort og lesbart uttrykk for «antall like elementer» — nettopp den korte, idiomatiske stilen sensor belønner.
(Midtveisnivå, sjanger A — kodesporing.) Hva skriver programmet ut?
import numpy as np
d = np.array([10, 12, 15, 21])
e = d[1:] - d[:-1]
print(e)
print(e.size, sum(e == 3))Tabeller med to indekser — bør kjenne til
Resten av denne løkka er nivå 3-stoff (kjenne til): 2D-arrays er bare i 2 av de 8 nyere settene, altså 25 %, og da som en mindre deloppgave. Har du kort tid, kan du komme hit tilbake etter at Del 5 og Del 7 sitter.
Du trenger likevel formen u[:, 0] senere, når et ODE-system i kap. 7.3 gir deg løsningen som en tabell med én kolonne per komponent. Det er den ene grunnen til å lese avsnittet nå.
Med en tuppel som argument lager np.zeros en tabell med flere rader: np.zeros((3, 4)) gir 3 rader og 4 kolonner, altså 12 nuller. Du henter ett element med to indekser, a[i, j] (rad i, kolonne j), en hel kolonne med a[:, j] og en hel rad med a[i, :]. Kolonnen og raden er selv vanlige arrays med én rad. .shape gir (3, 4), og .size gir 12.
Legg merke til de doble parentesene i np.zeros((3, 4)): de ytre hører til funksjonskallet, de indre lager tuppelen.
import numpy as np
A = np.zeros((2, 3))
A[1, 2] = 7.0
print(A[:, 2])Utskrift:
[0. 7.]Tre målestasjoner rapporterer nedbør fire ganger i døgnet. Bygg tabellen med np.zeros, fyll den med to nøstede løkker der verdien er stasjonsnummeret pluss en tidel per måletidspunkt, og hent ut kolonne 2 og rad 1.
Den ytre løkka går over rader (stasjoner), den indre over kolonner (måletidspunkt). Dette er den vanlige måten et 2D-array fylles.
import numpy as np
A = np.zeros((3, 4))
for i in range(3):
for j in range(4):
A[i, j] = i + 0.1*j
print(A)
print(A[:, 2])
print(A[1, :])
print(A.shape, A.size)Utskrift:
[[0. 0.1 0.2 0.3]
[1. 1.1 1.2 1.3]
[2. 2.1 2.2 2.3]]
[0.2 1.2 2.2]
[1. 1.1 1.2 1.3]
(3, 4) 12Merk hvordan et 2D-array skrives ut: én rad per linje, med ytterligere hakeparenteser rundt hele. A[:, 2] gir tre tall (én per stasjon), A[1, :] gir fire tall (én per tidspunkt). Blander du de to aksene, får du et svar med feil antall elementer — og det er lett å oppdage nettopp fordi antallet ikke stemmer.
Hva skriver programmet ut?
import numpy as np
B = np.zeros((2, 3))
for i in range(2):
for j in range(3):
B[i, j] = 2*i + j
print(B)
print(B[:, 0])
print(B[1, 1:])Programmet regner ut den relative endringen mellom nabomålinger. Hva skriver det ut?
import numpy as np
p = np.array([100.0, 110.0, 99.0])
r = (p[1:] - p[:-1]) / p[:-1]
print(r)
print(r.size)
print(sum(r > 0))Fem feller, i den rekkefølgen de oftest slår til:
1. #1 av-én på antall punkter. N intervaller gir N+1 punkter: np.linspace(0, T, N+1), og range(N) for oppdateringene.
2. #5 skjøting mot elementvis addisjon. Sjekk om variabelen er et array (ingen komma i utskriften) eller en liste (komma i utskriften).
3. math mot np på et array. math.sqrt og math.exp tar bare ett tall. Bruk np.sqrt og np.exp.
4. Feil akse i 2D. A[i, :] er en rad, A[:, j] er en kolonne. Tell antall elementer i svaret som kontroll.
5. np.arange der linspace var ment. arange utelater sluttverdien, linspace tar den med.
Og en huskeregel som gir poeng på fritekstoppgaver: import numpy as np skal alltid stå der. Glemt import er en av de få tingene som trekker selv når resten av koden er riktig.
Begrepsbank
Begrepsbanken er flashcard-/repetisjonsstoff — den gjentar det du nettopp har lest. Hopp trygt over ved førstegangslesing; tidsanslaget for kapitlet gjelder kjernestoffet.
En tabell av tall som Python regner på under ett. Til forskjell fra en liste har alle elementene samme talltype, lengden er fast, og +, -, *, / og ** virker elementvis. Et array skrives ut uten komma mellom elementene, som [2 4 6].
Å regne på en hel tabell i én operasjon, uten løkke. y = np.log(x) er den vektoriserte versjonen av å løpe gjennom x med en løkke og kalle math.log på hvert element. På eksamen er det en egen sjanger (M) å skrive samme tabell både med og uten løkke — se kap. 4.2.
Deler du et intervall i like biter, får du delepunkter: startpunktet, punkter inni, og sluttpunktet. Derfor er np.linspace(a, b, N+1) riktig når oppgaven oppgir steg, og derfor gir range(N) nøyaktig de oppdateringene som fyller punkt 1 til . Dette er feil #1 i feilkatalogen og fagets hyppigste feil.
Gjør x om til et array hvis det ikke alt er et, og returnerer det uendret hvis det er. Brukes i starten av en funksjon som skal takle både liste og array som argument, slik at resten av koden trygt kan regne elementvis.
Resultatet av en elementvis sammenligning, for eksempel x > 0 eller x == y: et array med True eller False for hvert element, like langt som x. Det er ikke ett sant/falsk-svar for hele tabellen. Siden True teller som 1 i en sum, gir sum(x > 0) antall positive elementer.
np.array([[1.0, 2.0], [3.0, 4.0]]) gir et array med 2 rader og 2 kolonner. Hver indre liste blir en rad, og alle de indre listene må være like lange. Elementet i rad 1, kolonne 0 hentes med M[1, 0] og er 3.0.Begge henter samme element i et 2D-array, men a[i, j] er formen boka og sensor bruker: den slår opp direkte med to indekser. a[i][j] henter først hele rad i som et nytt array og indekserer deretter i den. For nøstede lister finnes bare den siste formen, siden en liste ikke godtar to indekser i én klamme.
b = a[1:] gir et utsyn inn i det samme minnet som a, så en endring i b vises også i a. b = a.copy() gir en uavhengig kopi. Dette er feil #23 (aliasing) og skiller arrays fra lister, der a[1:] alltid er en ny liste.x * 3 multipliserer hvert element med 3 og gir et array av samme lengde. Med en liste betyr liste * 3 at lista gjentas tre ganger etter hverandre, slik at lengden tredobles. Det er samme forskjell som mellom array-addisjon og liste-skjøting (feil #5).Mønsteret er: lag plassen med A = np.zeros((n, m)), og fyll med to nøstede løkker der den ytre går over rader (for i in range(n)) og den indre over kolonner (for j in range(m)). Tilordningen er A[i, j] = .... Utskriften får én rad per linje.
Funksjonene i math tar ett tall: math.sqrt(4.0) er greit, men math.sqrt med et array inn gir en TypeError. NumPy-versjonene tar hele tabellen, så np.sqrt gir et array med røtter. Regelen på eksamen: skal koden virke på et array, skal den bruke np.-funksjonene.
Med t = np.linspace(a, b, N+1) er steglengden , og du kan alltid hente den ut av tabellen selv med t[1] - t[0]. Den siste formen er den tryggeste i en simulering, fordi den er riktig selv om du senere endrer hvordan t lages.
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.