Hledání průsečíku pomocí půlení intervalu

(2016)



Metodou půlení intervalu nalezněte průsečík s osou x u funkce dané polynomem (například f=10*(x-200)3=10x3 - 6000x2 + 1200000x - 80000000) na daném intervalu (například-1000 až +1000)

(představu o průběhu funkce lze získat například pomocí online nástroje http://wolframalpha.com .





Princip metody (jedná se o „dohledání“ průsečíku v případě, že na intervalu existuje jeden průsečík):
1) Vypočtěte hodnoty v krajních bodech intervalu a uprostřed
2) Vypusťte tu z hodnot na kraji, která má stejné znaménko jako prostřední hodnota. (Předpokládáme, že existuje pouze jeden průsečík na daném intervalu).
3) Zbylé dvě hodnoty použijte jako krajní hodnoty pro výpočet podle bodu 1).
4) Výpočet ukončete v okamžiku, kdy hodnota spočítaná pro prostřední bod nabyde hodnotu „nula“ (zde musíme počítat s tím, že při „diskrétních“ výpočtech nemusíme přesné hodnoty nula dosáhnout. Proto stanovíme určitý interval, ve kterém budeme hodnoty považovat za nulové (v závislé proměnné/amplitudě, osa y). Pokud bychom uvažovali, že průběh v okolí průsečíku bude velice strmý (například 1/x v okolí nuly), museli bychom položit i podmínku na minimální interval v nezávislé proměnné („čas“, osa x)).



0) Vytvořte projekt a v něm soubor mainpul.c (kde bude funkce main a volání funkcí), soubor funkcepul.c (kde budou funkce z bodů 2 a 3) a soubor funkcepul.h (zveřejňující funkce ze souboru funkcepul.c).

1) Načtěte ze vstupu koeficienty funkce třetího řádu (pro uvedenou funkci uvažujte vstup 10;-6000;1200000;-80000000 (pro uložení použijte reálný typ-pole)). Dále načtěte tři čísla pro okraje intervalu a přesnost (pro uvedenou funkci -1000;1000;0.1 (reálné typy, pole pro interval, hodnota pro přesnost))

Jelikož vstup z klávesnice je dosti rozsáhlý, byl by při testování programu problém s neustálým zadáváním hodnot. Proto použijte pro načítání hodnot mechanizmus přesměrování vstupu místo klávesnice ze souboru. Vytvořte si soubor (například vstup.input s daty „ 10;-6000;1200000;-80000000 -1000;1000;0.1“.
Pro přesměrování vstupu na soubor se na příkazové řádce používá symbol pro přesměrování „
<program.exe < input.stdin. Tento mechanizmus funguje i v ladícím modu. Soubor input.stdin je ovšem nutné umístnit do pracovního adresáře, kterým je adresář se zdrojovými texty (standardně by tento soubor byl ve stejném adresáři jako spustitelný soubor). Přesměrování provedeme uvedením textu „<input.stdindo parametru argumenty překladače (u projektu volba properties/ configuration properties/ debugging/command arguments).

Dojde-li k chybě při načítání koeficientů, zahlaste chybu 1 (například při zadání “ 10;-6000;1200000“). Při špatném vstupu hodnot krajů intervalu zahlaste chybu 2 (například při “9000;1000;0.1“), je-li špatně hodnota tolerance (například nepodaří-li se najít průsečík do 100 iterací. Například řetězec “-10000000;10000000;0“) zahlaste chybu 3.

2) Napište funkci, která na základě dodaných parametrů vypočte pro dané koeficienty polynomu hodnotu v daném bodě. Pro mocninu lze použít funkce pow. (Pozn.: lze použít i cyklus s výpočtem v těle: cislo = cislo*aX + koef[i];.
Výpočet f(x)=k[2]*x*x+k[1]*x+k[0] ma 6 operaci; Výpočet f(x)=(k[2]*x+k[1])*x+k[0] ma 5 operaci;)
Funkce bude mít prototyp double HodnotaFunkce(unsigned int aRad, double aKoef[], double aX).
Správnost funkce vyzkoušejte pro vstupy s příslušnými kontrolními výstupními hodnotami:(vstup,vystup), (0,-80000000),(1,-78805990), (-1,-81206010)

3) Napište funkci („normální“ a následně ji zkuste navrhnout jako rekurzivní), která vypočte průsečík s nulou. Funkce bude mít prototyp double Prusecik (unsigned int aRad, double aKoef[],double aOkraje[2], double aTolerance). Funkce rekurzivní bude mít prototyp double Prusecik Rek(unsigned int aRad, double aKoef[],double aOkraje[2], double aTolerance). Tolerance určuje v jakém intervalu ukončit výpočet (bude-li výsledek v intervalu +-Tolerance, prohlásíme ho za nulu a ukončíme výpočet).
Funkce vypočte hodnoty v krajních bodech a uprostřed mezi nimi. Pokud je hodnota uprostřed dostatečně malá (v intervalu +-Tolerance), pak vrátí jí odpovídající polohu (hodnotu vstupu z intervalu, která dá příslušný výsledek). Jinak pokračuje (nebo u rekurzivní formy zavolá opět funkci Prusecik) s hodnotami krajnich bodů, kdy jeden z původních (ten jehož hodnota má stejné znaménko jako střední) nahradí bodem středním.

Pro špatné vstupní hodnoty mezí (například “900;1000;0.1“ kde neleží průsečík s osou x) zahlásí funkce chybu tím, že vrátí hodnotu větší než je horní mez prohledávaného intervalu (pro účely sjednocení z důvodu ladících kontrol stanovme, že vrátí hodnotu horní meze, ke které přičte jedničku).

Po dobu ladění si pro kontrolu činnosti algoritmu tiskněte hodnoty mezí. K tisku použijte makro LOG1, LOG2..., kde číslo v názvu udává počet tisknutých parametrů pomocí funkce printf. Pro toto makro použijte mechanizmus podmíněného překladu – v případě nadefinování proměnné LADENI (pomoci #define) bude makro tisknout hodnoty (tj. bude obsahovat printf), v opačném případě bude makro „prázdné“ (tj. při překladu se na jeho místo neumístí žádný text).

Pozn.: funkci LOGX lze nahradit funkcí univerzální pro libovolný počet paramterů LOG(format, …) printf(format, __VA_ARGS__). „Parametr“ tři tečky značí, že na tomto místě může být libovolný počet parametrů. Tyto parametry se umístí do místa označeného __VA_ARGS__.

4) Pomocí funkcí z bodů 2) a 3) (zavoláte funkci z bodu 3, která dále využívá funkci z bodu 2) vypočtěte průsečík zadané funkce s osou x. Vypočtenou (vrácenou) hodnotu vytiskněte.



5) Upravte program tak, aby pracoval pro libovolný řád od 1 do MAXRAD (nastavte jako konstantu pomocí #define, v programu volte hodnotu 10). Jako první tedy načtěte ze vstupu celočíselnou hodnotu – řád polynomu funkce (pro uvedenou funkci 3 (celočíselný typ)). Při hodnotě řádu mimo stanovené meze, vraťte chybový kód 4. Následně načtěte koeficienty funkce, kdy jejich počet musí odpovídat zadanému řádu.



















Poslední změna 2015-02-22