({{Číslo projektu, CZ.1.07/1.1.36/02.0066}, {Autor, Ladislav Kašpárek}, {Předmět, Programovací metody}, {Téma, Numerické řešení rovnic}, {Metodický pokyn, výkladový text s ukázkami}})

Funkce FindRoot

Úvod

V tomto dokumentu ukážeme několik vlastností a parametrů funkce FindRoot, která je v systému Mathematica zabudována. Jedním ze závěrů bude nutnost znát vnitřní algoritmus numerického výpočtu, abychom mohli funkci efektivně používat, popř ji naprogramovat v Javě. Výklad metod půlení intervalu a Newtonovy metody tečen bude v dalších souborech.

V tomto souboru bude připravena řada pokusů s funkcí FindRoot, tak aby žák mohl experimentovat a zkoušet co vydrží, kde se osvědčí a kde selže.

Matematická poznámka

Rovnice jsou často zadávány jako rovnost dvou výzazů a řešením je bod kde se protnou jejich funkce. Např

({{({{ln x = (x^3)}})-x}})

Plot[{Log[x],(x^3)-x},{x,0,2}]

Dle potřeby lze rovnici upravit a převést neznámou na jednu stranu a na druhé ponechat nulu. Graf pak vypadá jinak, je tam jen jedna funkce a výsledek--kořen se pak hledá jako průsečík s osou x. Oba způsoby zápisu jsou ekvivalentní.

({{({{ln x = (x^3)}})-x | -(x^3)+x}, {-(x^3)+x+ln x = 0}})

Plot[{-(x^3)+x+Log[x]},{x,0,2},AxesLabel->{x,f[x]}]

Algebraické řešení rovnice pravděpodobně selže, proto bude nutné použít funkci FindRoot.

Solve[Log[x]==(x^3)-x,x]

Z grafů lze vyčíst, že rovnice má dva kořeny: x=1, ten je zřejmý, ověřte zkouškou a druhý “okolo” čísla 0,7.

FindRoot[Log[x]==(x^3)-x,{x,0.7}]

Funkce FindRoot

Několik poznámek k funkci FindRoot: 
1/ prostudujte si její dokumentaci (některým věcem bez dalších znalostí nebudeme rozumnět)
2/ implicitně používá Newtonovu metodu tečen, která má svá omezení
3/ zde popíšeme vybrané parametry funkce

Počet desetinných míst výsledku a přesnost výpočtu

Přesnost výpočtu lze ovlivnit celkem třemi paramtry (AccuracyGoal, PrecisionGoal, WorkingPrecision). Zde nebudeme rozebírat jemné rozdíly mezi těmito parametry, nám postačí WorkingPrecision.

FindRoot[Log[x]==(x^3)-x,{x,0.7},WorkingPrecision->12]

FindRoot[Log[x]==(x^3)-x,{x,0.7},WorkingPrecision->50]

FindRoot[Log[x]==(x^3)-x,{x,0.7},WorkingPrecision->222]

WorkingPrecision určuje na kolik desetinných míst budou nastavena čísla v průběhu výpočtu.

Počet iterací výpočtu

Iterace je jakýsi postupný krok algoritmu, výpočtu. V našem případě by výpočet měl po konečném počtu kroků skončit. Může se však stát, že se algoritmus zacyklí a pak by nikdy neskončil. Podobně, když je rovnice nešťastně zadaná, algoritmus spatně (pomalu) konverguje k výsledku a výpočet by trval dlouho. 
Algoritmus má nastaven maximální počet iterací. Pokud najde kořen do tohoto počtu kroků je vše vpořádku, pokud dosáhne maxima, je ukončen a uživatel musí rozhodnout co dál.

FindRoot[(x^x)==2x,{x,50}]

Plot[(x^x)-2x==0,{x,0,50}]

POZOR výsledek okolo 28 je zcela chybný! Proveďte zkoušku!!!
Ale Mathematica nás na to upozornila, že dosáhla maxima iterací, implicitně nastaveno na 100. Pokusme se toto číslo zvětšit.

FindRoot[(x^x)==2x,{x,50},MaxIterations->200]

Úkol

Tato rovnice má dva kořeny, najděte druhý na 100 desetinných míst. (použijte graf)

Počáteční podmínka výpočtu

Newtonova metoda pro svůj výpočet potřebuje počáteční podmínku: nějaký výchozí bod výpočtu. Určit nějaké obecné pravidlo kde a jak hodnotu volit nelze, ale rovnice zpravidla popisují nějaký reálný jev, děj, úlohu a lze tedy odhadnou přibližně výsledek, a to obvykle stačí. Newtonova metoda pak výpočet kořene oproti odhadu jen zpřesní. Na volbě počáteční hodnoty hodně záleží. Pro nevhodné počáteční hodnoty můžeme dotat zcela nevyhovující kořeny:

FindRoot[Log[x]==-x,{x,.5}]

Každá metoda tohoto typu potřebuje “starovací” hodnotu, od které spustí výpočet, ate to je slabina, je-li kořenů víc.

Rozdílné výsledky pro různá nastavení počáteční hodnoty výpočtu.

Plot[{Sin[x],-0.005x},{x,0,500}]

Table[FindRoot[Sin[x]==-0.005x,{x,a}],{a,{1,2,3,5,7,10,20,50,100,200,300,500,800}}]

Rozdílné výsledky pro různá nastavení počáteční hodnoty výpočtu.

Metoda sečen

Metoda tečen pro svůj regulerní běh potřebuje splnit poměrně přísná kriteria (zde ja zatím nebudeme vyjmenovávat, až u výkladu metody). Jsou-li splněna, pak je metoda rychlá. Pokud ne nemusíme výsledek dostat vůbec nebo za dlouho.
Metoda sečen tolik omezení nemá, ale je trochu pomalejší. Pro metodu sečen musíme zadat celý interval, kde se nachází právě jeden kořen.

FindRoot[(x^x)==2x,{x,0.1,.5}]

Metoda tečen selhává!

Plot[{1.8x*Sin[x],2x-1},{x,0,500}]

FindRoot[1.8x*Sin[x]==2x-1,{x,500}]

Metoda sečen bez problému vyčísluje výsledek

FindRoot[1.8x*Sin[x]==2x-1,{x,0,500}]

Shrnutí

Rovnice lze řešit numericky, různým metodami, které však mají své výhody a nevýhody. Proto je nutné metody znát, aby je uživatel mohl efektivně používat.

Úlohy

1/ Vyřeš rovnice, počáteční podmínky si stanov sám z pozorování grafů:

({{({{sin (x^x)=2x}, {sin (sin x) =2x-1}})}})

Zdroje

http://reference.wolfram.com/mathematica/ref/FindRoot.html

http://mathworld.wolfram.com/NewtonsMethod.html