Základy programování (IZP) Sedmé laboratorní cvičení Vysoké učení technické v Brně, Fakulta informačních technologií v Brně Božetěchova 2, 612 66 Brno Cvičící: Petr Veigend (iveigend@fit.vutbr.cz) Gabriela Nečasová Petr Veigend 2015/2016
Obsah Seznámení se zadáním druhého projektu Funkce a řetězce Iterační výpočty IZP cvičení 7 2
Seznámení s druhým projektem IZP cvičení 7 3
Seznámení se zadáním druhého projektu Iterační výpočty (max 7 bodů) Obhajoba: 24.11.2015 Odevzdání: Název: proj2.c Výstup: 29.11.2015, 23:59:59 do WISu 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 pedantic lm proj2.c o proj2 IZP cvičení 7 4
Syntaxe spuštění./proj2 -log X N./proj2 -iter MIN MAX EPS --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) --iter: hledání požadovaného počtu iterací pro dostatečně přesný výpočet logaritmu čísla z intervalu <MIN;MAX> Minimální přesnost: EPS = 1e-12 IZP cvičení 7 5
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!!! IZP cvičení 7 6
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 log 1 x = x x2 2 x3 3 x4 4 Pro x > ½ n x 1 log x = x n n=1 Doporučená mezní hodnota mezi polynomy je 1 IZP cvičení 7 7
Implementační detaily (--log) zřetězený zlomek double cfrac_log(double x, unsigned int n); x = číslo (zde z) n = rozvoj zřetězeného zlomku IZP cvičení 7 8
Implementační detaily (--log) formát výpisu log(x) = LOG_X cf_log(x) = CF_LOG_X taylor_log(x) = TAYLOR_LOG_X X hodnota daná argumentem (printf %g) LOG_ hodnoty log() z math.h CF_LOG_ hodnoty vypočtené zřetězeným zlomkem TAYLOR_LOG_ hodnoty vypočtené Taylorovým polynomem IZP cvičení 7 9
Implementační detaily hledaní počtu iterací Uživatel zadá interval <MIN;MAX> a přesnost EPS Program v tomto intervalu spočítá přirozený logaritmus pomocí Taylorova polynomu a zřetězených zlomků s danou přesností EPS a vypíše následující: IZP cvičení 7 10
Implementační detaily hledaní počtu iterací log(min) = LOG_MIN log(max) = LOG_MAX continued fraction iterations = CF_ITER cf_log(min) = CF_LOG_MIN cf_log(max) = CF_LOG_MAX taylor polynomial iterations = TAYLOR_ITER taylor_log(min) = TAYLOR_LOG_MIN taylor_log(max) = TAYLOR_LOG_MAX X, MIN, MAX hodnoty dané argumenty (printf %g) LOG_ hodnoty log() z math.h CF_LOG_ hodnoty vypočtené zřetězeným zlomkem TAYLOR_LOG_ hodnoty vypočtené Taylorovým polynomem IZP cvičení 7 11
Implementační detaily hledaní počtu iterací log(min) = LOG_MIN log(max) = LOG_MAX continued fraction iterations = CF_ITER cf_log(min) = CF_LOG_MIN cf_log(max) = CF_LOG_MAX taylor polynomial iterations = TAYLOR_ITER taylor_log(min) = TAYLOR_LOG_MIN taylor_log(max) = TAYLOR_LOG_MAX Všechny *LOG_* hodnoty (printf %.12g) CF_ITER, TAYLOR_ITER počet iterací IZP cvičení 7 12
Funkce a řetězce IZP cvičení 7 13
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í 7 14
Bodovaný úkol 1 Práce s řetězci IZP cvičení 7 15
Bodovaný úkol 1 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 IZP cvičení 7 16
Iterační výpočty IZP cvičení 7 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ě: Y i+1 = F(Y i ) Pro výpočet hodnoty Y i+1 je nutné zjistit hodnotu Y i IZP cvičení 7 18
Rekurentní problémy Musí být dána počáteční hodnota Y 0 Co musí platit pro hodnoty získané posloupnosti Y i+1 = F(Y i ) pro y 0 Y i Y j pro všechna i j Y i pro i < N nesplňuje podmínky požadované hodnoty Y N splňuje podmínky hledané hodnoty IZP cvičení 7 19
Rekurentní problémy Algoritmické schéma řešení 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í 7 20
Rekurentní problémy Algoritmické schéma řešení Y = y0; // Y proměnná, y0 počáteční hodnota while( B(Y)) // dokud není splněna koncová podmínka Y = F(Y); Zápis v C může vypadat např. double y = y0; // budeme počítat další prvek // posloupnosti while(!b(y)) // dokud není splněna koncová podmínka return y; y = f(y); // budeme počítat další prvek // posloupnosti IZP cvičení 7 21
Ukončovací podmínka Běžně se iterační výpočet ukončí, pokud Y i Y i 1 EPS 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í 7 22
Příklad 1: Druhá odmocnina Newtonovou metodou Implementujte funkci, která vypočítá druhou odmocninu x Newtonovou metodou y i+1 = 1 2 x y i + y i Prototyp funkce si vhodně zvolte IZP cvičení 7 23
Výpočet řad K výpočtu řad se používají částečné součty Pro řadu t 0, t 1, t 2, t 3,, kde t i = f t i 1 můžeme napsat řadu částečných součtů s 0, s 1, s 2, s 3,, kde s i = Můžeme je opět řešit rekurentně: s 0 = t 0 s 1 = s 0 + t 1 = t 0 + t 1 i j=0 s i = s i 1 + t i částečný součet pro aktuální člen je částečný součet pro předchozí člen + hodnota aktuálního členu t j IZP cvičení 7 24
Výpočet řad 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í 7 25
Bodovaný úkol 2 Částečné součty (řady) IZP cvičení 7 26
Bodovaný úkol 2 Pomocí částečných součtů implementuje výpočet exponenciální funkce e x. (Taylorova) řada má následující tvar: e x = 1 + x + x2 2! + x3 3! + x4 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 výpis IZP cvičení 7 27
Bodovaný úkol 2 (66.6 ) x = 4.2; eps = 0.01; e x = 1 + x + x2 2! + x3 3! + x4 4! + double t = t0; // první člen řady double s = t; int i = 1; while (fabs(t) > eps) { // součet = první člen řady // index aktuálního členu řady t = f(t, i); // vypočítáme nový člen řady s = s + t; } return s; // tento člen přičteme k // aktuálnímu částečnému součtu IZP cvičení 7 28
Zřetězené zlomky IZP cvičení 7 29
Zřetězené zlomky Implementujte výpočet čísla π pomocí zřetězeného zlomku: π = 1 + 3 + 4 5 + 1 2 2 2 3 2 7 + 42 9 + IZP cvičení 7 30
Zřetězené zlomky Implementujte výpočet čísla π pomocí zřetězeného zlomku: π = 1 + n = 4 3 + 4 5 + 1 2 2 2 3 2 7 + 42 9 + IZP cvičení 7 31
Zřetězené zlomky Implementujte výpočet čísla π pomocí zřetězeného zlomku: π = n = 3 1 + n = 4 3 + 4 5 + 1 2 2 2 3 2 7 + 42 9 + IZP cvičení 7 32
Zřetězené zlomky Implementujte výpočet čísla π pomocí zřetězeného zlomku: π = n = 2 n = 3 1 + n = 4 3 + 4 5 + 1 2 2 2 3 2 7 + 42 9 + IZP cvičení 7 33
Zřetězené zlomky Implementujte výpočet čísla π pomocí zřetězeného zlomku: n = 1 π = n = 2 n = 3 1 + n = 4 3 + 4 5 + 1 2 2 2 3 2 7 + 42 9 + IZP cvičení 7 34
Příklad 2: Zřetězené zlomky Implementujte výpočet čísla π pomocí zřetězeného zlomku: π = 1 + 3 + 4 5 + 1 2 2 2 3 2 7 + 42 9 + IZP cvičení 7 35
Příště 17.11. státní svátek CVIČENÍ ODPADÁ Můžete přijít na libovolné jiné cvičení, ale zadání bude vhodné pro samostudium Pozor: spousta cvičících je příští týden pryč Protože se už do půlsemestrálky neuvidíme, hodně štěstí IZP cvičení 7 36
Příklady k procvičení IZP cvičení 7 37
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í 7 38
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í 7 39
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í 7 40
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í 7 41
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í 7 42
Příklad 3: Zřetězené zlomky Implementujte výpočet čísla π pomocí zřetězeného zlomku: 4 π = 1 + 1 2 + Čitatele se vypočítají podle vztahu (2 n 1) 2 9 2 + 25 2 + IZP cvičení 7 43
Děkuji Vám za pozornost! IZP cvičení 7 44