Laboration 3 - Grundläggande numeriska beräkningar
- Inlämningsdatum 19 sep 2024 av 17:00
- Poäng 10
- Lämnar in en filuppladdning
- Tillgänglig 10 sep 2024 kl 8:00–24 sep 2024 kl 17:00
Obligatoriska uppgifter
1. Målet är att skriva en funktion som beräknar kvadratroten ur ett tal och jämföra med den inbyggda funktionen i modulen math. (Idén bakom metoden är beskriven för i matteboken Globala system har i sin parallella kurs (Exempel 0.2), men fungerar för alla positiva tal. Det är en iterativ metod där man successivt hittar bättre och bättre rationell approximation av kvadratroten. Man startar med ett positivt tal x1. Om
så kommer
och om man förlänger båda leden med n så får man att
. Om istället
så kommer vi att få
. Vi har alltså att ett av följande två fall gäller
Det leder en att gissa att medelvärdet av x1 och n/x1 ligger närmare vilket ger följande talföljd
Ni ska skriva en funktion kvadratrot som använder denna metod för att beräkna kvadratroten ur ett ickenegativt tal.
- Funktionen ska beräkna tal x1, x2, .. ,xk. tills
- Därefter ska den skriva ut hur många iterationer som behövdes och returnera xk.
Skriv sedan kod som ber användaren mata in ett positivt tal och som sedan beräknar roten ur detta med er funktion. Om det var ett korrekt värde som användaren matade in så ska den skriva vad roten blev och också hur mycket detta värde skiljer sig från det som den inbyggda funktionen sqrt i modulen math ger.
Kontrollera: Se så att differensen mellan det värde som er funktion ger och den inbyggda sqrt i math ger är (klart) mindre än för
.
2. Ni ska skriva en funktion som givet en lista L och ett tal n returnerar en lista av glidande medelvärden av värdena i L med n värden i varje "fönster". Vad är då ett glidande medelvärde? Det betyder att man för alla element i listan med tillräckligt högt index tar medelvärdet av de n värdena fram till och med detta element. T.ex. om man tar listan [0, 3 , 5, 8, 11] och tar fönster av längd 3 så kommer det glidande medelvärdet att bli [(0+3+5)/3, (3+5+8)/3, (5+8+11)/3] = [8/3, 16/3, 8]. Alltså ett anrop med er funktion skulle kunna se ut som glidande_medelvarde([0, 3 , 5, 8, 11], 3) och i så fall resultera i [2.66..., 5.33...,8].
Glidande medelvärde kan vara bra att använda om man har data som har en variation mellan mätvärdena som är "slumpmässig" på något sätt så att värdena hoppar på ett sätt som kan dölja trender i datan. Det används t.ex. inom finans där det glidande medelvärdet på en akties kurs kan ge indikationer på långsiktiga trender.
En dataserie där glidande medelvärde är effektivt för att få en tydligare trend är antalet rapporterade insjuknade respektive döda i Covid-19 per dag under pandemin i Sverige. Den blir väldigt hackig eftersom antalet beror mycket på vilken veckodag det är pga hur rapporteringen var. Kör er funktion på dessa data över antalet insjuknade per dag respektive döda per dag (hämtade från FHM (fliken "Information om datakällor") med ett fönster av längd 7 så att varje värde blir ett medelvärde av senast veckan för att sudda ut variationen pga veckodag. (Data för insjuknade startar den 4 februari 2020 och data för döda den 11 mars 2020 och sista datum är 7 september 2022 i båda listorna.)
Egentligen ska vi inte titta på hur man kan illustrera data förrän nästa vecka, men för att det ska bli lite intressantare än en lista med tal så kan ni använda följande kommandon för att plotta de glidande medelvärdena och jämföra med de ursprungliga serierna.
import matplotlib.pyplot as plt # Laddar modul för att skapa plottar
plt.plot(listan) # Plottar värdena i 'listan' som y-värden med x-värden 0,1,2,...
Kontrollera: Listan med glidande medelvärden för de sjuka ska innehålla 941 element och det första respektive sista värdet ska vara 0.14285714285714285 respektive 624.0. För de döda ska det vara 905 element och första respektive sista elementet ska vara 1.1428571428571428 respektive 4.0.
3. Vi återvänder till standardavvikelsen. I materialet inför föreläsning 3 så finns en funktion som beräknar standardavvikelsen för talen i en lista. Ni ska nu ska nu skriva en funktion som gör samma sak, men som utnyttjar funktionerna i NumPy på ett effektivt sätt. Funktionen ska inte innehålla någon loop utan istället använda de universella funktionerna np.sum och np.sqrt. Testa och jämför med de värden ni fick i laboration 2 med värdena på temperaturen i Stockholm för att kontrollera att den räknar rätt.
Kontrollera: Värdena i listan data i denna fil från andra överbetygslaborationen förra veckan ska ge standardavvikelsen 1.0197 med fyra korrekta decimaler.
Överbetygsuppgifter
4. Ni ska skriva en egen universell funktion som generaliserar den funktion korsa_x_axeln som vi gjorde på föreläsning 3. Den ska ha två inparametrar. Den första ska vara en lista med "k-värden" k1, ... , kn och den andra en lista med "m-värden" m1, ..., mn. Den ska sedan returnera en lista med värden där det i:te värdet är det x-värde där linjen y=kix+mi korsar x-axeln.
Kontrollera: Anropet korsa_x_axeln([1, 2, 0], [1, 0, 1]) ska returnera [-1.0, 0.0, 'Inget svar'].
5. Man kan representera ett polynom som en lista av dess koefficienter med följande identifiering
.
T.ex. så representeras polynomet av listan [1, 5, 0, 2]. Ni kan förutsätta att sista talet i listan an inte är noll.
Ni ska nu skriva funktioner, add och multiply som definierar de grundläggande operatorerna addition och multiplikation av två polynom samt en funktion derivative som definierar derivering av ett polynom. Dessutom ska ni skriva en funktion isequal med två polynom som indata som returnerar True om och endast polynomen är lika och annars False.
Exempelvis eftersom (x2+1) + (x+3) = x2+x+4 så ska add([1,0,1],[3,1]) returnera [4,1,1].
Multiplikationen är lurigast, men notera exempelvis att
.
Kontrollera: Låt pol1=[1, 0, -1, 0, 0, 1] och pol2=[3, 1, 2] dvs. respektive
. Dessa ska då uppfylls:
- add(pol1, pol2) = [4, 1, 1, 0, 0, 1]
- multiply(pol1, pol2) = [3, 1, -1, -1, -2, 3, 1, 2]
- derivative(pol1) = [0, -2, 0, 0, 5]
- derivative(pol2) = Kontrollera själv att det stämmer genom att utföra deriveringen på papper.
- isequal(derivative(multiply(pol1, pol2)), add(multiply(pol1, derivative(pol2)), multiply(derivative(pol1), pol2))) returnerar True (produktregeln för derivering)