Tomáš Kalvoda, publikován 01. 08. 2017, editován 26. 10. 2018

Jak řešit rovnice, které neumíme vyřešit na papíře? Ukážeme si několik iterativních postupů pro hledání kořenů reálných funkcí jedné reálné proměnné. Metody porovnáme a zmíníme se i o několika zajímavých problémech vedoucích na tento typ úlohy.

Popis problému

Základní pojmy

Při studiu středoškolské matematiky čtenář již jistě narazil na problém řešení rovnice typu (1)f(x)=0 v neznámé x, kde f je zadaná reálná funkce reálné proměnné případně závisející na dalších parametrech. Řešením úlohy (1) pak nazýváme číslo x, které splňuje f(x)=0. O x se také mluví jako o kořenu funkce f. Řešení této úlohy může být nekonečně mnoho, konečně mnoho, nebo i žádné.

Známé řešitelné příklady

Zcela jistě čtenář umí nalézt řešení kvadratické rovnice ax2+bx+c=0 s parametry a,b,c a ví, že

  • pokud b24ac=0, pak má tato rovnice právě jedno řešení x=b2a,
  • pokud b24ac>0, pak má tato rovnice právě dvě řešení x±=12a(b±b24ac),
  • pokud b24ac<0, pak nemá žádné řešení v reálném oboru (má ovšem dvě komplexní řešení).

Rovnice sin(x)=1 má nekonečně mnoho řešení xk=πk,kZ.

Naproti tomu rovnice sin2(x)+1=0 nemá ani jedno řešení. Výraz na levé straně je vždy větší nebo roven 1 a nikdy (pro žádné reálné x) tak nemůže být nulový.

Obecný problém

Ve středoškolské matematice se v drtivé většině případů setkáváte s příklady rovnic f(x)=0, které umíte explicitně vyřešit podobně jako ve výše uvedených příkladech. To ovšem ve studentech zanechává poněkud nesprávný dojem, že umí řešit rovnice tohoto typu. Opak je pravdou. Explicitní řešení lze nalézt typicky jenom u školních příkladů.

V mnoha a mnoha zajímavých příkladech (pár ukázek nabídneme čtenáři níže) nejsme schopni takovéto explicitní řešení nalézt. I přesto bychom chtěli danou rovnici alespoň v rámci jisté přesnosti vyřešit. Je to možné?

V tomto článku si nejprve ukážeme několik tzv. numerických (přibližných) algoritmů pro hledání řešení zadaných rovnic pomocí počítače. Poté si ukažme zajímavé příklady, kde nám středoškolské kuchařky pro řešení různých typů rovnic (trigonometrické, exponenciální, polynomiální) budou platné jako mrtvému zimník.

Základní metody pro hledání nulových bodů funkcí

Soustřeďme se nyní na řešení úlohy nalézt řešení rovnice f(x)=0, kde f je předem daná reálná funkce reálné proměnné. O této funkci předpokládáme, že je definována na jistém intervalu J.

Následující metody ukazují různé strategie, jak se snažit hledat řešení uvedené rovnice (o kterém v tento moment ani nevíme jestli existuje). Každá z metod může na různých příkladech vykazovat různé výsledky. Zdůrazněme, že se soustředíme na hledání alespoň jednoho řešení. Nezabýváme se otázkou, jak nalézt všechny, je-li jich více. Bez hlubší analýzy funkce f a znalosti jejích vlastností toho nelze příliš mnoho tvrdit.

Bisekce (půlení)

Vstupem této metody jsou dva body (čísla) a0 a b0, a0<b0, z intervalu J. Funkční hodnoty funkce f v bodech a0 a b0 jsou nenulové (jinak jsme úlohu vyřešili) a mají různé znaménko. Tuto podmínku můžeme elegantně vyjádřit požadavkem, aby f(a0)f(b0)<0.

Nyní uvažme bod c uprostřed mezi a0 a b0, tj. c=a0+b02. Pokud náhodou (to se typicky nestane) f(c)=0, pak jsme úlohu vyřešili. Pokud tato situace nenastala, pak f(c) je buď kladné nebo záporné. To znamená, že buď f(a0) a f(c) mají různá znaménka, nebo f(c) a f(b0) mají různá znaménka. V prvním případě položíme a1:=a0 a b1:=c, ve druhém pak a1:=c a b1=b0. Tato situace je graficky znázorněna na následujícím obrázku:

Koreny bisection

Obrázek č. 1: Znázornění principu bisekční metody pro hledání řešení rovnice f(x)=0. Začneme s intervalem a0,b0 majícím na krajích různá znaménka funkčních hodnot a vybereme půlku tohoto intervalu a1,b1 tak, aby znaménka funkčních hodnot byla stále různá.

Dále celý proces opakujeme s a1 a b1 místo a0 a b0 a tak dále. Tím získáváme posloupnosti (an)n=1 a (bn)n=1, pro něž platí (skutečně, v každém kroku nový krajní bod leží uprostřed starých krajních bodů) 0<bnan=ba2n. V případě, že jsme se v některém z kroků prostředním bodem trefili do kořene funkce f, tak je již úloha vyřešena (viz popis kroku algoritmu, resp. konstrukce bodu c, výše). Obě posloupnosti jsou navíc monotónní a konvergují ke stejné limitě x. Tento bod, x, leží v každém z intervalů an,bna,b. Pokud je funkce f navíc spojitá, pak lze ukázat, že x splňuje f(x)=0 a je tedy námi hledaným řešení původního problému.

Podstatnou výhodou této metody je její konvergence a kontrola chyby. Body které konstruujeme se neustále přibližují z obou stran k hledanému řešení.

Nevýhodou této metody je její relativně pomalá rychlost konvergence. Konkrétní ukázku nalezne čtenář na konci tohoto článku.

Regula falsi

Princip této metody je stejný jako u metody bisekce. Jediným rozdílem je způsob volby dělícího bodu intervalu. Bisekce ho volí uprostřed daného intervalu, regula falsi k tomu účelu využívá lineární interpolaci funkce f na daném intervalu.

Mějme tedy opět zadány dva body a0<b0 v intervalu J a předpokládejme opět různost znamének f(a0) a f(b0). Lineární interpolací mezi body (a0,f(a0)) a (b0,f(b0)) je přímka s rovnicí y=f(b0)f(a0)b0a0(xa0)+f(a0). Tato přímka protíná osu x v bodě (c,0). Po přímočarých algebraických úpravách toto c snadno spočteme, c=a0f(b0)b0f(a0)f(b0)f(a0). Dále pokračujeme jako u metody bisekce. Tedy na základě hodnoty f(c) buď hledání ukončíme, nebo klademe a1=a0 a b1=c pokud f(a0)f(c)<0, nebo a1=c a b1=b0 pokud f(c)f(b0)<0. Pro ilustraci uvádíme obrázek.

Koreny regula falsi

Obrázek č. 2: Znázornění principu metody regula falsi pro hledání řešení rovnice f(x)=0. Začneme s intervalem a0,b0 majícím na krajích různá znaménka funkčních hodnot. Interval rozdělíme pomocí lineární interpolace funkce (znázorněna červenou barvou) a vybereme část tohoto intervalu a1,b1 tak, aby znaménka funkčních hodnot byla stále různá.

Regula falsi má podobné vlastnosti jako metoda bisekce. Za předpokladu spojitosti funkce f a různosti znamének funkčních hodnot na krajích intervalu je konvergentní a řešení leží v počátečním intervalu. Konvergenci lze očekávat o něco rychlejší než v případě bisekce.

Newtonova metoda

Tato metoda vyžaduje vyhodnocování nejen funkčních hodnot funkce f, ale i její derivace f. K vylepšení aproximace řešení rovnice f(x)=0 totiž použijeme tečnu ke grafu funkce f. Uživatel tedy musí derivaci zadat, nebo bychom ji museli odhadovat (touto komplikovanější variantou se zde zabývat nebudeme; navíc lze v tomto případě použít metodu sečny uvedenou vzápětí). Dále máme na vstupu zadán jeden bod a0 představující první aproximaci řešení naší úlohy.

Nejprve sestrojíme tečnu grafu funkce f v bodě (a0,f(a0)). Tato tečna je přímka daná rovnicí y=f(a0)(xa0)+f(a0). Průsečík této přímky s osou x je dán vzorcem (za předpokladu nenulovosti f(a0)) (2)a1:=a0f(a0)f(a0). Nyní tento proces opakujeme s a1 místo a0.

Koreny newton

Obrázek č. 3: Znázornění principu Newtonovy metody pro hledání řešení rovnice f(x)=0. Aproximaci řešení a0 se snažíme vylepšit posunutím do průsečíku (a1,0) tečny ke grafu funkce f v bodě (a0,f(a0)) (znázorněna červenou barvou) s osou x.

Tímto způsobem se pokoušíme zkonstruovat posloupnost (an)n=0, o které doufáme, že konverguje k hledanému řešení úlohy f(x)=0.

Newtonova metoda trpí několika neduhy. Algoritmus konstrukce této posloupnosti může selhat, například pokud derivace ve jmenovateli rekurentního vzorce je nulová (či velmi blízká nule v rámci pracovní přesnosti), nebo když průsečík tečny s osou x padne mimo definiční obor naší funkce. Konvergence posloupnosti není zaručena. Přímo z konstrukce členů posloupnosti (an)n=0 neplyne žádná možnost jejich kontroly. Lze zkonstruovat případy, kdy zkonstruovaná posloupnost konverguje nebo je dokonce periodická.

Optimisticky lze ale říci, že začneme-li s prvním bodem a0 blízko skutečného řešení, pak Newtonova metoda konverguje velmi rychle. Viz praktické ukázky níže.

Metoda sečny

Metoda sečny je variace Newtonovy metody pro funkce f, které nejsou diferencovatelné, nebo pro které nemáme možnost počítat derivaci (uživatel ji nezadal nebo je funkce zadána tak komplikovaně, že není jednoduché spočítat její derivaci), či je to výpočetně výrazně náročnější než vyhodnocení funkční hodnoty. Místo tečny v Newtonově metodě použijeme sečnu.

Na vstupu je tedy zadána funkce f a dva body a0 a b0. Sestrojíme sečnu grafu funkce f procházející body (a0,f(a0)) a (b0,f(b0)). Tato přímka je dána rovnicí y=f(b0)f(a0)b0a0(xb0)+f(b0). Průsečíkem této přímky s osou x je bod (c,0), kde (3)c=b0b0a0f(b0)f(a0)f(b0). Položíme b1:=c a a1:=b0 a celý proces opakujeme s a1,b1 místo a0,b0.

Koreny secant

Obrázek č. 4: Znázornění principu metody sečny pro hledání řešení rovnice f(x)=0. Sečna je znázorněna červeně.

U této metody si sice pamatujeme dva body, ale na rozdíl od metody bisekce a regula falsi hledané řešení neleží nutně mezi nimi. Jedná se vlastně o diskrétní variantu Newtonovy metody (derivaci v ní nahrazujeme diferencí, porovnejte rovnici (2) a (3)).

I u této metody nemáme přílišnou kontrolu nad chováním zkonstruované posloupnosti. Obecně o ní platí podobné poznámky jako v případě Newtonovy metody.

Kritérium pro zastavení

V praktické implementaci nelze výše uvedené metody provádět až do nekonečna (všechny čtyři metody dávají nekonečné posloupnosti, o kterých doufáme, že konvergují k hledanému řešení).

Je nutné výpočet ve vhodný okamžik ukončit, jinak jsme pouze implementovali nekonečnou smyčku. K zastavení lze použít například následující kritéria:

  • pokud pro poslední aproximaci řešení, ozn. c, je |f(c)| dostatečně malé (typicky závisí na zvolené přesnosti výpočtu),
  • u bisekce a regula falsi lze skončit pokud poslední sestrojený interval (a,b) je dostatečně krátký.

Dále bývá dobrým zvykem v implementaci algoritmu nastavit jistý maximální povolený počet iterací. Pokud do tohoto maximálního počtu iterací nedosáhneme zastavovací podmínky, pak vrátíme chybu a ohlásíme selhání pokusu o nalezení řešení.

Příklady použití

Naplňování nádrží (*Water filling*)

Představme si, že máme n vzájemně propojených nádrží s dny v různých výškách a různými plochami den. Dále máme zadáno množství vody, které do systému vpustíme. Otázkou je, jak vysoko se vyrovná hladina vody v nádržích. Alternativně lze o této úloze uvažovat jako o optimalizační úloze, při níž se snažíme rovnoměrně distribuovat jistou veličinu mezi různě zatížené a různě kapacitní kanály (pro jednoduchost se budeme držet vodní interpretace, ve které ale není úplně jednoduché si představit vzájemné propojení kanálů: trubky je spojující jsou zavedeny vždy u dna nádrže a objem vody v trubkách zanedbáváme). Popisovaná situace je znázorněna na obrázku 5.

Nechť je tedy zadáno nN nezáporných konstant α1,,αn0. Tyto konstanty reprezentují jak vysoko jsou dna nádrží umístěna (viz obrázek 5). Dále nechť je zadáno n kladných konstant β1,,βn>0. Tyto konstanty reprezentují obsah podstav nádrží. Do soustavy napustíme vodu o objemu V>0 a ptáme se na jaké hladině h0 se voda vyrovná a jak bude v jednotlivých nádržích.

Je-li hladina ve výšce h, pak v ité nádrži je βimax(0,hαi) vody. Rozeberme toto tvrzení podrobněji. Funkce max vrací větší z obou jejích argumentů. Výraz výše je nulový pokud je dno výše než hladina (výraz hαi je pak záporný). V opačném případě kdy hαi0 představuje hloubku vodního sloupce v ité nádrži a přenásobením βi získáme objem vody v této nádrži.

Hledaná hladina h proto musí splňovat i=1nβimax(0,hαi)=V. Alternativně, h je řešením rovnice (4)g(h):=Vi=1nβimax(0,hαi)=0 Povšimněme si, že g(0)=V a limhg(h)=. Funkce g je navíc klesající a spojitá. Úloha (4) má tedy právě jedno řešení, které můžeme nalézt vhodně zvolenou numerickou metodou. Na následujícím obrázku je znázorněna jedna konkrétně zvolená situace.

Water filling

Obrázek č. 5: Ilustrace a řešení problému naplňování nádrží s pěti nádržemi a β1=β2=β4=1, β3=2, β5=32, α=15, β2=35, β3=310, β4=14, β5=32 a V=1110. Pomocí metody sečny s počátečním a0=0 a b0=2210 ve čtyřech iteracích najdeme h=12 s přesností 1016.

Pro zajímavost uveďme graf funkce g z konkrétního příkladu uvedeného v předchozím obrázku 5.

Water filling g

Obrázek č. 6: Obrázek funkce g odpovídající situaci uvedené v obrázku 5.

Rychlá reciproká druhá odmocnina (*Fast inverse square root*)

Newtonova metoda je využita v implementaci funkce f(x)=1x ve známe počítačové hře Quake III Arena. Tuto funkci je třeba opakovaně vyhodnocovat při tzv. normalizaci vektoru (podělení vektoru jeho délkou), což je operace prováděná v počítačové grafice velmi často. Newtonova metoda s dobrou první aproximací konverguje velmi rychle a proto se na tento úkol díky této své efektivitě hodí.

Příslušná cenzurovaná část kódu vypadá následovně:

float Q_rsqrt( float number )
{
  long i;
  float x2, y;
  const float threehalfs = 1,5F;

  x2 = number * 0,5F;
  y  = number;
  i  = * ( long * ) &y;                       // evil floating point bit level hacking
  i  = 0x5f3759df - ( i >> 1 );               // what the ****?
  y  = * ( float * ) &i;
  y  = y * ( threehalfs - ( x2 * y * y ) );   // 1st iteration
//  y  = y * ( threehalfs - ( x2 * y * y ) );   // 2nd iteration, this can be removed

  return y;
}

První část kódu (až před řádek s komentářem // 1st iteration) spočívá v nalezení první aproximace pro Newtonovu metodu. Tuto část nebudeme podrobněji rozebírat, zájemce odkazujeme na již dříve zmíněnou stránku. Poznamenejme, že se využívá znalosti tvaru strojového čísla a uvedený kód je optimalizován pro 32 bitový datový typ (odtud plyne i hodnota oné magické konstanty). Těsně před koncem těla funkce se provede jeden krok Newtonovy metody (druhý krok je zakomentovaný, protože přesnost získaná v jednom kroku z vhodné počáteční aproximace je prakticky dostatečná).

Skutečně, rovnice f(c)=1c=x pro zadané c>0 a neznámé x>0 je ekvivalentní rovnici (5)g(x)=c1x2=0. Derivací funkce g je g(x)=2x3 a rekurentní vzorec pro Newtonovu metodu odpovídající úloze (5) proto je xn+1=xng(xn)g(xn)=xnc1xn22xn3=32xncxn32, což přesně odpovídá zmíněné části kódu (kde si je jen potřeba dát pozor na použité škálování).

Porovnání metod

Porovnejme uvedené metody na několika jednoduchých konkrétních příkladech.

Hledání druhé odmocniny ze dvou

Jako testovací jednoduchý problém si zvolíme hledání druhé odmocniny ze dvou, tj. numerické hodnoty 2. Toto číslo je kladným řešením rovnice f(x):=x22=0. Postupně použijeme počáteční nastavení:

  • Bisekce: počáteční interval 1,2,
  • *Regula falsi*: počáteční interval 1,2,
  • Newtonova metoda: první aproximace 1,
  • Metoda sečny: první dvě aproximace 1 a 2.

Výpočet ve všech případech ukončíme pokud absolutní hodnota poslední aproximace je menší než ε=1,4901161193847656108. Ve všech čtyřech případech použijeme aritmetiku 64 bitových čísel s pohyblivou desetinnou čárkou (tj. tzv. *double*).

Shrnutí výsledků je následující (správné cifry jsou označeny pro přehlednost tučně):

  • Bisekce: 1,4142135605216026 (27 iterací)
  • Regula falsi*: **1,41421356*05326258 (11 iterací)
  • Newtonova metoda: 1,4142135623746899 (5 iterací)
  • Metoda sečny: 1,4142135626888697 (5 iterací)
  • Známá hodnota s přesností na 17 cifer: 1,4142135623730950

Pro zájemce uvádíme i vyčerpávající tabulku s jednotlivými kroky algoritmů. Nejprve pro metodu bisekce.

# a b c |f(c)|
1 1,02,01,50,25
2 1,01,51,250,4375
3 1,251,51,3750,109375
4 1,3751,51,43750,06640625
5 1,3751,43751,406250,0224609375
6 1,406251,43751,4218750,021728515625
7 1,406251,4218751,41406250,00042724609375
8 1,41406251,4218751,417968750,0106353759765625
9 1,41406251,417968751,4160156250,005100250244140625
10 1,41406251,4160156251,41503906250,0023355484008789062
11 1,41406251,41503906251,414550781250,0009539127349853516
12 1,41406251,414550781251,4143066406250,0002632737159729004
13 1,41406251,4143066406251,41418457031258,200109004974365e-5
14 1,41418457031251,4143066406251,414245605468759,063258767127991e-5
15 1,41418457031251,414245605468751,4142150878906254,314817488193512e-6
16 1,41418457031251,4142150878906251,41419982910156253,8843369111418724e-5
17 1,41419982910156251,4142150878906251,41420745849609381,726433401927352e-5
18 1,41420745849609381,4142150878906251,41421127319335946,474772817455232e-6
19 1,41421127319335941,4142150878906251,41421318054199221,0799813026096672e-6
20 1,41421318054199221,4142150878906251,41421413421630861,6174171832972206e-6
21 1,41421318054199221,41421413421630861,41421365737915042,687177129701013e-7
22 1,41421318054199221,41421365737915041,41421341896057134,056318516632018e-7
23 1,41421341896057131,41421365737915041,41421353816986086,845708355740499e-8
24 1,41421353816986081,41421365737915041,41421359777450561,0013031115363447e-7
25 1,41421353816986081,41421359777450561,41421356797218321,583661290993632e-8
26 1,41421353816986081,41421356797218321,4142135530710222,6310235545778937e-8
27 1,4142135530710221,41421356797218321,41421356052160265,236811428943611e-9

Nyní pro metodu regula falsi.

# a b c |f(c)|
1 1,02,01,33333333333333330,22222222222222232
2 1,33333333333333332,01,40,04000000000000026
3 1,42,01,4117647058823530,006920415224913157
4 1,4117647058823532,01,41379310344827580,0011890606420930094
5 1,41379310344827582,01,4141414141414140,00020406081012214194
6 1,4141414141414142,01,41420118343195263,501277966488914e-5
7 1,41420118343195262,01,414211438474876,007286838860537e-6
8 1,414211438474872,01,41421319796954341,030688757230891e-6
9 1,41421319796954342,01,41421349985132321,7683827158165855e-7
10 1,41421349985132322,01,41421355164605483,034065154672305e-8
11 1,41421355164605482,01,41421356053262585,2056330357430625e-9

Nyní, podstatně rychlejší, Newtonova metoda.

# a |f(a)|
1 1,01,0
2 1,50,25
3 1,41666666666666670,006944444444444642
4 1,41421568627450996,007304882871267e-6
5 1,41421356237468994,510614104447086e-12

A konečně metoda sečny.

# a b c |f(c)|
1 1,02,01,33333333333333350,22222222222222188
2 1,33333333333333351,01,42857142857142860,04081632653061229
3 1,42857142857142861,33333333333333351,41379310344827580,0011890606420930094
4 1,41379310344827581,42857142857142861,414211438474876,007286838860537e-6
5 1,414211438474871,41379310344827581,41421356268886978,931455575122982e-10

Z výpočtů je vidět, že bisekce a regula falsi konvergují nejpomaleji. Naopak Newtonova metoda a metoda sečny dosáhnou řeší v požadované přesnosti v podstatně menším počtu iterací.


Tento článek byl vznikl v rámci řešení projektu Institucionální podpora Českého vysokého učení technického v Praze (CZ.02.2.69/0.0/0.0/16_015/0002382).


Diskuze