Praktikum 15¶
Allolevad ülesanded on kursuse "Sissejuhatus programmeerimisse Pythoni baasil" YFX0500 praktikumis koos kursusega ja kodus iseseisvalt lahendamiseks. Kuidas lahendada allolevaid ülesandeid? Uuri ja kasuta loengus kommenteeritud süntaksi näiteid, abiinfot (Pythoni sisseehitatud funktsioon help, jne.), Internetti ja enda aju. Küsimuste korral, mis tekivad praktikumi ajal, pöördu õppejõu või õppejõudude poole. Iganädalaselt peale praktikumi toimumist avaldatakse ülesannete lahendused kursuse kodulehel.
Inimintellekti loodud ülesanded¶
Ülesanne 0:
Loo korrutustabel kasutades massiivi numpy.ndarray. Tsüklite kasutamine keelatud.
- Korrutustabel mis sisaldab korrutustehteid arvudega 1 kuni 10.
- Kuitahes suur korrusustabel. Loo funktsioon.
Vastus Punkt 1:
[[ 1 2 3 4 5 6 7 8 9 10]
[ 2 4 6 8 10 12 14 16 18 20]
[ 3 6 9 12 15 18 21 24 27 30]
[ 4 8 12 16 20 24 28 32 36 40]
[ 5 10 15 20 25 30 35 40 45 50]
[ 6 12 18 24 30 36 42 48 54 60]
[ 7 14 21 28 35 42 49 56 63 70]
[ 8 16 24 32 40 48 56 64 72 80]
[ 9 18 27 36 45 54 63 72 81 90]
[ 10 20 30 40 50 60 70 80 90 100]]
Vastus Punkt 2: Eeldame, et tahetakse tabelit kuni arvuni 5.
[[ 1 2 3 4 5]
[ 2 4 6 8 10]
[ 3 6 9 12 15]
[ 4 8 12 16 20]
[ 5 10 15 20 25]]
Ülesanne 1:
Kirjuta Pythoni klass mis loob etteantud ühe muutujaga funktsiooni $f(x)$ diskretiseeritud väärtustega objekte etteantud vahemikus $x \in [x_{\rm start}, x_{\rm stopp}]$. Lisaks funktsiooni $f(x)$ väärtusetele peab programm leidma ka selle esimese $f'(x)$ ja teise $f''(x)$ täistuletise diskretiseeritud väärtused. Lisa klassile neli meetodit. Meetodid peavad looma/väljastama/kuvama graafikuid:
- funktsioonist $f(x)$ etteantud vahemikus ja sammuga,
- selle esimesest tuletisest $f'(x)$,
- selle teisest tuletisest $f''(x)$ ja
- kuvama kõiki eelmainituid funktsioonide graafikuid samal teljepaaril.
Oodatav tulemus juhul kui kasutad funktsioonina $f(x) = {\rm e}^{-x^2} \equiv \exp(-x^2)$ vahemikul $x \in [-5, 5]$ ja sammuga ${\rm d}x = 0.2$:
| Joonis 1. Ülesande 1 näidiseeldustele vastav oodatav tulemus. Neljale meetodile vastavad neli joonist. |
Ülesanne 2:
Kontrolli kas võrdus kujul:
$$\ln(1 + 2 + 3) = \ln(1) + \ln(2) + \ln(3)$$
on tõene. Keskkooli ajast teame, et
$$\boxed{\ln(1 \cdot 2 \cdot 3) = \ln(1) + \ln(2) + \ln(3)}$$
on tõene. Kuidas seletada esimest võrdust?
Vastus:
$$\ln(1 + 2 + 3) = \ln(1) + \ln(2) + \ln(3)$$ $$\ln(1 + 2 + 3) = \ln(1 \cdot 2 \cdot 3)$$ $$\ln(6) = \ln(6)$$
Seega, esimene võrdus on tõene kuna
$$ 1 + 2 + 3 = 1 \cdot 2 \cdot 3 = 6.$$
Esimene seos kujul:
$$ \ln(a + b + c) = \ln(a) + \ln(b) + \ln(c)$$
kus $\{a, b, c\} \in \mathbb{R}$, ei kehti üldjuhul.
Ülesanne 3:
Loo allolev numpy.ndarray andmemassiiv. Tee sellest massiivist koopia milles on kõik kolmega mittejaguvad arvud asendatud metsalise arvuga $666$ (Viide: Piibel Ilmutuse raamat 13:18) või $616$ kui tahad olla ajalooliselt ja faktiliselt täpne, vt. https://en.wikipedia.org/wiki/Number_of_the_beast
Massiiv:
[[30 29 28 27 26]
[25 24 23 22 21]
[20 19 18 17 16]
[15 14 13 12 11]
[10 9 8 7 6]
[ 5 4 3 2 1]]
Oodatav tulemus:
[[ 30 666 666 27 666]
[666 24 666 666 21]
[666 666 18 666 666]
[ 15 666 666 12 666]
[666 9 666 666 6]
[666 666 3 666 666]]
Oodatav tulemus juhul kui oled ajaloolane või ei hooli pikaajalisest kristlikust traditsioonist mille kohaselt tuleb usku eelistada teadmisele:
[[ 30 616 616 27 616]
[616 24 616 616 21]
[616 616 18 616 616]
[ 15 616 616 12 616]
[616 9 616 616 6]
[616 616 3 616 616]]
Ülesanne 4:
Loo allolev numpy.ndarray andmemassiiv.
Massiiv:
[[30 29 28 27 26]
[25 24 23 22 21]
[20 19 18 17 16]
[15 14 13 12 11]
[10 9 8 7 6]
[ 5 4 3 2 1]]
- Leia selles esinevate paarisarvude summa.
- Leia selles esinevate paarisarvude mille väärtus on väiksem kui 22 summa.
- Leia selles esinevate paarisarvude ja arvude 7 ning 77 (kui need esinevad massiivis) summa.
Vastused:
240110247
Ülesanne 5:
Sul on $4 \times 3$ ruudustik temperatuuriprognoose (read = laiuskraadid, veerud = pikkuskraadid).
import numpy as np
temp = np.array([[15, 16, 17],
[14, 15, 16],
[13, 14, 15],
[12, 13, 14]])
Lisa parandused (neid liites), mis sõltuvad ainult laiuskraadist ja ainult pikkuskraadist.
laius_par = np.array([0.5, 1.0, -0.2, -1.0]) # Kuju (4,) -> üks iga rea kohta.
pikkus_par = np.array([0.1, -0.3, 0.4]) # Kuju (3,) -> üks iga veeru kohta
Vastus:
Temp algne:
[[15 16 17]
[14 15 16]
[13 14 15]
[12 13 14]]
Koos parandusega:
[[15.6 16.2 17.9]
[15.1 15.7 17.4]
[12.9 13.5 15.2]
[11.1 11.7 13.4]]
Ülesanne 6:
Kirjuta programm mis prindib konsooli:
- $4 \times 4$ malelaua mustri kus arv
0tähistab valget ja arv1musta värvi. Malelaud peaks välja nägema järgmiselt:
[[0 1 0 1]
[1 0 1 0]
[0 1 0 1]
[1 0 1 0]]
- Kuitahes suurt malelauda. Kirjuta funktsioon.
Kasuta massiivi numpy.ndarray. Tsüklite kasutamine keelatud. Vt. vrd. Ülesandega 0.
Vihje: Pea meeles, et
$$ 0 \mod 2 = 0, $$ $$ 1 \mod 2 = 1, $$ $$ 2 \mod 2 = 0, $$
kus $\mod{} $ on jagamise jäägi operaator.
Ülesanne 7:
Loo graafik mis kujutab Lissajous kõverat. Kõver on esitatud parameetrilisel kujul:
$$ \begin{cases} x(t) = A \sin (a t + \delta),\\ y(t) = B \sin (b t), \end{cases} $$
kus parameeter $t \in [0, t_\text{max})$ on $x$-i ja $y$-t siduv muutuja, ning $A$, $B$, $a$, $b$ ja $\delta$ on meelevaldselt valitavad konstandid. Tulemus sõltub tugevalt $a$ ja $b$ suhtest.
Lisainfo: https://en.wikipedia.org/wiki/Lissajous_curve
Vastus: Joonis 2 kujutab kõverat juhul kui $A = 1$, $B = 1$, $a = 5$, $b = 4$, $\delta = \pi / 5$ ja $t_\text{max} = 6.28$.
| Joonis 2. Ülesande 7 oodatav tulemus. |
Ülesanne 8:
Kasutades Ülesandes 7 defineeritud Lissajous kõvera parameetrilist kuju, loo allpool kujutatud joonis. Vali joonise suuruseks suurus (6.5, 5). Joonis 3 kujutab kõverat juhul kui $A = 1$, $B = 1$, $a = 5$, $b = 4$, $\delta = \pi / 5$ ja $t_\text{max} = 6.28$.
Telgede eemaldamine:
import numpy as np
fig, axes = plt.subplots(2, 2)
axes[1, 1].remove() # Telgede eemaldamine kohalt axes[1, 1].
| Joonis 3. Ülesande 8 oodatav tulemus. |
Ülesanne 9:
Kasutades Ülesandes 7 defineeritud Lissajous kõvera parameetrilist kuju, loo allpool kujutatud joonis. Vali joonise suuruseks suurus (6.5, 7). Joonis 4 kujutab kõverat juhul kui $A = 1$, $B = 1$, $a = 5$, $b = 4$, $\delta = \pi / 5$ ja $t_\text{max} = 6.28$.
Joonise koostamisel võid kasutada funktsiooni matplotlib.pyplot.subplot_mosaic ja joonise mosaiiki kujul:
mosaic = [['A', 'A'],
['A', 'A'],
['B', 'C']]
| Joonis 4. Ülesande 9 oodatav tulemus. |
Ülesanne 10:
Leia kolmefaasilise voolu faaside hetkeliste pingete summa. Loo graafik mis kujutab iga faasi pinge väärtuse muutumist ajas koos kõigi faaside summa graafikuga. Normeeri pinge aegrida, st. vali pinge amplituudiks $|\max U(t)| = 1$. Loeme iga faasi vahelduvvoolu sageduseks $f = 50$ Hz.
Vihje: Loe Vikipeedia artiklit: https://en.wikipedia.org/wiki/Three-phase_electric_power
Oodatav tulemus on näidatud Joonisel 5 kus kujutatakse 50 ms pikkust pinge aegrida $U(t)$.
| Joonis 5. Ülesande 10 oodatav tulemus. |
Ülesanne 11:
Loo Joonisel 6 kujutatud joonis (ligikaudselt, ei peal olema 100% koopia). Ringi loomiseks kasuta allpool esitatud ringjoone parameetrilist kuju. Suu loomiseks kasuta parabooli. Silmade kujutamiseks kasuta punkte.
import numpy as np
theta = np.linspace(0, 2*np.pi, 100)
r = 1.9 # Raadius, vali ise.
x = r * np.cos(theta)
y = r * np.sin(theta)
| Joonis 6. Ülesande 11 oodatav tulemus. |
Ülesanne 12:
Kontrolli kas juhuslike arvude generaator numpy.random.rand loob arve mille jaotus on konstantne nagu väidab selle dokumentatsioon. Loo histogramm kasuta vähemalt 30 000 juhuslikku arvu.
Loo histogramm kasutades:
- Matplotlib graafikutüüpi
matplotlib.pyplot.hist. - NumPy funktsiooni
numpy.histogramkoos Matplotlib graafikutüüpimatplotlib.pyplot.plot(tavaline graafik).
Joonised 7 ja 8 kujutavad oodatavaid tulemusi.
Joonis 7. Ülesande 12.1 oodatav tulemus. Histogramm arvutati kasutades 30 000 arvu. Histogrammi loomiseks on kasutatud teegi Matplotlib graafikutüüpi matplotlib.pyplot.hist (vaikimisi seaded). |
Joonis 8. Ülesande 12.2 oodatav tulemus. Histogramm arvutati kasutades 30 000 arvu. Histogrammi andmete leidmiseks on kasutatud funktsiooni numpy.histogram. |
Ülesanne 13: *
Kontrollime kahe integraatori täpsust. Kasuta integraatoreid:
scipy.integrate.cumulative_trapezoidscipy.integrate.cumulative_simpson
Kirjuta programm mis teostab funktsiooni kumulatiivse integreerimise ja seejärel tuletise (numpy.gradient) võtmise etteantud arvu n korda. Defineeri lõigul $x \in [-1, 1]$ funktsioon kujul:
$$ f_0(x) = {\rm e}^{- \alpha x^2} \equiv \exp(- \alpha x^2), $$
kus parameeter $\alpha$ on kellukakujulise pulsi laiust määrav parameeter.
Eelmainitud tsükli jooksul leitakse numbriliselt integraal kujul:
$$ F(x) = \int \!\! f(x)\, {\rm d}x, $$
ning seejärel leitakse kohe ka tuletis ehk teostatakse pöördtehe kujul:
$$ f(x) = \frac{{\rm d}}{{\rm d} x}F(x). $$
Esimese tsükli ajal asendatakse $f(x) = f_0(x)$.
Loo mõlema integraatori jaoks kolm graafikut mis on sarnased Joonisel 9 kujutatud graafikutega. Viimasel graafikul leitud maksimaalsed erinevused on leitud järgmiselt:
$$ \text{tulemus}_i = \max(|f_i(x) - f_0(x)|) = |\max(f_i(x) - f_0(x))|, $$
kus $i$ on eelmainitud integreerimise ja tuletise võtmise tsükkel.
Joonis 9. Ülesande 13 üks oodatavatest tulemustest. Kujutatud graafikute ja joonise loomiseks kasutati integraatorit scipy.integrate.cumulative_simpson ning $n = 30$ integreerimise ja tuletise võtmise tsüklit. Algse pulsi $f_0(x)$ defineerimiseks kasutati $\alpha = 20$ ning $50$ andmepunkti. |
Ülesanne 14: *
Kontrollime kas seos Kuu kraatrite diameetri ja vanuse vahel on astmeseadus. Lae kursuse kodulehelt alla fail Kuu.csv käsitsi või kasuta Pythoni standardteegi moodulit urllib. Faili saab enda töökausta alla laadida näiteks järgmise koodiga:
from urllib.request import urlretrieve
from pathlib import Path
def save_fail_kursuse_kodulehelt(fname):
my_file_obj = Path(fname)
if my_file_obj.is_file():
print("Fail on juba töökaustas...")
else:
url = f"https://www.tud.ttu.ee/web/dmitri.kartofelev/YFX0500/{fname}"
urlretrieve(url, fname)
print("Fail on alla laetud töökausta...")
server_file_name = "Kuu.csv"
save_fail_kursuse_kodulehelt(server_file_name)
Allalaetud fail sisaldab muuseas Kuu kraatrite diameetreid ja nende vanust, vt. kaks viimast veergu. Sorteeri andmed kraatrite vanuse järgi kasutades koodi:
import numpy as np
data = np.loadtxt('Kuu.csv',
delimiter=',',
skiprows=1,
unpack=False,
usecols=(-2, -1)) # Viimased veerud.
data_sorted = data[data[:, 1].argsort()] # Sorteerimine.
vanus = data_sorted[:, 1] # Kraatrite vanused.
d = data_sorted[:, 0] # Kraatrite diameetrid.
Kustuta või eemalda andmeread kus on kraatri diameetrid suuremad kui 45 km. Loo graafikud, kasutades eelnevalt sorteeritud andmeid, kus kuvatakse kraatrite diameetri seost nende vanusest ja andmemassiivi indeksist, vt. Joonis 6. Loo histogramm. Veendu, et Kuu kraatrite jaotus on log-log tüüpi graafikul ligikaudu sirge, vt. Joonis 10.
| Joonis 10. Ülesande 14 oodatav tulemus. Histogrammi loomisel kasutati 10 vahemikku (bins) ja logaritmilisi telgi. |
Ülesanne 15:
Leia päratu integraali väärtus kasutades funktsiooni scipy.integrate.quad,
$$ \int\limits_{-\infty}^{\infty} \! {\rm e}^{- x^{2}}\, {\rm d}x ~ \equiv \!\!\! \int\limits_{-\infty}^{\infty} \! \exp(-x^2)\, {\rm d}x. $$
Kontrolli leitud tulemuse õigsust.
Analüütiline lahend:
$$ \int\limits_{-\infty}^{\infty}\! {\rm e}^{- x^{2}}\, {\rm d}x ~ \equiv \!\!\! \int\limits_{-\infty}^{\infty} \! \exp(-x^2)\, {\rm d}x = \sqrt{\pi}. $$
Ülesanne 16:
Leia polünoomi globaalse miinimumi argumendi väärtus kui:
$$ f(x) = 5 x^6 - 3 x^5 + 23 x^3 + (x + 1)^2. $$
Loo joonis mis kujutab polünoomi graafikut, juhul $x \in [-2, 2]$.
| Joonis 11. Ülesande 16 oodatav tulemus. Miinimum on kujutatud punase punktiga. |
Ülesanne 17:
Leia kõvera ja sirge lõikepunktid. Sirge ja kõver on antud kujul:
$$ y_1(x) = -0.1 x, $$
$$ y_2(x) = \sin x. $$
Otsi lõikepunkte vahemikus $x \in [-6, 6]$. Kujuta leitud punktid koos sirge $y_1$ ja kõveraga $y_2$ ühisel teljepaaril. Joonis 12 kujutab ülesande lahendit.
Vihje: Loeng 15 näited mis on leitavad Lõikudest 5.4.2 ja 5.4.3.
| Joonis 12. Ülesande 17 oodatav tulemus. Lõikepunktid on kujutatud punaste punktidega. |
Ülesanne 18: *
Konvolutsiooni kasutatakse piltidelt huvipakkuvate kujutiste (tunnuste) tuvastamiseks ja lokaliseerimiseks. Analüüsitav pilt konvoleeritakse tavaliselt palju väiksema pildiga mida hakkame nimetama tuumaks. Tuum sisaldab kujutist mida soovime suuremalt pildilt leida. Konvolutsiooni teel loodud pildi globaalne maksimum peaks vastama otsitava kujutise asukohale. Vaatame kas selline lähenemine töötab:
- Lae kursuse kodulehelt alla failid fig_P15.tiff ja ker_P15.tiff.
- Loe sisse piltide andmed. Eralda pildi andmetest üks kolmest värvikanalist (fail sisaldab kanaleid: Red, Green, Blue, alpha). Kasuta andmete lugemiseks meetodit
matplotlib.image.imread:
from matplotlib.image import imread
import matplotlib.pyplot as plt
import numpy as np
from scipy.signal import convolve
img = imread('fig_P15.tiff').astype(np.float32)
ker = imread('ker_P15.tiff').astype(np.float32)
- Teosta konvolutsiooni operatsioon kasutades funktsiooni
scipy.signal.convolve(konvolutsioon = pilt $\ast$ tuum). Teosta konvolutsioon kahe massiivi vahel: 1) failist fig_P15.tiff eraldatud andmemassiiv; 2) failist ker_P15.tiff eraldatud andmemassiivi. - Leia konvolutsiooni tulemusel leitud massiivi maksimaalse värviintentsiivsusega piksel. Leia selle piksli asukoht massiivis.
- Loo joonis mis on sarnane Joonisele 13. Pildiandmete kuvamiseks kasuta meetodit
matplotlib.pyplot.imshow. Kujuta pildifailidest eraldatud massiivid ja konvolutsiooni tulemusel saadud massiiv. Lisa viimasele teljepaarile ka eelnevalt leitud maksimaalse värviintentsiivsusega piksli asukoht, vt. Joonis 13.
| Joonis 13. Ülesande 18 näidislahendus. Leitud maksimaalse värviintentsiivsusega piksel on kujutatud punase plussiga. |
Ülesanne 19: *
Loome eelmise ülesande konvolutsioonitehtes kasutatud andmemassiivid ja kuvame neid joonisel, vt. vrd. Joonis 14.
Häguse servaga punkti või ringi kujutise saame luua kasutades nt. funktsiooni kujul:
$$ z = z(x, y) = {\rm e}^{-\alpha [(x - x_\text{s})^2 + (y - y_\text{s})^2 ]} \equiv \exp( -\alpha [(x - x_\text{s})^2 + (y - y_\text{s})^2 ]), $$
kus $\alpha$ on loodava häguse punkti suurust kontrolliv parameeter, $x_\text{s}$ ja $y_\text{s}$ on häguse punkti asukoht graafiku algpunkti $O = (x, y) = (0, 0)$ suhtes. Funktsiooni $z(x, y)$ väärtused saad siduda ristkoordinaatidega $x$ ja $y$ järgmiselt:
import matplotlib.pyplot as plt
import numpy as np
alpha = 0.2 # Suuruse parameeter.
x = np.linspace(-5, 5, 100)
y = np.linspace(-4, 4, 100)
xx, yy = np.meshgrid(x, y) # Loome andmemassiivi kuju.
z = np.exp(-alpha*((xx - x_nihe)**2 + (yy - y_nihe)**2)) # Loome massiivi andmed.
data = (x, y, z)
Loodud andmed saad järgi vaadata kasutades nt. matplotlib graafikutüüpi matplotlib.pyplot.contourf ja väljakutset kujul:
matplotlib.pyplot.contourf(*data, levels=100)
Programmi töövoog:
- Loo kaks massiivi üks suurem ja teine väiksem (resolutsioon) sarnaselt Joonisel 14 kujutatud massiividega. Sisuliselt loo originaalne anlüüsitav pilt ja tuum sarnaselt eelmisele ülesandele.
- Teosta konvulutsioon ning leia häguse servaga punkti asukoht sarnaselt eelmises ülesandes tehtule.
- Loo joonis mis on sarnane Joonisega 14. Lisa konvolutsiooni graafikutele häguse servaga punkti asukoht kasutades meelevaldselt valitud markerit.
Joonis 14. Ülesande 19 oodatav tulemus. Loodud andmemassiivid on kujutatud kasutades Matplotlib graafikutüüpe matplotlib.pyplot.contourf ja matplotlib.pyplot.contour (alumise rea parempoolne teljepaar). Häguse servaga punkti asukoht on kujutatud punase plussiga. |
Ülesanne 20:
Kirjuta programm mis loob 8-bitiseid ühe värvikanaliga ehk must-valgeid .tiff failivormingus pilte. Kasuta eelmises ülesandes loodud andmemassiivi defineeriv kood.
Loo kolm funktsiooni:
- Funktsioon mis loob andmemassiivi (vt. eelmine ülesanne).
- Funktsioon mis kuvab graafiliselt loodud massiivi. Kasuta Matplotlib graafikutüüpi
matplotlib.pyploy.imshow. Joonis 15 kujutab ühte loodud massiivi. - Funktsioon mis salvestab töökausta kaks 8-bitist pildifaili $-$ originaali ja selle negatiivi. Kasuta pythoni funktsiooni kujul:
from matplotlib.image import imsave
def save_8bit_image(fname, dat):
'''Salvestab kaks pilti töökausta.
fname: str
Loodavate failide failinimede tüvi.
dat: numpy.ndarray
2D massiiv mis sisaldab pildi andmeid.
'''
# Normeerime vahemikku [0,256]. Andmetüüp np.uint8 (unsigned 8-bit integer).
img8bit = (((dat - dat.min()) / (dat.max() - dat.min()))*255.9).astype(np.uint8)
# Salvestamine:
# Õige värv: 0=must ja 256=max intensiivsus, valge.
imsave(f'{fname}.tiff', img8bit, cmap='gray')
# Negatiiv.
imsave(f'{fname}_neg.tiff', img8bit, cmap='Grays')
return True
Joonis 16 kujutab funktsiooniga save_8bit_image loodud pilte mis vastavad Joonisel 15 kujutatud andmemassiivile.
Joonis 15. Ülesande 20 loodud andmemassiiv milles on $i = 300$ rida ja $j = 450$ veergu täisarve. Häguse servaga punkti asukohaks on valitud alumine vasakpoolne serva lähedane piirkond. Andmedmassiiv on kujutatud kasutades Matplotlib graafikutüüpi matplotlib.pyplot.imshow. |
| Joonis 16. Ülesande 20 oodatav näidistulemus. Loodud 8-bitised .tiff failivormingus pildid: originaal ja selle negatiiv. (NB! Enamus veebilehitsejaid ei toeta .tiff pildifaile. Siia salvestatud piltide tegelik failiforming on .png.) |
Ülesanne 21:
Kasutades parabooli võrrandit kujul:
$$ f(x) = x^2. $$
Loo $n = 10$ andmepunkti mis asuvad paraboolil. Lisa loodud punktidele valge müra amplituudiga $[-1, 1]$ allpool näidatud viisil. Lähenda loodud andmetele teist järku polünoom kasutades teeki NumPy.
Müra lisamine:
import numpy as np
import matplotlib.pyplot as plt
n = 10 # Andmepunktide arv graafikul.
x = np.linspace(-2, 2, n)
y_orig = x ** 2 # Parabool.
y = y_orig + 2 * np.random.rand(n) - 1 # Valge müra lisamine.
Joonis 17 kujutab võimalikku näidislahendit.
Vihje: Vt. loengu näiteid.
| Joonis 17. Ülesande 21 oodatav tulemus. |
Tehisintellekti loodud ülesanded¶
Järgnevad ülesanded on loodud 7.12.2025 juturoboti OpenAI ChatGPT (GPT-5.1 Pro) poolt.
Ülesanne TI-1:
Käivita ja tõlgenda
- Käivita kood mitu korda (nt. 5 korda). Mida märkad
poptväärtuste ja erinevuste (Δa,Δb,Δc) osas? - Miks tulemused iga jooksutuse järel pisut erinevad?
Vihje: Mürast sõltuvus.
Lahendus/selgitus:
- Iga käivitusega muutub
yn(sestnp.random.normalannab eri müra), seegacurve_fitleiab veidi erinevad parameetrid. - Kui müra on väike võrreldes signaali amplituudiga, siis leitud parameetrid jäävad ligikaudu tegelike väärtuste lähedale (väikesed
Δ). Kui suurusjärguliselt müra suureneb, Δ kasvavad. - Soovi korral fikseeri juhuslikkuse jätk
np.random.seed(42)korduva tulemuste saamiseks.
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
def func(x, a, b, c):
return a * np.exp(-b * x) + c
x = np.linspace(0, 4, 50)
a, b, c = 2.5, 1.3, 0.5
y = func(x, a, b, c)
yn = y + 0.2*np.random.normal(size=len(x))
popt, pcov = curve_fit(func, x, yn)
print(f'Leitud parameetrid: a = {popt[0]}, b = {popt[1]} ja c = {popt[2]}')
da = np.abs(a - popt[0])
db = np.abs(b - popt[1])
dc = np.abs(c - popt[2])
print(f'Erinevus tegelikusest: Δa = {da}, Δb = {db} ja Δc = {dc}')
plt.figure(figsize=(4.5, 3))
plt.plot(x, yn, 'k.', label="Andmed")
plt.plot(x, func(x, *popt), 'r-', label="Lähendatud kõver")
plt.xlabel(r'$x$')
plt.ylabel(r'Andmed ja funktsioon $f(x)$')
plt.legend()
plt.tight_layout()
plt.savefig('ul_TI_1.png', dpi=180)
plt.show()
Ülesanne TI-2:
Residuaalid ja RMSE
Eeldame, et oled eelmise ülessande lahendanud ja vajalikud massiivid on arvuti mälus.
Kirjuta kood,
- mis arvutab jääkvektorit kujul
res = yn - func(x, *popt). - Loo graafik millel kuvad
resfunktsiooninax-st. - Lisaks arvuta RMSE (root-mean-square error) kasutades valemit
rmse = np.sqrt(np.mean(res**2)).
Lahendus/selgitus:
- Erinevuste graafik näitab, kas jäägid käituvad juhuslikult (hea märk) või on süstemaatilised (näitab mudeli puudujääke).
- RMSE annab kvantitatiivse vea suuruse $—$ õpilane näeb, et see on sarnane sisendi müra standardhälbele (0.2) või veidi väiksem/suurem.
Ülesanne TI-3:
Eeldame, et oled eelmised kaks ülesannet lahendanud ja vajalikud massiivid on arvuti mälus.
Parameetrite usaldusintervallid:
- Kasutades
pcov(covariance matrix), leia ligikaudsed standardhälbed parameetritele ja kirjelda, mida need tähendavad. Loe dokumentatsiooni.
Lahendus/selgitus:
pcovtagastab hinnangulise kõrvutuste maatriksi; diagonaalilt võetud ruutjuur annavab parameetrite standardhälbe.- $1 \sigma$ tähendab ligikaudu 68% intervalli eeldusel, et jäägid on normaaljaotusega ja mudel korrektne.
Kodus¶
Ülesanne 22:
Loo joonis kasutades Gumowski-Mira kujutuse (fraktaali) definitsiooni. Kujuta iga iteratsiooni tulemus pikslina $xy$-tasandile. Gumowski-Mira fraktaal on esitatud kujutusega kujul:
$$ \begin{cases} x_{n+1} = b y_n + F(x_n),\\ y_{n+1} = -x_n + F(x_{n+1}), \end{cases} $$
$$ F(x) = a x + \frac{2 (1 - a) x^2}{1 + x^2}, $$
kus $n$ on iteratsiooni indeks ja $a$ ja $b$ on parameetrid (vali väärtused ise). Joonis 18 kujutab ülesande lahendit.
| Joonis 18. Ülesande 22 oodatav tulemus. Kujutatud kujutis on genereeritud kasutades $n = 10^5$ iteratsiooni. |
Ülesanne 23: *
Loo joonis kasutades Gumowski-Mira fraktaali definitsiooni. Kujuta iga iteratsiooni tulemus punktina $xy$-tasandile. Kasuta graafikutüüpi matplotlib.pyplot.scatter. Värvi fraktaali iga punkt (iteratsioon) vastavalt selle kaugusele punktist $O = (x, y) = (0, 0)$. Kauguse $k$ leidmiseks kasuta valemit kujul:
$$ k(x, y) = \sqrt{x^2 + y^2}. $$
Gumowski-Mira fraktaal on esitatud kujutusega kujul:
$$ \begin{cases} x_{n+1} = b y_n + F(x_n),\\ y_{n+1} = -x_n + F(x_{n+1}), \end{cases} $$
$$ F(x) = a x + \frac{2 (1 - a) x^2}{1 + x^2}, $$
kus $n$ on iteratsiooni samm ja kus $a$ ja $b$ on parameetrid (vali väärtused ise). Joonis 19 kujutab ülesande lahendit.
Joonis 19. Ülesande 23 oodatav tulemus. Kujutatud kujutis on genereeritud kasutades $n = 10^5$ iteratsiooni. Kasutatud Matplotlib värvipaletti nimi on 'twilight'. |