IZP cvičení 8
2
Náplň cvičení • Seznámení se zadáním druhého projektu • Funkce a řetězce • Iterační výpočty
IZP cvičení 9
3
Hodnocení prvního projektu
• Konzultace 15.11. 09-11:15; 16-17 A221 • Formulář online, adresa v mailu
IZP cvičení 9
4
SEZNÁMENÍ S DRUHÝM PROJEKTEM IZP cvičení 9
5
Seznámení se zadáním druhého projektu Iterační výpočty (max 7 bodů) • Obhajoba: • Odevzdání:
21.11.2016 (Po) / 23.11.2016 (St) 27.11.2016, 23:59:59 do WISu
• Název: proj2.c • Výstup: • standardní výstup pro výpis výsledků (na wiki) • standardní chybový výstup pro výpis chyb
• V rámci projektu můžete používat pouze matematické operace +,-,* a / • Překlad: nutno využít přepínač -lm: gcc -std=c99 -Wall -Wextra -Werror proj2.c -lm -o proj2 IZP cvičení 9
6
Syntaxe spuštění ./proj2 –-log X N ./proj2 –-pow X Y N
• --log: vypočítá přirozený logaritmus čísla X v N iteracích • A) Pomocí Taylorova polynomu • B) Pomocí zřetězených zlomků (Continued Fractions)
• --pow: vypočítá exponenciální funkci z čísla Y s obecným základem X v N iteracích • A) Pomocí Taylorova polynomu • B) Pomocí zřetězených zlomků (Continued Fractions) IZP cvičení 9
7
Implementační detaily • Zakázáno: používat funkce z math.h • Povoleno: • Funkce • Konstanty
log(), isnan(), isinf() NAN, INFINITY
• Nezapomeňte důkladně testovat na merlinovi !!! • Pozor na ošetření vstupních hodnot
IZP cvičení 9
8
Implementační detaily (--log) – Taylorův polynom
double taylor_log(double x, unsigned int n);
• x = číslo • n = počet členů Taylorova polynomu • Pro 0 < x < 2
𝑥2 𝑥3 𝑥4 log 1 − 𝑥 = −𝑥 − − − − ⋯ 2 3 4
• Pro x > ½ ∞ 𝑥−1 𝑥 log 𝑥 = 𝑛
𝑛
𝑛=1
• Doporučená mezní hodnota mezi polynomy je 1 IZP cvičení 9
9
Implementační detaily (--log) – zřetězený zlomek
double cfrac_log(double x, unsigned int n);
• x = číslo (zde z) • n = stupeň rozvoje zřetězeného zlomku
IZP cvičení 9
10
Implementační detaily (--log) – formát výpisu log(X) = LOG_X cfrac_log(X) = CFRAC_LOG_X taylor_log(X) = TAYLOR_LOG_X
• X – hodnota daná argumentem (printf %g) • LOG_X hodnoty log() z math.h
• CFRAC_LOG_ hodnoty vypočtené zřetězeným zlomkem • TAYLOR_LOG_ hodnoty vypočtené Taylorovým polynomem • Všechny *LOG_* a *POW hodnoty odpovídají formátu %.12g IZP cvičení 9
11
Implementační detaily (--pow) – formát výpisu pow(X,Y) = POW taylor_pow(X,Y) = TAYLOR_POW taylorcf_pow(X,Y) = TAYLORCF_POW
• X,Y – hodnota daná argumentem (printf %g) • POW hodnota pow() z math.h
• TAYLORCF_POW hodnoty vypočtené zřetězeným zlomkem • TAYLOR_POW hodnoty vypočtené Taylorovým polynomem • Všechny *LOG_* a *POW hodnoty odpovídají formátu %.12g IZP cvičení 9
12
Implementační detaily (--pow) – Taylorův polynom double taylor_pow(double x, double y, unsigned int n); double taylorcf_pow(double x, double y, unsigned int n);
• n = počet členů Taylorova polynomu • x,y = odpovídají parametrům funkce pow z matematické knihovny 𝑎 𝑥 = 𝑒 𝑥⋅ln 𝑎 𝑥 ⋅ ln 𝑎 𝑥 2 ⋅ 𝑙𝑛2 𝑎 𝑥 3 ⋅ 𝑙𝑛3 𝑎 =1+ + + +⋯ 1! 2! 3! pro 𝑎 > 0 • Funkce se liší pouze tím, jak se počítá přirozený logaritmus IZP cvičení 9
13
Prémie • Implementace funkcí double mylog(double x);
double mypow(double x, double y);
• Funkce volí podle hodnoty zadaného argumentu • nejpřesnější typ výpočtu (Taylorův polynom nebo zřetězené zlomky) • Minimální počet iterací pro požadovanou přesnost (8 významných číslic, výstupní formát %.7e přesného výsledku)
• Podmínkou je úspěšná obhajoba projektu a vypracovaných prémiových funkcí IZP cvičení 9
14
FUNKCE A ŘETĚZCE
IZP cvičení 9
15
Funkce pro práci s řetězci – string.h • Vyhledání znaku c v řetězci s, vrací ukazatel na vyhledaný znak, jinak NULL char* strchr(char* s, int c); • Kopie řetězce src do řetězce dst, vrací ukazatel na dst char* strcpy(char* dst, char* src); • Spojení řetězců dst a src, výsledek v dst char* strcat(char* dst, char* src); • Lexikografické porovnání řetězců s1 a s2 int strcmp(char* s1, char* s2);
IZP cvičení 9
16
ITERAČNÍ VÝPOČTY
IZP cvičení 9
17
Rekurentní problémy • Rekurentní problém: výpočet nové hodnoty závisí na hodnotě výpočtu z předcházejícího kroku • Rekurentní vztah obecně: 𝑌𝑖+1 = 𝐹(𝑌𝑖 ) • Pro výpočet hodnoty 𝑌𝑖+1 je nutné zjistit hodnotu 𝑌𝑖
IZP cvičení 9
18
Rekurentní problémy • Musí být dána počáteční hodnota 𝑌0 • Co musí platit pro hodnoty získané posloupnosti • 𝑌𝑖+1 = 𝐹(𝑌𝑖 ) pro y ≥ 0 • 𝑌𝑖 ≠ 𝑌𝑗 pro všechna i ≠ 𝑗
• 𝑌𝑖 pro i < 𝑁 nesplňuje podmínky požadované hodnoty • 𝑌𝑁 splňuje podmínky hledané hodnoty
IZP cvičení 9
19
Posloupnosti • Algoritmické schéma posloupnosti Y = y0; // Y – proměnná, y0 – počáteční hodnota while(¬B(Y)) // dokud není splněna koncová podmínka Y = F(Y); // budeme počítat další prvek // posloupnosti
IZP cvičení 9
20
Posloupnosti • Algoritmické schéma posloupnosti Y = y0; // Y – proměnná, y0 – počáteční hodnota while(¬B(Y)) // dokud není splněna koncová podmínka Y = F(Y); // budeme počítat další prvek // posloupnosti
• Zápis v C může vypadat např.
IZP cvičení 9
21
Posloupnosti • Algoritmické schéma posloupnosti Y = y0; // Y – proměnná, y0 – počáteční hodnota while(¬B(Y)) // dokud není splněna koncová podmínka Y = F(Y); // budeme počítat další prvek // posloupnosti
• Zápis v C může vypadat např. double y = y0;
while(!b(y)) // dokud není splněna koncová podmínka y = f(y); // budeme počítat další prvek // posloupnosti return y;
IZP cvičení 9
22
Ukončovací podmínka • Běžně se iterační výpočet ukončí, pokud |𝑌𝑖 − 𝑌𝑖−1 | ≤ 𝐸𝑃𝑆 • To se dá v C zapsat např.
• Algoritmické schéma lze použít pro výpočet číselných řad (Taylorův rozvoj), kterými lze aproximovat funkce IZP cvičení 9
23
Ukončovací podmínka • Běžně se iterační výpočet ukončí, pokud |𝑌𝑖 − 𝑌𝑖−1 | ≤ 𝐸𝑃𝑆 • To se dá v C zapsat např. double y = y0; // aktuální člen double yp; // předchozí člen do { yp = y; // uložíme hodnotu předchozího členu y = f(y); // vypočítáme další člen } while (fabs(y - yp) > eps);
• Algoritmické schéma lze použít pro výpočet číselných řad (Taylorův rozvoj), kterými lze aproximovat funkce IZP cvičení 9
24
Posloupnosti
BODOVANÝ ÚKOL
IZP cvičení 9
25
Příklad 1: Druhá odmocnina Newtonovou metodou
• Implementujte funkci, která vypočítá druhou odmocninu √𝑥 Newtonovou metodou
𝒚𝒊+𝟏
𝟏 𝒙 = ∗ + 𝒚𝒊 𝟐 𝒚𝒊
• Prototyp funkce si vhodně zvolte
• Můžete použít funkci sqrt(x) pro ověření funkčnosti řešení
IZP cvičení 9
26
Algoritmické schéma double y = y0; // aktuální člen double yp; // předchozí člen do { yp = y; // uložíme hodnotu předchozího členu y = f(y); // vypočítáme další člen } while (fabs(y - yp) > eps);
𝒚𝒊+𝟏
𝟏 𝒙 = ∗ + 𝒚𝒊 𝟐 𝒚𝒊
• sqrt(x) IZP cvičení 9
27
Řady (částečné součty) • K výpočtu řad se používají částečné součty • Pro řadu 𝑡0 , 𝑡1 , 𝑡2 , 𝑡3 , … , 𝑘𝑑𝑒 𝑡𝑖 = 𝑓 𝑡𝑖−1 můžeme napsat řadu částečných součtů 𝑖
𝑠0 , 𝑠1 , 𝑠2 , 𝑠3 , … , 𝑘𝑑𝑒 𝑠𝑖 = 𝑡𝑗 𝑗=0
• Můžeme je opět řešit rekurentně: • • • •
𝑠0 = 𝑡0 𝑠1 = 𝑠0 + 𝑡1 = 𝑡0 + 𝑡1 𝑠𝑖 = 𝑠𝑖−1 + 𝑡𝑖 částečný součet pro aktuální člen je částečný součet pro předchozí člen + hodnota aktuálního členu IZP cvičení 9
28
Řady (částečné součty) • Algoritmické schéma T = t0; // první člen řady S = T; // součet = první člen řady while(¬B(S, T)) { T = f(T); // vypočítáme nový člen řady S = S + T; // tento člen přičteme k aktuálnímu // částečnému součtu }
• Je nutné si vždy zjistit, jak se od sebe liší jednotlivé členy řady • Pozor: Některé řady konvergují nejrychleji jen v omezeném definičním oboru funkce IZP cvičení 9
29
Posloupnosti vs. řady (částečné součty) Y = y0; // Y – proměnná, y0 – počáteční hodnota while(¬B(Y)) // dokud není splněna koncová podmínka Y = F(Y); // budeme počítat další prvek // posloupnosti
T = t0; // první člen řady S = T; // součet = první člen řady while(¬B(S, T)) { T = f(T); // vypočítáme nový člen řady S = S + T; // tento člen přičteme k aktuálnímu // částečnému součtu } IZP cvičení 9
30
Částečné součty (řady)
BODOVANÝ ÚKOL
IZP cvičení 9
31
Bodovaný úkol 2 Pomocí částečných součtů implementuje výpočet exponenciální funkce 𝒆𝒙 . (Taylorova) řada má následující tvar: 2 3 4 𝑥 𝑥 𝑥 𝑒𝑥 = 1 + 𝑥 + + + + ⋯ 2! 3! 4!
Výsledek porovnejte s matematickou knihovnou math.h
a obě hodnoty vypište na standardní výstup Nemůžete použít mocninu, faktoriál a funkci exp(x) z matematické knihovny math.h. Můžete použít funkci fabs()pro výpočet absolutní hodnoty a exp(x) pro ověření funkčnosti řešení IZP cvičení 9
32
Bodovaný úkol 2 (66.684…) 2 3 4 𝑥 𝑥 𝑥 𝑒𝑥 = 1 + 𝑥 + + + + ⋯ 2! 3! 4! x = 4.2; eps = 0.01; double t = t0; double s = t; int i = 1; while (fabs(t) t = f(t, i); s = s + t;
// první člen řady // součet = první člen řady // index aktuálního členu řady > eps) { // vypočítáme nový člen řady // tento člen přičteme k // aktuálnímu částečnému součtu
} return s; IZP cvičení 9
33
Continued Fractions
ZŘETĚZENÉ ZLOMKY
IZP cvičení 9
34
Algoritmické schéma double cf = 1.0; // nebo 0.0 while (k >= 1) { cf = fa(k) / ( fb(k) + cf ); k = k - 1; }
return fb(0) + cf;
IZP cvičení 9
35
Zřetězené zlomky Implementujte výpočet čísla 𝜋 pomocí zřetězeného zlomku:
𝜋=
4
12 1+ 22 3+ 32 5+ 42 7+ 9+⋯
IZP cvičení 9
36
Zřetězené zlomky Implementujte výpočet čísla 𝜋 pomocí zřetězeného zlomku:
𝜋=
4
12 1+ 22 3+ 32 5+ 42 7+ 9+⋯
n=4
IZP cvičení 9
37
Zřetězené zlomky Implementujte výpočet čísla 𝜋 pomocí zřetězeného zlomku:
𝜋=
n=3
4
12 1+ 22 3+ 32 5+ 42 7+ 9+⋯
n=4
IZP cvičení 9
38
Zřetězené zlomky Implementujte výpočet čísla 𝜋 pomocí zřetězeného zlomku:
𝜋= n=2 n=3
4
12 1+ 22 3+ 32 5+ 42 7+ 9+⋯
n=4
IZP cvičení 9
39
Zřetězené zlomky Implementujte výpočet čísla 𝜋 pomocí zřetězeného zlomku:
𝜋= n=1 n=2 n=3
4
12 1+ 22 3+ 32 5+ 42 7+ 9+⋯
n=4
IZP cvičení 9
40
Příklad 2: Zřetězené zlomky Implementujte výpočet čísla 𝜋 pomocí zřetězeného zlomku:
𝜋=
4
12 1+ 22 3+ 32 5+ 42 7+ 9+⋯
IZP cvičení 9
41
PŘÍKLADY K PROCVIČENÍ
IZP cvičení 9
42
Příklad na rozehřátí • Implementujte funkci void getMax(int *pole, int len, int *max);
která vyhledá v poli maximální hodnotu a vrátí ji přes ukazatel
IZP cvičení 9
43
Příklad na rozehřátí • Implementujte funkci void getMax(int *pole, int len, int *max);
která vyhledá v poli maximální hodnotu a vrátí ji přes ukazatel • Jak inicializujeme pole?
IZP cvičení 9
44
Příklad na rozehřátí • Implementujte funkci void getMax(int *pole, int len, int *max);
která vyhledá v poli maximální hodnotu a vrátí ji přes ukazatel • Jak inicializujeme pole? int pole[10]={7,2,3,9,15,20,-1,42,100,-75};
IZP cvičení 9
45
Příklad na rozehřátí • Implementujte funkci void getMax(int *pole, int len, int *max);
která vyhledá v poli maximální hodnotu a vrátí ji přes ukazatel • Jak inicializujeme pole? int pole[10]={7,2,3,9,15,20,-1,42,100,-75};
• Jak zavoláme funkci getMax()?
IZP cvičení 9
46
Příklad na rozehřátí • Implementujte funkci void getMax(int *pole, int len, int *max);
která vyhledá v poli maximální hodnotu a vrátí ji přes ukazatel • Jak inicializujeme pole? int pole[10]={7,2,3,9,15,20,-1,42,100,-75};
• Jak zavoláme funkci getMax()? int maximum = 0; getMax(pole, &maximum); IZP cvičení 9
47
Příklad 3: Zřetězené zlomky Implementujte výpočet čísla 𝜋 pomocí zřetězeného zlomku: 4 =1+ 𝜋 2+
1 9
25 2+ 2+⋯ Čitatele se vypočítají podle vztahu (2 ∗ 𝑛 − 1)2
IZP cvičení 9
48
Příklad 4: práce s řetězci • Implementujte si vlastní funkci pro lexikografické porovnání dvou řetězců int strcmpMy(char* s1, char* s2);
• Funkce vrací: • 0 pokud s1 == s2 • -1 pokud s1 < s2 • 1 pokud s1 > s2
• Vyzkoušejte implementovat i další funkce z knihovny string.h
IZP cvičení 9
49
Děkuji Vám za pozornost!
IZP cvičení 9
50