MN14: Różnice pomiędzy wersjami
Nie podano opisu zmian |
|||
Linia 1: | Linia 1: | ||
<!-- | |||
Konwertowane z pliku LaTeX przez latex2mediawiki, zob. http://www.ii.uj.edu.pl/ pawlik1/latex2mediawiki.php. | |||
Niezb�dne rozszerzenia i modyfikacje oryginalnego latex2mediawiki | |||
wprowadzi� przykry@mimuw.edu.pl | |||
--> | |||
=Całkowanie= | =Całkowanie= | ||
{{powrot |Metody numeryczne | do strony głównej | |||
przedmiotu <strong>Metody numeryczne</strong>}} | |||
Zajmiemy się teraz zadaniem całkowania numerycznego. | Zajmiemy się teraz zadaniem całkowania numerycznego. | ||
Linia 11: | Linia 21: | ||
<math>\displaystyle F</math> funkcji rzeczywistych określonych i całkowalnych w | <math>\displaystyle F</math> funkcji rzeczywistych określonych i całkowalnych w | ||
sensie Riemanna na całym przedziale <math>\displaystyle [a,b]</math>. | sensie Riemanna na całym przedziale <math>\displaystyle [a,b]</math>. | ||
Każdy, kto przeszedł przez [[Analiza_matematyczna_1/Wykład_14:_Całka_Riemanna_funkcji_jednej_zmiennej|kurs całkowania]] wie, że obliczanie całek rozumiane jako znalezienie elementarnego wzoru na funkcję pierwotną może być trudne, bardzo trudne, a nawet niewykonalne. Tymczasem zadanie <strong>przybliżonego</strong> wyznaczenia wartości całki daje się w dużej mierze zautomatyzować z całkiem dobrym skutkiem. | |||
Obliczanie całek jest wymagane w bardzo wielu zadaniach inżynierskich i naukowych. Całki z funkcji (bardzo) wielu zmiennych (które na swój sposób są szczególnie trudne do obliczenia) znajdują ważne zastosowania w bankowości i finansach. | |||
Będziemy zakładać, że mamy możliwość obliczania | Będziemy zakładać, że mamy możliwość obliczania | ||
wartości funkcji <math>\displaystyle f</math>, a w niektórych przypadkach | wartości funkcji <math>\displaystyle f</math>, a w niektórych przypadkach | ||
również jej pochodnych o ile istnieją. Dokładna | również jej pochodnych, o ile istnieją. Dokładna | ||
całka <math>\displaystyle S(f)</math> będzie więc w ogólności przybliżana | całka <math>\displaystyle S(f)</math> będzie więc w ogólności przybliżana | ||
wartością <math>\displaystyle A(f)</math>, która zależy tylko od wartości <math>\displaystyle f</math> | wartością <math>\displaystyle A(f)</math>, która zależy tylko od wartości <math>\displaystyle f</math> | ||
i | i ew. jej pochodnych w skończonej liczbie punktów. | ||
==Kwadratury== | ==Kwadratury== | ||
Linia 47: | Linia 61: | ||
od danej informacji o <math>\displaystyle f</math>, otrzymana w ten sposób wartość | od danej informacji o <math>\displaystyle f</math>, otrzymana w ten sposób wartość | ||
też będzie zależeć tylko od tej informacji, a w | też będzie zależeć tylko od tej informacji, a w | ||
konsekwencji funkcjonał wynikowy będzie | konsekwencji funkcjonał wynikowy będzie postaci | ||
ja wyżej. Są to tzw. kwadratury interpolacyjne. | |||
{{definicja||| | {{definicja||| | ||
Linia 59: | Linia 73: | ||
gdzie <math>\displaystyle w_f</math> jest wielomianem interpolacyjnym funkcji <math>\displaystyle f</math> | gdzie <math>\displaystyle w_f</math> jest wielomianem interpolacyjnym funkcji <math>\displaystyle f</math> | ||
stopnia co najwyżej <math>\displaystyle n</math> opartym na tych węzłach. | stopnia co najwyżej <math>\displaystyle n</math>, opartym na tych węzłach. | ||
}} | }} | ||
Linia 84: | Linia 98: | ||
Podamy teraz kilka przykładów. | Podamy teraz kilka przykładów. | ||
<strong>Kwadratura prostokątów</strong> jest oparta na jednym węźle | <strong>Kwadratura prostokątów</strong> jest oparta na jednym węźle | ||
<math>\displaystyle x_0=(a+b)//2</math>, | <math>\displaystyle x_0=(a+b)//2</math>, | ||
Linia 91: | Linia 104: | ||
</math></center> | </math></center> | ||
<strong>Kwadratura trapezów</strong> jest oparta na jednokrotnych | <strong>Kwadratura trapezów</strong> jest oparta na jednokrotnych | ||
węzłach <math>\displaystyle x_0=a</math>, <math>\displaystyle x_1=b</math> i jest równa polu odpowiedniego | węzłach <math>\displaystyle x_0=a</math>, <math>\displaystyle x_1=b</math> i jest równa polu odpowiedniego | ||
Linia 99: | Linia 111: | ||
</math></center> | </math></center> | ||
<strong>Kwadratura parabol (Simpsona)</strong> jest oparta na | <strong>Kwadratura parabol (Simpsona)</strong> jest oparta na | ||
jednokrotnych węzłach <math>\displaystyle x_0=a</math>, <math>\displaystyle x_1=b</math>, <math>\displaystyle x_2=(a+b)//2</math>, | jednokrotnych węzłach <math>\displaystyle x_0=a</math>, <math>\displaystyle x_1=b</math>, <math>\displaystyle x_2=(a+b)//2</math>, | ||
Linia 123: | Linia 134: | ||
{{twierdzenie||| | {{twierdzenie||| | ||
Niech <math>\displaystyle Q^I</math> będzie kwadraturą | |||
Niech <math>\displaystyle Q^I</math> będzie kwadraturą | |||
interpolacyjną opartą na (jednokrotnych lub wielokrotnych) | interpolacyjną opartą na (jednokrotnych lub wielokrotnych) | ||
węzłach <math>\displaystyle x_i</math>, <math>\displaystyle 0\le i\le n</math>. Jeśli <math>\displaystyle f\in F^n_M([a,b])</math> | węzłach <math>\displaystyle x_i</math>, <math>\displaystyle 0\le i\le n</math>. Jeśli <math>\displaystyle f\in F^n_M([a,b])</math> to | ||
<center><math>\displaystyle | <center><math>\displaystyle | ||
Linia 131: | Linia 143: | ||
</math></center> | </math></center> | ||
W klasie <math>\displaystyle F^n_M([a,b])</math> maksymalny błąd kwadratury <math>\displaystyle Q^I</math> | W klasie <math>\displaystyle F^n_M([a,b])</math>, maksymalny błąd kwadratury <math>\displaystyle Q^I</math> | ||
wynosi | wynosi | ||
Linia 140: | Linia 152: | ||
}} | }} | ||
''Dowód''\quad Korzystając ze znanego nam już wzoru na | ''Dowód''\quad Korzystając ze znanego nam już wzoru na | ||
błąd interpolacji wielomianowej z Lematu [[##leblint|Uzupelnic: leblint ]], mamy | błąd interpolacji wielomianowej z Lematu [[##leblint|Uzupelnic: leblint ]], mamy | ||
Linia 189: | Linia 200: | ||
{{twierdzenie||| | {{twierdzenie||| | ||
Jeśli <math>\displaystyle f\in C^{(2)}([a,b])</math> | |||
to dla kwadratury trapezów mamy | to dla kwadratury trapezów mamy | ||
Linia 195: | Linia 207: | ||
</math></center> | </math></center> | ||
Jeśli <math>\displaystyle f\in C^{(4)}([a,b])</math> to dla kwadratury | |||
parabol mamy | parabol mamy | ||
Linia 204: | Linia 216: | ||
}} | }} | ||
''Dowód''\quad (i) Ze wzoru ([[##blkwad|Uzupelnic: blkwad ]]) | ''Dowód''\quad (i) Ze wzoru ([[##blkwad|Uzupelnic: blkwad ]]) | ||
Linia 213: | Linia 224: | ||
wielomian <math>\displaystyle (x-a)(x-b)</math> przyjmuje jedynie wartości | wielomian <math>\displaystyle (x-a)(x-b)</math> przyjmuje jedynie wartości | ||
nieujemne, można zastosować twierdzenie o wartości | nieujemne, można zastosować twierdzenie o wartości | ||
średniej dla całki aby otrzymać | średniej dla całki, aby otrzymać | ||
<center><math>\displaystyle \aligned S(f)\,-\,T(f) &= f(a,b,c)\int_a^b (x-a)(x-b)\,dx \\ | <center><math>\displaystyle \aligned S(f)\,-\,T(f) &= f(a,b,c)\int_a^b (x-a)(x-b)\,dx \\ | ||
Linia 221: | Linia 232: | ||
dla pewnych <math>\displaystyle c,\xi_1\in [a,b]</math>. | dla pewnych <math>\displaystyle c,\xi_1\in [a,b]</math>. | ||
(ii) Niech <math>\displaystyle w_{f,2}\in\Pi_2</math> i <math>\displaystyle w_{f,3}\in\Pi_3</math> będą | (ii) Niech <math>\displaystyle w_{f,2}\in\Pi_2</math> i <math>\displaystyle w_{f,3}\in\Pi_3</math> będą | ||
wielomianami interpolacyjnymi funkcji <math>\displaystyle f</math> odpowiednio dla | wielomianami interpolacyjnymi funkcji <math>\displaystyle f</math> odpowiednio dla | ||
Linia 296: | Linia 306: | ||
{{twierdzenie||| | {{twierdzenie||| | ||
Błąd kwadratury złożonej | |||
Błąd kwadratury złożonej | |||
<math>\displaystyle \bar Q(f)</math> w klasie <math>\displaystyle F^r_M([a,b])</math> jest ograniczony przez | <math>\displaystyle \bar Q(f)</math> w klasie <math>\displaystyle F^r_M([a,b])</math> jest ograniczony przez | ||
Linia 311: | Linia 322: | ||
}} | }} | ||
''Dowód''\quad Twierdzenie to jest bezpośrednim | ''Dowód''\quad Twierdzenie to jest bezpośrednim | ||
wnioskiem z Twierdzenia [[##twblkw|Uzupelnic: twblkw ]]. Mamy bowiem | wnioskiem z Twierdzenia [[##twblkw|Uzupelnic: twblkw ]]. Mamy bowiem | ||
Linia 324: | Linia 334: | ||
co kończy dowód. <math>\displaystyle \quad\Box</math> | co kończy dowód. <math>\displaystyle \quad\Box</math> | ||
W klasie <math>\displaystyle F^r_M([a,b])</math> błąd kwadratur złożonych | W klasie <math>\displaystyle F^r_M([a,b])</math>, błąd kwadratur złożonych | ||
jest rzędu <math>\displaystyle n^{-(r+1)}</math>, czyli jest taki sam jak | jest rzędu <math>\displaystyle n^{-(r+1)}</math>, czyli jest taki sam jak | ||
błąd interpolacji kawałkami wielomianowej. I tak | błąd interpolacji kawałkami wielomianowej. I tak | ||
Linia 353: | Linia 363: | ||
{{twierdzenie||| | {{twierdzenie||| | ||
Jeśli <math>\displaystyle f\in C^{(2)}([a,b])</math> to | |||
<center><math>\displaystyle S(f)\,-\,\bar T_k(f)\,=\,-\frac{(b-a)^2}{12\,k^2} | <center><math>\displaystyle S(f)\,-\,\bar T_k(f)\,=\,-\frac{(b-a)^2}{12\,k^2} | ||
f^{(2)}(\xi_1). | f^{(2)}(\xi_1). | ||
</math></center> | </math></center> | ||
Jeśli <math>\displaystyle f\in C^{(4)}([a,b])</math> to | |||
<center><math>\displaystyle S(f)\,-\,\bar P_k(f)\,=\,-\frac{(b-a)^4}{2280\,k^4} | <center><math>\displaystyle S(f)\,-\,\bar P_k(f)\,=\,-\frac{(b-a)^4}{2280\,k^4} | ||
Linia 413: | Linia 424: | ||
pożądaną dokładność, zob. U. [[##kwas|Uzupelnic: kwas ]]. | pożądaną dokładność, zob. U. [[##kwas|Uzupelnic: kwas ]]. | ||
Jeśli funkcja jest więcej niż dwa razy różniczkowalna | Jeśli funkcja jest więcej niż dwa razy różniczkowalna | ||
użycie złożonych kwadratur trapezów zdaje się tracić | to użycie złożonych kwadratur trapezów zdaje się tracić | ||
sens. Wtedy istnieją przecież kwadratury, których błąd | sens. Wtedy istnieją przecież kwadratury, których błąd | ||
maleje do zera szybciej niż <math>\displaystyle n^{-2}</math>. Okazuje się jednak, | maleje do zera szybciej niż <math>\displaystyle n^{-2}</math>. Okazuje się jednak, | ||
Linia 424: | Linia 435: | ||
[[grafika:Euler.jpg|thumb|right||Leonhard Euler<br> [[Biografia Euler|Zobacz biografię]]]] | [[grafika:Euler.jpg|thumb|right||Leonhard Euler<br> [[Biografia Euler|Zobacz biografię]]]] | ||
[[grafika:Maclaurin.jpg|thumb|right|| Maclaurin<br> [[Biografia | [[grafika:Maclaurin.jpg|thumb|right||Colin Maclaurin<br> [[Biografia Maclaurin|Zobacz biografię]]]] | ||
{{lemat|Formuła Eulera-Maclaurina|| | {{lemat|Formuła Eulera-Maclaurina|Formuła Eulera-Maclaurina| | ||
Dla funkcji <math>\displaystyle f\in C^{(2m+2)}([a,b])</math> błąd złożonej | Dla funkcji <math>\displaystyle f\in C^{(2m+2)}([a,b])</math>, błąd złożonej | ||
kwadratury trapezów <math>\displaystyle \bar T_k</math> wyraża się wzorem | kwadratury trapezów <math>\displaystyle \bar T_k</math> wyraża się wzorem | ||
Linia 485: | Linia 496: | ||
Wtedy, dla <math>\displaystyle f\in F^{2m+1}_M([a,b])</math>, rząd zbieżności | Wtedy, dla <math>\displaystyle f\in F^{2m+1}_M([a,b])</math>, rząd zbieżności | ||
kwadratury <math>\displaystyle \bar T^m_k</math> wynosi <math>\displaystyle k^{-(2m+2)}</math>. Rzeczywiście | kwadratury <math>\displaystyle \bar T^m_k</math> wynosi <math>\displaystyle k^{-(2m+2)}</math>. Rzeczywiście, | ||
sprawdziliśmy, że jest to prawdą dla <math>\displaystyle m=0,1</math>. Niech <math>\displaystyle m\ge 2</math>. | sprawdziliśmy, że jest to prawdą dla <math>\displaystyle m=0,1</math>. Niech <math>\displaystyle m\ge 2</math>. | ||
Postępując indukcyjnie ze względu na <math>\displaystyle s=1,2,\ldots,m</math> mamy | Postępując indukcyjnie ze względu na <math>\displaystyle s=1,2,\ldots,m</math> mamy | ||
Linia 519: | Linia 530: | ||
Zauważmy jeszcze, że <math>\displaystyle \bar T^m_k</math> wykorzystuje | Zauważmy jeszcze, że <math>\displaystyle \bar T^m_k</math> wykorzystuje | ||
<math>\displaystyle n=k2^m+1</math> wartości <math>\displaystyle f</math> w punktach równoodległych | <math>\displaystyle n=k2^m+1</math> wartości <math>\displaystyle f</math> w punktach równoodległych | ||
na <math>\displaystyle [a,b]</math> | na <math>\displaystyle [a,b]</math> co oznacza, że w terminach <math>\displaystyle n</math> rząd | ||
zbieżności wynosi też <math>\displaystyle n^{-(2m+2)}</math>, a więc jest | zbieżności wynosi też <math>\displaystyle n^{-(2m+2)}</math>, a więc jest | ||
optymalny w klasie <math>\displaystyle F^{2m+1}_M([a,b])</math>. | optymalny w klasie <math>\displaystyle F^{2m+1}_M([a,b])</math>. | ||
Kwadratury <math>\displaystyle \bar T^s_k</math> nazywane są <strong>kwadraturami | Kwadratury <math>\displaystyle \bar T^s_k</math> nazywane są <strong>kwadraturami | ||
Romberga</strong>. Dla danej funkcji <math>\displaystyle f</math> można je łatwo | Romberga</strong>. Dla danej funkcji <math>\displaystyle f</math>, można je łatwo | ||
konstruować budując następującą tablicę trójkątną: | konstruować budując następującą tablicę trójkątną: | ||
Linia 543: | Linia 554: | ||
w której pierwsza kolumna jest tworzona indukcyjnie | w której pierwsza kolumna jest tworzona indukcyjnie | ||
zgodnie ze wzorem ([[##indtrap|Uzupelnic: indtrap ]]), a kolejne zgodnie | zgodnie ze wzorem ([[##indtrap|Uzupelnic: indtrap ]]), a kolejne zgodnie | ||
z ([[##indRom|Uzupelnic: indRom ]]). | z ([[##indRom|Uzupelnic: indRom ]]). | ||
==Biblioteki== | ==Biblioteki== | ||
Linia 558: | Linia 569: | ||
<div style="margin-top:1em; padding-top,padding-bottom:1em;"> | <div style="margin-top:1em; padding-top,padding-bottom:1em;"> | ||
<span style="font-variant:small-caps;">Przykład: Prosta całka funkcji jednej zmiennej</span> | <span style="font-variant:small-caps;">Przykład: Prosta całka funkcji jednej zmiennej</span> | ||
<div class="solution"> | <div class="solution" style="margin-left,margin-right:3em;"> | ||
Przypuśćmy, że chcemy obliczyć całkę <math>\displaystyle I = \int_0^1 F(x)\, dx</math>, | Przypuśćmy, że chcemy obliczyć całkę <math>\displaystyle I = \int_0^1 F(x)\, dx</math>, | ||
Linia 564: | Linia 575: | ||
implementujemy <math>\displaystyle F</math> w Octave: | implementujemy <math>\displaystyle F</math> w Octave: | ||
<div | <div style="margin: 1em; padding:1em; color: #006; background-color:#fcfcfc;"><pre>function y = F(x) | ||
function y = F(x) | |||
y = sin(23*x)+1/sqrt(1-x^2); | y = sin(23*x)+1/sqrt(1-x^2); | ||
endfunction | endfunction | ||
</pre></div> | </pre></div> | ||
Aby teraz obliczyć całkę <math>\displaystyle I = \int_0^1 F(x)\, dx</math>, wystarczy wywołać | Aby teraz obliczyć całkę <math>\displaystyle I = \int_0^1 F(x)\, dx</math>, wystarczy wywołać | ||
<div | <div style="margin: 1em; padding:1em; color: #006; background-color:#fcfcfc;"><pre>I = quad("F", 0, 1); | ||
</pre></div> | |||
I = quad("F", 0, 1); | |||
</pre></div> | |||
</div></div> | </div></div> | ||
W rzeczywistości, podobnie jak w przypadku funkcji <code>fsolve</code>, funkcja | W rzeczywistości, podobnie jak w przypadku funkcji <code style="color: #006">fsolve</code>, funkcja | ||
<code>quad</code> zwraca więcej informacji, można jej także przekazać dodatkowe | <code style="color: #006">quad</code> zwraca więcej informacji, można jej także przekazać dodatkowe | ||
parametry. I tak, jeśli chcemy ustawić poziom tolerancji błędu obliczenia | parametry. I tak, jeśli chcemy ustawić poziom tolerancji błędu obliczenia | ||
całki: | całki: | ||
Linia 592: | Linia 599: | ||
przekazując jej te parametry następująco: | przekazując jej te parametry następująco: | ||
<div | <div style="margin: 1em; padding:1em; color: #006; background-color:#fcfcfc;"><pre>quad("F", 0, 1, [1e-3, 1e-6]); | ||
</pre></div> | |||
quad("F", 0, 1, [1e-3, 1e-6]); | |||
</pre></div> | |||
Musimy jednak pamiętać, by pojęcia tolerancji "błędu" nie traktować zbyt | Musimy jednak pamiętać, by pojęcia tolerancji "błędu" nie traktować zbyt | ||
dosłownie: tym, co naprawdę kontroluje <code>quad</code> podczas wyznaczania | dosłownie: tym, co naprawdę kontroluje <code style="color: #006">quad</code> podczas wyznaczania | ||
wartości całki, jest jedynie pewien <strong>estymator</strong> błędu, dlatego wartość | wartości całki, jest jedynie pewien <strong>estymator</strong> błędu, dlatego wartość | ||
tolerancji należy zawsze wybierać w sposób konserwatywny, czyli z pewnym zapasem | tolerancji należy zawsze wybierać w sposób konserwatywny, czyli z pewnym zapasem | ||
bezpieczeństwa, np. | bezpieczeństwa, np. | ||
<blockquote style="background-color:#fefeee"> Jeśli chcemy wyznaczyć wartość całki z błędem bezwzględnym na | <blockquote style="background-color: #fefeee; padding:1em; margin-left,margin-right:2em; margin-top,margin-bottom: 1em;"> Jeśli chcemy wyznaczyć wartość całki z błędem bezwzględnym na | ||
poziomie <math>\displaystyle 10^{-6}</math>, ustawimy -- na wszelki wypadek -- | poziomie <math>\displaystyle 10^{-6}</math>, ustawimy -- na wszelki wypadek -- | ||
<code>ATOL = 1e-7</code>, a nie, prostodusznie, | <code style="color: #006">ATOL = 1e-7</code>, a nie, prostodusznie, | ||
<code>ATOL = 1e-6</code>... Musimy także pamiętać, że choć są bardzo mało | <code style="color: #006">ATOL = 1e-6</code>... Musimy także pamiętać, że choć są bardzo mało | ||
prawdopodobne do spotkania w praktyce, to jednak istnieją <strong>wyuzdane</strong> | prawdopodobne do spotkania w praktyce, to jednak istnieją <strong>wyuzdane</strong> | ||
funkcje, dla których estymator błędu może dać całkowicie fałszywe wartości, | funkcje, dla których estymator błędu może dać całkowicie fałszywe wartości, | ||
przez co i obliczona całka może być obarczona dowolnie wielkim błędem.</blockquote> | przez co i obliczona całka może być obarczona dowolnie wielkim błędem.</blockquote> | ||
Dodajmy, że <code>quad</code> doskonale radzi sobie także z funkcjami z osobliwościami (o | Dodajmy, że <code style="color: #006">quad</code> doskonale radzi sobie także z funkcjami z osobliwościami (o | ||
ile tylko ją o nich uprzedzimy). Przykładowo, scałkujmy funkcję ze złośliwą nieciągłością w | ile tylko ją o nich uprzedzimy). Przykładowo, scałkujmy funkcję ze złośliwą nieciągłością w | ||
zerze: | zerze: | ||
Linia 620: | Linia 625: | ||
</math></center> | </math></center> | ||
Oczywiście <math>\displaystyle \int_{-1}^1 f(x)\, dx = 0</math>, tymczasem definiując | Oczywiście, <math>\displaystyle \int_{-1}^1 f(x)\, dx = 0</math>, tymczasem definiując | ||
<div | <div style="margin: 1em; padding:1em; color: #006; background-color:#fcfcfc;"><pre>function y = osobliwa(x) | ||
function y = osobliwa(x) | |||
if (x != 0.0) | if (x != 0.0) | ||
y = 1/x; | y = 1/x; | ||
Linia 632: | Linia 635: | ||
quad("osobliwa", -1, 1) | quad("osobliwa", -1, 1) | ||
</pre></div> | </pre></div> | ||
daje w rezultacie | daje w rezultacie | ||
<div | <div style="font-family: monospace; white-space: pre; border-style: dashed; border-width: thin; border-color: black; margin: 1em; padding:1em; color: #444; background-color:#fdfdfd;"><nowiki>ABNORMAL RETURN FROM DQAGP | ||
ans = -81.098 | ans = -81.098 | ||
</ | </nowiki></div> | ||
-- błędny wynik i (na szczęście!) także komunikat o jakichś problemach procedury | -- błędny wynik i (na szczęście!) także komunikat o jakichś problemach procedury | ||
całkującej. Jeśli jednak wspomożemy <code>quad</code> informacją o tym, że w <math>\displaystyle x=0</math> czai | całkującej. Jeśli jednak wspomożemy <code style="color: #006">quad</code> informacją o tym, że w <math>\displaystyle x=0</math> czai | ||
się osobliwość, wszystko przebiegnie już gładko: | się osobliwość, wszystko przebiegnie już gładko: | ||
<div | <div style="font-family: monospace; white-space: pre; border-style: dashed; border-width: thin; border-color: black; margin: 1em; padding:1em; color: #444; background-color:#fdfdfd;"><nowiki>quad("osobliwa", -1, 1, [1e-8 1e-8], 0) | ||
quad("osobliwa", -1, 1, [1e-8 1e-8], 0) | |||
ans = 0 | ans = 0 | ||
</ | </nowiki></div> | ||
(<code>1e-8</code> jest żądaną tolerancją błędu, równą wartości domyślnej). | (<code style="color: #006">1e-8</code> jest żądaną tolerancją błędu, równą wartości domyślnej). | ||
===QUADPACK=== | |||
Właściwie jedynym klasycznym pakietem, jaki mamy do dyspozycji jest | Właściwie jedynym klasycznym pakietem, jaki mamy do dyspozycji jest | ||
Linia 660: | Linia 659: | ||
Jest to zestaw kilkunastu procedur fortranowskich, służących obliczaniu typowych całek | Jest to zestaw kilkunastu procedur fortranowskich, służących obliczaniu typowych całek | ||
jednowymiarowych, w tym kilka ogólnego stosowania: | jednowymiarowych, w tym kilka ogólnego stosowania: | ||
{| border=1 | {| border=1 | ||
|+ <span style="font-variant:small-caps"> </span> | |+ <span style="font-variant:small-caps"> </span> | ||
|- | |- | ||
| | | Typ całki || Procedura QUADPACKa | ||
Typ całki || Procedura QUADPACKa | |||
|- | |- | ||
| | | <math>\displaystyle \int_a^b f(x)</math> || DQNG, DQAG, DQAGS, DQAGP | ||
<math>\displaystyle \int_a^b f(x)</math> || DQNG, DQAG, DQAGS, DQAGP | |||
|- | |- | ||
| | | <math>\displaystyle \int_{-\infty}^{\infty} f(x)</math> || DQAGI | ||
<math>\displaystyle \int_{-\infty}^{\infty} f(x)</math> || DQAGI | |||
|- | |- | ||
| | | <math>\displaystyle \int_a^b f(x)\cos(\omega x)</math> || DQAWO | ||
<math>\displaystyle \int_a^b f(x)\cos(\omega x)</math> || DQAWO | |||
|- | |- | ||
| | | <math>\displaystyle \int_a^b \dfrac{f(x)}{x-c}</math> || DQAWC | ||
<math>\displaystyle \int_a^b \dfrac{f(x)}{x-c}</math> || DQAWC | |||
|- | |- | ||
| | | | ||
|} | |} | ||
oraz spora liczba podstawowych kwadratur, na których oparto te ogólne. Nazwy | oraz spora liczba podstawowych kwadratur, na których oparto te ogólne. Nazwy | ||
procedur rozszyfrowuje się podobnie jak nazwy procedur LAPACKa, zatem | procedur rozszyfrowuje się podobnie jak nazwy procedur LAPACKa, zatem | ||
* przedrostek <code>D</code> w nazwie każdej procedury wymienionej w | * przedrostek <code style="color: #903">D</code> w nazwie każdej procedury wymienionej w tabeli (np. <code style="color: #903">DQAGI</code>) oznacza, że będzie działać na liczbach typu <code>double</code> (całkując funkcję <math>\displaystyle f</math> zwracającą wartości tego samego typu). Gdybyśmy chcieli użyć pojedynczej precyzji, użylibyśmy nazwy procedury <strong>bez przedrostka</strong>. | ||
* Kolejna litera, <code style="color: #903">Q</code>, oczywiście oznacza kwadraturę (''Quadrature''). | |||
<code>double</code> (całkując funkcję <math>\displaystyle f</math> zwracającą wartości tego samego typu). | * Trzecia litera --- <code style="color: #903">A</code> lub <code style="color: #903">N</code> oznacza, odpowiednio, kwadraturę adaptacyjną lub nieadaptacyjną. Jak wiadomo, w praktyce lepiej sprawdzają się kwadratury adaptacyjne, potrafiące w jakiejś mierze dostosować się do przebiegu funkcji podcałkowej. Kwadratury nieadaptacyjne nie mają tej własności, natomiast są tańsze, warto więc je stosować w szczególnych przypadkach, gdy wiemy ''a priori'', że adaptacja niewiele pomoże: np. do wolno zmiennych funkcji. | ||
Gdybyśmy chcieli użyć pojedynczej precyzji, użylibyśmy nazwy procedury <strong>bez | * Pozostałe litery precyzują typ liczonej całki i zakres ingerencji użytkownika; <code style="color: #903">G</code> --- "zwykła" całka, bez wagi, <code style="color: #903">W</code> --- całka z wagą, <code style="color: #903">O</code> --- oscylacyjną, <code style="color: #903">C</code> --- wartość główna całki (tzw. całka Cauchy'ego), <code style="color: #903">I</code> --- przedział nieskończony, <code style="color: #903">S</code> --- możliwe osobliwości, <code style="color: #903">P</code> --- użytkownik poda listę punktów, gdzie są osobliwości. | ||
przedrostka</strong>. | |||
* Kolejna litera, <code>Q</code>, oczywiście oznacza kwadraturę | ===GSL=== | ||
(''Quadrature ''). | |||
* Trzecia litera - <code>A</code> lub <code>N</code> | |||
kwadraturę adaptacyjną lub nieadaptacyjną. Jak wiadomo, w praktyce lepiej | |||
sprawdzają się kwadratury adaptacyjne, potrafiące w jakiejś mierze dostosować | |||
się do przebiegu funkcji podcałkowej. Kwadratury nieadaptacyjne nie mają tej | |||
własności, są | |||
przypadkach, gdy wiemy a priori, że adaptacja niewiele pomoże: np. do | |||
wolno zmiennych funkcji. | |||
* Pozostałe litery precyzują typ liczonej całki i zakres ingerencji | |||
użytkownika; <code>G</code> --- "zwykła" całka, bez wagi, <code>W</code> --- całka z | |||
wagą, | |||
Cauchy'ego), <code>I</code> --- przedział nieskończony, <code>S</code> --- możliwe | |||
osobliwości, <code>P</code> --- użytkownik poda listę punktów, gdzie są osobliwości. | |||
Biblioteka GSL reimplementuje podstawowe procedury QUADPACKa w języku C, zob. | Biblioteka GSL reimplementuje podstawowe procedury QUADPACKa w języku C, zob. | ||
Linia 717: | Linia 690: | ||
szczegółowo opisane. Procedury GSL mają nazwy analogiczne, jak procedury | szczegółowo opisane. Procedury GSL mają nazwy analogiczne, jak procedury | ||
QUADPACKa, ale z przedrostkiem <code>gsl_integration</code>, jak w poniższym | QUADPACKa, ale z przedrostkiem <code>gsl_integration</code>, jak w poniższym | ||
przykładzie, gdzie wywołamy odpowiednik procedury <code>DQAG</code>: funkcję | przykładzie, gdzie wywołamy odpowiednik procedury <code style="color: #903">DQAG</code>: funkcję | ||
<code>gsl_integration_qag</code>. | <code>gsl_integration_qag</code>. | ||
<div | <div style="margin: 1em; padding:1em; color: #000; background-color:#fcfcfc;"><pre>#include <stdio.h> | ||
#include <stdio.h> | |||
#include <math.h> | #include <math.h> | ||
#include <gsl/gsl_integration.h> | #include <gsl/gsl_integration.h> | ||
Linia 759: | Linia 731: | ||
if (IER != 0) | if (IER != 0) | ||
fprintf(stderr,"GSL_QAG: Kłopoty z całkowaniem\n"); | fprintf(stderr,"GSL_QAG: Kłopoty z całkowaniem\n"); | ||
fprintf(stderr,"Całka: | fprintf(stderr,"Całka: %g Est. błąd: %g IER: %d\n", RESULT, ABSERR, IER); | ||
gsl_integration_workspace_free(workspace); | gsl_integration_workspace_free(workspace); | ||
Linia 772: | Linia 745: | ||
Miłym rozszerzeniem funkcjonalności jest możliwość | Miłym rozszerzeniem funkcjonalności jest możliwość | ||
przekazywania parametrów do wnętrza funkcji podcałkowej. | przekazywania parametrów do wnętrza funkcji podcałkowej. | ||
=Różniczkowanie= | |||
{{powrot |Metody numeryczne | do strony głównej | |||
przedmiotu <strong>Metody numeryczne</strong>}} | |||
Z zadaniem numerycznego różniczkowania zadanej funkcji spotykamy się często w numeryce. Rzeczywiście, jeśli przypomnimy sobie metodę siecznych, to była to po prostu metoda Newtona, w której pochodną przybliżono pewnym ilorazem różnicowym: | |||
<center><math>\displaystyle x_{k+1} = x_k - \frac{f(x_k)}{g_k}, | |||
</math></center> | |||
<center><math>\displaystyle \ | gdzie <center><math>\displaystyle g_k = \frac{f(x_k)-f(x_{k-1})}{x_k - x_{k-1}} \approx f'(x_k).</math></center> | ||
Zauważmy, że nie jest to jedyny możliwy wzór na przybliżoną metodę Newtona, równie dobrze(? --- to się dopiero okaże!) moglibyśmy wziąć <center><math>\displaystyle g_k = \frac{f(x_k+h)-f(x_k)}{h}</math></center> | |||
dla dostatecznie małego <math>\displaystyle h</math>. | |||
Podobne formuły są także konieczne do konstrukcji metod numerycznego rozwiązywania równań różniczkowych, gdzie w naturalny sposób pojawia się konieczność operowania pochodną nieznanej funkcji. | |||
== | ==Metody różnicowe== | ||
Rozważmy najprostszy sposób aproksymacji pochodnej <math>\displaystyle f'(x)</math>, oparty na <strong>różnicy dzielonej w przód</strong>, gdyż ze wzoru Taylora | |||
= | <center><math>\displaystyle f(x+h) = f(x) + f'(x)h + O(h^2), | ||
</math></center> | |||
pomijając człony rzędu <math>\displaystyle h^2</math>, dostajemy przybliżenie | |||
<center><math>\displaystyle f'(x) \approx \frac{f(x+h)-f(x)}{h}, | |||
<center><math>\displaystyle | |||
</math></center> | </math></center> | ||
a dokładniej, | |||
<center><math>\displaystyle f'(x) = \frac{f(x+h)-f(x)}{h} + O(h). | |||
</math></center> | |||
Podobną dokładność aproksymacji dostaniemy, biorąc <strong>różnicę dzieloną w tył</strong>, | |||
<center><math>\displaystyle \frac{ | <center><math>\displaystyle f'(x) = \frac{f(x)-f(x-h)}{h} + O(h). | ||
</math></center> | </math></center> | ||
Nietrudno przekonać się, że wzięcie średniej arytmetycznej tych dwóch aproksymacji daje tzw. <strong>różnicę centralną</strong>, która ma wyższy rząd aproksymacji, gdyż | |||
<strong> | |||
<center><math>\displaystyle | <center><math>\displaystyle f'(x) = \frac{f(x+h)-f(x-h)}{2h} + O(h^2), | ||
</math></center> | </math></center> | ||
co znaczy, że dwukrotnie zmniejszając <math>\displaystyle h</math>, powinniśmy się spodziewać czterokrotnego zmniejszenia błędu aproksymacji pochodnej! | |||
== | ==Metody interpolacyjne== | ||
Jeśli chcemy uzyskać jeszcze wyższy rząd aproksymacji pochodnej, często jako wyrażenie aproksymujące przyjmuje się pochodną wielomianu interpolacyjnego. | |||
< | Rzeczywiście, niech <math>\displaystyle w_n</math> będzie wielomianem interpolującym funkcję <math>\displaystyle f</math> w parami różnych węzłach <math>\displaystyle x_0< \cdots < x_n</math>, tzn. | ||
<center><math>\displaystyle | |||
w_n(x) = \sum_{i=0}^{n}f(x_i) l_i(x), | |||
</math></center> | |||
gdzie <math>\displaystyle l_i(x)</math> są \link{sec:interpol}{wielomianami bazowymi Lagrange'a}. Wtedy | |||
<center><math>\displaystyle | |||
f'(x) \approx w_n'(x) = \sum_{i=0}^{n}f(x_i) l_i'(x), | |||
</math></center> | |||
<math>\displaystyle | |||
przy czym można wykazać, że | |||
{{twierdzenie|O błędzie aproksymacji pochodnej za pomocą pochodnej wielomianu interpolacyjnego|O błędzie aproksymacji pochodnej za pomocą pochodnej wielomianu interpolacyjnego| | |||
Niech <math>\displaystyle w_n</math> będzie wielomianem interpolującym funkcję <math>\displaystyle f\in C^{n+2}[a,b]</math> w równoodległych węzłach <math>\displaystyle a, a+h, a+2h, \ldots, b</math>, gdzie <math>\displaystyle h = (b-a)/n</math>. Wtedy zachodzi | |||
< | <center><math>\displaystyle | ||
\ | f'(x) - w_n'(x) = O(h^n) \quad \forall x\in [a,b] | ||
</math></center> | </math></center> | ||
}} | |||
Wszystkie wprowadzone powyżej metody interpolacji oparte na wielomianie Taylora w rzeczywistości dadzą się sprowadzić do pochodnej wielomianu interpolacyjnego. Rzeczywiście, | |||
* różnica w przód to aproksymacja <math>\displaystyle f'(x)</math> pochodną wielomianu opartego na węzłach <math>\displaystyle x</math> i <math>\displaystyle x+h</math>, | |||
* różnica w tył to aproksymacja <math>\displaystyle f'(x)</math> pochodną wielomianu opartego na węzłach <math>\displaystyle x</math> i <math>\displaystyle x-h</math>, | |||
* różnica centralna to aproksymacja <math>\displaystyle f'(x)</math> pochodną wielomianu opartego na węzłach <math>\displaystyle x-h</math> i <math>\displaystyle x+h</math>; w tym ostatnim przypadku widzimy także, że powyższe twierdzenie nie zawsze jest ostre, bo dla różnicy centralnej byliśmy w stanie uzyskać wyższy niż minimalny gwarantowany przez twierdzenie rząd aproksymacji. | |||
Łatwo także --- korzystając z powyższego --- wyprowadzić nowe wzory na aproksymację, przykładowo, | |||
<center><math>\displaystyle | <center><math>\displaystyle f'(x) = \frac{1}{2h} ( 3f(x) - 4f(x-h) + f(x-2h)) + O(h^2) | ||
</math></center> | </math></center> | ||
korzysta tylko z wartości <math>\displaystyle f</math> na lewo od <math>\displaystyle x</math> (jest to więc ''różniczkowanie wstecz'') i też daje kwadratową aproksymację. | |||
Analogicznie możemy aproksymować pochodne wyższych rzędów, np. | |||
<center><math>\displaystyle f''(x) = \frac{f(x-h) - 2f(x) + f(x+h)}{h^2} + O(h^2). | |||
</math></center> | |||
= | Tę formułę możemy znów uzyskać na wiele sposobów: | ||
* wprost ze wzoru Taylora, raz dla <math>\displaystyle f(x+h)</math>, a raz dla <math>\displaystyle f(x-h)</math>, | |||
* jako drugą pochodną wielomianu interpolacyjnego, | |||
* jako złożenie różnicy dzielonej w przód z różnicą dzieloną w tył (co ma naśladować matematyczną zależność, że <math>\displaystyle f''(x) = (f'(x))'</math>. | |||
Namawiamy czytelnika do sprawdzenia, że faktycznie powyższy wzór można tak wyprowadzić. | |||
<!-- | |||
===Różniczkowanie wielomianu algorytmem Hornera=== | |||
Jak widać z powyższego, warto jest umieć rozwiązać następujące ogólne zagadnienie: mając zadany wielomian interpolacyjny, znaleźć jego pochodną w punkcie <math>\displaystyle x</math>. Okazuje się, że do tego znakomicie nadaje się [[|algorytm Hornera]]. | |||
--> | |||
==Uwarunkowanie== | |||
==Kłopoty numeryczne== | |||
Rozważmy przykładowo różnicę w przód dla <math>\displaystyle h>0</math>. Gdyby arytmetyka której używamy miała nieskończoną precyzję, to oczywiście zachodzi | |||
<center><math>\displaystyle \frac{f(x+h)-f(x)}{h} - f'(x) = O(h), | |||
<center><math>\displaystyle | |||
</math></center> | </math></center> | ||
i przybliżenie byłoby tym lepsze, im mniejsze byłoby <math>\displaystyle h</math>. Jednak w praktyce tak nie będzie, ze względu na fakt, że działamy w arytmetyce skończonej precyzji: | |||
* dla małych <math>\displaystyle h</math>, mamy <math>\displaystyle f(x+h) -f(x) \approx 0</math>, a więc zachodzi duże ryzyko utraty cyfr przy odejmowaniu | |||
* dla małych <math>\displaystyle h</math>, może zdarzyć się, że numerycznie <math>\displaystyle fl_\nu(x+h) = fl_\nu(x)</math> i w konsekwencji <math>\displaystyle fl_\nu(\frac{f(x+h)-f(x)}{h}) = 0</math>. | |||
< | |||
Można więc postawić sobie pytanie, jak dobrać <math>\displaystyle h</math> na tyle małe, by mieć możliwie dobrą aproksymację <math>\displaystyle f'(x)</math>, a jeszcze nie odczuć zgubnych skutków wpływu arytmetyki zmiennoprzecinkowej. Formalnie, możemy pytanie postawić w sposób następujący: | |||
Przypuśćmy, że zamiast <math>\displaystyle f(x)</math> wyznaczane jest <math>\displaystyle \tilde{f}(x) = f(x)+\epsilon_x</math>, przy czym <math>\displaystyle |\epsilon_x| \leq \epsilon</math>. Jak dobrać do <math>\displaystyle \epsilon</math> parametr <math>\displaystyle h</math> w taki sposób, by aproksymacja <center><math>\displaystyle \frac{\tilde{f}(x+h)-\tilde{f}(x)}{h} \approx f'(x)</math></center> | |||
była jak najlepsza? | |||
Mamy: | |||
</ | |||
< | |||
<center><math>\displaystyle \aligned \left| \frac{\tilde{f}(x+h)-\tilde{f}(x)}{h} - f'(x) \right| &= \left| \frac{1}{h}( (f(x+h)+\epsilon_{x+h}) - (f(x) + \epsilon_x)) - f'(x) \right| \\ | |||
&\leq | |||
\left| \frac{ f(x+h) - f(x)}{h} - f'(x)\right| + \frac{2\epsilon}{h} | |||
\endaligned</math></center> | |||
< | Ponieważ pierwszy człon wyrażenia daje się oszacować (dla dostatecznie regularnej funkcji <math>\displaystyle f</math>) przez <math>\displaystyle C\cdot h</math>, to ostatecznie dostajemy | ||
<center><math>\displaystyle \left| \frac{\tilde{f}(x+h)-\tilde{f}(x)}{h} - f'(x) \right| \leq C_1(h + \frac{1}{h}). | |||
</math></center> | |||
<math> | |||
= | Wyrażenie po prawej stronie jest minimalizowane dla <math>\displaystyle h = \sqrt{\epsilon}</math> i stąd inżynierska reguła: | ||
<blockquote style="background-color: #fefeee; padding:1em; margin-left,margin-right:2em; margin-top,margin-bottom: 1em;"> | |||
Jeśli chcesz używać różnicy w przód, powinieneś wziąć <math>\displaystyle h</math> równe co najmniej <math>\displaystyle \sqrt{\epsilon_{ \mbox{mach} }}</math>. | |||
</blockquote> |
Wersja z 21:53, 29 wrz 2006
Całkowanie
<<< Powrót do strony głównej przedmiotu Metody numeryczne
Zajmiemy się teraz zadaniem całkowania numerycznego. Polega ono na obliczeniu (a raczej przybliżeniu) całki oznaczonej
gdzie , a należy do pewnej klasy funkcji rzeczywistych określonych i całkowalnych w sensie Riemanna na całym przedziale .
Każdy, kto przeszedł przez kurs całkowania wie, że obliczanie całek rozumiane jako znalezienie elementarnego wzoru na funkcję pierwotną może być trudne, bardzo trudne, a nawet niewykonalne. Tymczasem zadanie przybliżonego wyznaczenia wartości całki daje się w dużej mierze zautomatyzować z całkiem dobrym skutkiem.
Obliczanie całek jest wymagane w bardzo wielu zadaniach inżynierskich i naukowych. Całki z funkcji (bardzo) wielu zmiennych (które na swój sposób są szczególnie trudne do obliczenia) znajdują ważne zastosowania w bankowości i finansach.
Będziemy zakładać, że mamy możliwość obliczania wartości funkcji , a w niektórych przypadkach również jej pochodnych, o ile istnieją. Dokładna całka będzie więc w ogólności przybliżana wartością , która zależy tylko od wartości i ew. jej pochodnych w skończonej liczbie punktów.
Kwadratury
Kwadraturami nazywamy funkcjonały liniowe Parser nie mógł rozpoznać (nieznana funkcja „\toR”): {\displaystyle \displaystyle Q:F\toR} postaci
albo ogólniej
gdzie są punktami z , a (albo ) są pewnymi współczynnikami rzeczywistymi. Zauważmy, że obliczenia kwadratur są dopuszczalne w naszym modelu obliczeniowym, mogą więc służyć jako sposób przybliżania całki.
Jeden z możliwych sposobów konstrukcji kwadratur jest następujący. Najpierw wybieramy węzły (pojedyncze lub wielokrotne), budujemy wielomian interpolacyjny odpowiadający tym węzłom, a następnie całkujemy go. Ponieważ postać wielomianu interpolacyjnego zależy tylko od danej informacji o , otrzymana w ten sposób wartość też będzie zależeć tylko od tej informacji, a w konsekwencji funkcjonał wynikowy będzie postaci ja wyżej. Są to tzw. kwadratury interpolacyjne.
Definicja
Kwadraturę opartą na węzłach o łącznej krotności nazywamy interpolacyjną, jeśli
gdzie jest wielomianem interpolacyjnym funkcji stopnia co najwyżej , opartym na tych węzłach.
Współczynniki kwadratur interpolacyjnych można łatwo wyliczyć. Rozpatrzmy dla uproszczenia przypadek, gdy węzły są jednokrotne. Zapisując wielomian interpolacyjny w postaci jego rozwinięcia w bazie kanonicznej Lagrange'a (zob. (Uzupelnic: Lagrbaza )), otrzymujemy
a stąd i z postaci ,
.
Podamy teraz kilka przykładów.
Kwadratura prostokątów jest oparta na jednym węźle ,
Kwadratura trapezów jest oparta na jednokrotnych węzłach , i jest równa polu odpowiedniego trapezu,
Kwadratura parabol (Simpsona) jest oparta na jednokrotnych węzłach , , , i jest równa polu pod parabolą interpolującą w tych węzłach,
Zauważmy, że kwadratury trapezów i parabol są oparte na węzłach jednokrotnych i równoodległych, przy czym i . Ogólnie, kwadratury interpolacyjne oparte na węzłach równoodległych Parser nie mógł rozpoznać (błąd składni): {\displaystyle \displaystyle x_i=a+(b-a)i/ń} , , nazywamy kwadraturami Newtona--Cotesa.
Błąd kwadratur interpolacyjnych
Zajmiemy się teraz błędem kwadratur interpolacyjnych. Przypomnijmy, że oznacza klasę funkcji razy różniczkowalnych w sposób ciągły i takich, że , .
Twierdzenie
Niech będzie kwadraturą interpolacyjną opartą na (jednokrotnych lub wielokrotnych) węzłach , . Jeśli to
W klasie , maksymalny błąd kwadratury wynosi
Dowód\quad Korzystając ze znanego nam już wzoru na błąd interpolacji wielomianowej z Lematu Uzupelnic: leblint , mamy
Stąd, jeśli to
Ograniczenie górne w dokładnej formule na błąd w klasie wynika bezpośrednio z oszacowania (Uzupelnic: blkwad ). Aby pokazać ograniczenie dolne zauważmy, że dla funkcji takiej, że przyjmuje na przedziałach , , , naprzemiennie wartości i mamy
Co prawda, nie jest w , ale może być dla dowolnego przybliżana funkcjami w ten sposób, że całka
Zapisując mamy
co wobec dowolności daje dowód twierdzenia.
W szczególnych przypadkach kwadratur trapezów i parabol możemy otrzymać innego rodzaju formuły na błąd.
Twierdzenie
Jeśli to dla kwadratury trapezów mamy
Jeśli to dla kwadratury parabol mamy
().
Dowód\quad (i) Ze wzoru (Uzupelnic: blkwad )
Ponieważ funkcja jest ciągła, a wielomian przyjmuje jedynie wartości nieujemne, można zastosować twierdzenie o wartości średniej dla całki, aby otrzymać
dla pewnych .
(ii) Niech i będą wielomianami interpolacyjnymi funkcji odpowiednio dla węzłów oraz . Wtedy
Wobec
mamy
Stąd i ze wzoru na błąd interpolacji Hermite'a otrzymujemy
Ponieważ wielomian jest niedodatni na , możemy znów zastosować twierdzenie o wartości średniej. Mamy
co kończy dowód.
Kwadratury złożone
Podobnie jak w przypadku zadania interpolacji chcielibyśmy, aby błąd kwadratur malał do zera, gdy liczba węzłów rośnie do nieskończoności. Można to osiągnąć stosując np. kwadratury złożone. Są to kwadratury, które powstają przez scałkowanie funkcji kawałkami wielomianowej interpolującej .
Prostym przykładem kwadratury złożonej jest suma Riemanna,
gdzie oraz . Jeśli średnica podziału, , maleje do zera to .
Będziemy rozpatrywać kwadratury złożone postaci
gdzie jest kawałkami wielomianem z Rozdziału Uzupelnic: kawwiel . To znaczy, dla danego kładziemy , , a następnie dla każdego wybieramy dowolne węzły , . Wtedy jest na każdym przedziale wielomianem interpolacyjnym funkcji stopnia co najwyżej opartym na węzłach . Kwadratura korzysta z węzłów o łącznej krotności .
Twierdzenie
Błąd kwadratury złożonej w klasie jest ograniczony przez
gdzie
Dowód\quad Twierdzenie to jest bezpośrednim wnioskiem z Twierdzenia Uzupelnic: twblkw . Mamy bowiem
co kończy dowód.
W klasie , błąd kwadratur złożonych jest rzędu , czyli jest taki sam jak błąd interpolacji kawałkami wielomianowej. I tak jak przy interpolacji można pokazać, że błąd każdej innej metody całkowania korzystającej jedynie z wartości funkcji w punktach nie może w klasie maleć szybciej niż , zob. U. Uzupelnic: optzlo . Podane kwadratury złożone mają więc optymalny rząd zbieżności.
Zajmiemy się teraz błędem szczególnych kwadratur złożonych, mianowicie złożonych kwadratur trapezów i parabol . Powstają one przez zastosowanie na każdym przedziale odpowiednio kwadratur trapezów i parabol . Jak łatwo się przekonać,
oraz
Twierdzenie
Jeśli to
Jeśli to
Dowód
Dla kwadratury trapezów mamy
a dla kwadratury parabol podobnie

Kwadratura parabol ma więc optymalny rząd zbieżności nie tylko w klasie , ale też w .
Przyspieszanie zbieżności kwadratur
W praktyce często stosuje się obliczanie kwadratur poprzez zagęszczanie podziału przedziału . Na przykład, dla złożonej kwadratury trapezów zachodzi następujący wygodny wzór rekurencyjny:
Pozwala on obliczyć na podstawie poprzez "doliczenie" wartości funkcji w punktach "gęstszej" siatki. W ten sposób możemy obserwować zachowanie się kolejnych przybliżeń () całki . Jest to szczególnie istotne wtedy, gdy nie mamy żadnej informacji a priori o , a przez to nie potrafimy oszacować liczby węzłów, dla której osiągniemy pożądaną dokładność, zob. U. Uzupelnic: kwas .
Jeśli funkcja jest więcej niż dwa razy różniczkowalna to użycie złożonych kwadratur trapezów zdaje się tracić sens. Wtedy istnieją przecież kwadratury, których błąd maleje do zera szybciej niż . Okazuje się jednak, że kwadratury mogą być podstawą dla prostej rekurencyjnej konstrukcji innych kwadratur posiadających już optymalną zbieżność. Konstrukcja ta bazuje na następującym ważnym lemacie.

Zobacz biografię

Zobacz biografię
Lemat Formuła Eulera-Maclaurina
Dla funkcji , błąd złożonej kwadratury trapezów wyraża się wzorem
gdzie , , a są pewnymi stałymi liczbowymi. Mamy , i, ogólnie, , gdzie są tzw. liczbami Bernoulliego.
Dowód tego lematu pominiemy.
Formułę Eulera-Maclaurina można przepisać w postaci
gdzie , , oraz . Zauważmy przy tym, że jeśli to współczynniki są wspólnie ograniczone przez .
Definiując teraz kwadraturę
dla mamy
gdzie i jest wspólnie ograniczone dla . Kwadratura ma więc optymalny w rząd zbieżności . Proces ten można kontynuować dalej tworząc kolejne kwadratury o coraz to wyższym rzędzie zbieżności. Dokładniej, połóżmy oraz, dla ,
Wtedy, dla , rząd zbieżności kwadratury wynosi . Rzeczywiście, sprawdziliśmy, że jest to prawdą dla . Niech . Postępując indukcyjnie ze względu na mamy
ponieważ współczynniki przy redukują się. są tutaj pewnymi nowymi stałymi, a może być w klasie ograniczona przez stałą niezależną od . Ostatecznie, dla mamy więc
i w klasie
dla pewnej stałej niezależnej od .
Zauważmy jeszcze, że wykorzystuje wartości w punktach równoodległych na co oznacza, że w terminach rząd zbieżności wynosi też , a więc jest optymalny w klasie .
Kwadratury nazywane są kwadraturami Romberga. Dla danej funkcji , można je łatwo konstruować budując następującą tablicę trójkątną:
w której pierwsza kolumna jest tworzona indukcyjnie zgodnie ze wzorem (Uzupelnic: indtrap ), a kolejne zgodnie z (Uzupelnic: indRom ).
Biblioteki
W Octave dostępne są jedynie procedury całkujące funkcje skalarne jednej zmiennej na odcinku:
Robi to funkcja DQAGP ze znakomitego pakietu QUADPACK. Najlepiej od razu posłużmy się przykładem.
Przykład: Prosta całka funkcji jednej zmiennej
Przypuśćmy, że chcemy obliczyć całkę , gdzie np. . W tym celu najpierw implementujemy w Octave:
function y = F(x) y = sin(23*x)+1/sqrt(1-x^2); endfunction
Aby teraz obliczyć całkę , wystarczy wywołać
I = quad("F", 0, 1);
W rzeczywistości, podobnie jak w przypadku funkcji fsolve
, funkcja
quad
zwraca więcej informacji, można jej także przekazać dodatkowe
parametry. I tak, jeśli chcemy ustawić poziom tolerancji błędu obliczenia
całki:
z wartościami i , to wywołamy funkcję przekazując jej te parametry następująco:
quad("F", 0, 1, [1e-3, 1e-6]);
Musimy jednak pamiętać, by pojęcia tolerancji "błędu" nie traktować zbyt
dosłownie: tym, co naprawdę kontroluje quad
podczas wyznaczania
wartości całki, jest jedynie pewien estymator błędu, dlatego wartość
tolerancji należy zawsze wybierać w sposób konserwatywny, czyli z pewnym zapasem
bezpieczeństwa, np.
Jeśli chcemy wyznaczyć wartość całki z błędem bezwzględnym na
poziomie , ustawimy -- na wszelki wypadek --
ATOL = 1e-7
, a nie, prostodusznie,ATOL = 1e-6
... Musimy także pamiętać, że choć są bardzo mało prawdopodobne do spotkania w praktyce, to jednak istnieją wyuzdane funkcje, dla których estymator błędu może dać całkowicie fałszywe wartości,przez co i obliczona całka może być obarczona dowolnie wielkim błędem.
Dodajmy, że quad
doskonale radzi sobie także z funkcjami z osobliwościami (o
ile tylko ją o nich uprzedzimy). Przykładowo, scałkujmy funkcję ze złośliwą nieciągłością w
zerze:
Oczywiście, , tymczasem definiując
function y = osobliwa(x) if (x != 0.0) y = 1/x; else y = 1e6; endif endfunction quad("osobliwa", -1, 1)
daje w rezultacie
-- błędny wynik i (na szczęście!) także komunikat o jakichś problemach procedury
całkującej. Jeśli jednak wspomożemy quad
informacją o tym, że w czai
się osobliwość, wszystko przebiegnie już gładko:
(1e-8
jest żądaną tolerancją błędu, równą wartości domyślnej).
QUADPACK
Właściwie jedynym klasycznym pakietem, jaki mamy do dyspozycji jest ponaddwudziestoletni QUADPACK . Jest to zestaw kilkunastu procedur fortranowskich, służących obliczaniu typowych całek jednowymiarowych, w tym kilka ogólnego stosowania:
Typ całki | Procedura QUADPACKa |
DQNG, DQAG, DQAGS, DQAGP | |
DQAGI | |
DQAWO | |
DQAWC | |
oraz spora liczba podstawowych kwadratur, na których oparto te ogólne. Nazwy procedur rozszyfrowuje się podobnie jak nazwy procedur LAPACKa, zatem
- przedrostek
D
w nazwie każdej procedury wymienionej w tabeli (np.DQAGI
) oznacza, że będzie działać na liczbach typudouble
(całkując funkcję zwracającą wartości tego samego typu). Gdybyśmy chcieli użyć pojedynczej precyzji, użylibyśmy nazwy procedury bez przedrostka. - Kolejna litera,
Q
, oczywiście oznacza kwadraturę (Quadrature). - Trzecia litera ---
A
lubN
oznacza, odpowiednio, kwadraturę adaptacyjną lub nieadaptacyjną. Jak wiadomo, w praktyce lepiej sprawdzają się kwadratury adaptacyjne, potrafiące w jakiejś mierze dostosować się do przebiegu funkcji podcałkowej. Kwadratury nieadaptacyjne nie mają tej własności, natomiast są tańsze, warto więc je stosować w szczególnych przypadkach, gdy wiemy a priori, że adaptacja niewiele pomoże: np. do wolno zmiennych funkcji. - Pozostałe litery precyzują typ liczonej całki i zakres ingerencji użytkownika;
G
--- "zwykła" całka, bez wagi,W
--- całka z wagą,O
--- oscylacyjną,C
--- wartość główna całki (tzw. całka Cauchy'ego),I
--- przedział nieskończony,S
--- możliwe osobliwości,P
--- użytkownik poda listę punktów, gdzie są osobliwości.
GSL
Biblioteka GSL reimplementuje podstawowe procedury QUADPACKa w języku C, zob.
{GSL-reference}, gdzie zostały one bardzo przystępnie i
szczegółowo opisane. Procedury GSL mają nazwy analogiczne, jak procedury
QUADPACKa, ale z przedrostkiem gsl_integration
, jak w poniższym
przykładzie, gdzie wywołamy odpowiednik procedury DQAG
: funkcję
gsl_integration_qag
.
#include <stdio.h> #include <math.h> #include <gsl/gsl_integration.h> double F(double X, void * param) /* wrapper dla funkcji sin(x)/x */ { return(sin(X)/X); } int main(void) { gsl_function f; /* argument z funkcją podcałkową */ double A,ABSERR,B, EPSABS,EPSREL,RESULT; int IER,NEVAL; gsl_integration_workspace *workspace; int KEY, LIMIT; /* przygotowujemy argument z funkcją podcałkową */ f.function = &F; A = 0.0E0; B = 10*M_PI; /* przedział całkowania */ EPSABS = 0.0E0; EPSREL = 1.0E-3; /* tolerancja błędu */ /* parametry specyficzne dla QAG */ KEY = 1; /* tzn. użyj minimalnej liczby punktów kwadratury bazowej */ LIMIT = 100; /* maksymalny podział przedziału całkowania */ workspace = gsl_integration_workspace_alloc(LIMIT); /* całkujemy: QAG! */ IER = gsl_integration_qag(&f, A, B, EPSABS, EPSREL, LIMIT, KEY, workspace, &RESULT, &ABSERR); if (IER != 0) fprintf(stderr,"GSL_QAG: Kłopoty z całkowaniem\n"); fprintf(stderr,"Całka: %g Est. błąd: %g IER: %d\n", RESULT, ABSERR, IER); gsl_integration_workspace_free(workspace); return(0); }
W powyższym przykładzie specjalnie pozostawiliśmy oznaczenia wykorzystywane w poprzednim programie. Jak widać, funkcje całkujące GSL mają bardzo podobną składnię do odpowiadających im funkcji QUADPACKa.
Miłym rozszerzeniem funkcjonalności jest możliwość przekazywania parametrów do wnętrza funkcji podcałkowej.
Różniczkowanie
<<< Powrót do strony głównej przedmiotu Metody numeryczne
Z zadaniem numerycznego różniczkowania zadanej funkcji spotykamy się często w numeryce. Rzeczywiście, jeśli przypomnimy sobie metodę siecznych, to była to po prostu metoda Newtona, w której pochodną przybliżono pewnym ilorazem różnicowym:
gdzie
Zauważmy, że nie jest to jedyny możliwy wzór na przybliżoną metodę Newtona, równie dobrze(? --- to się dopiero okaże!) moglibyśmy wziąć
dla dostatecznie małego .
Podobne formuły są także konieczne do konstrukcji metod numerycznego rozwiązywania równań różniczkowych, gdzie w naturalny sposób pojawia się konieczność operowania pochodną nieznanej funkcji.
Metody różnicowe
Rozważmy najprostszy sposób aproksymacji pochodnej , oparty na różnicy dzielonej w przód, gdyż ze wzoru Taylora
pomijając człony rzędu , dostajemy przybliżenie
a dokładniej,
Podobną dokładność aproksymacji dostaniemy, biorąc różnicę dzieloną w tył,
Nietrudno przekonać się, że wzięcie średniej arytmetycznej tych dwóch aproksymacji daje tzw. różnicę centralną, która ma wyższy rząd aproksymacji, gdyż
co znaczy, że dwukrotnie zmniejszając , powinniśmy się spodziewać czterokrotnego zmniejszenia błędu aproksymacji pochodnej!
Metody interpolacyjne
Jeśli chcemy uzyskać jeszcze wyższy rząd aproksymacji pochodnej, często jako wyrażenie aproksymujące przyjmuje się pochodną wielomianu interpolacyjnego.
Rzeczywiście, niech będzie wielomianem interpolującym funkcję w parami różnych węzłach , tzn.
gdzie są \link{sec:interpol}{wielomianami bazowymi Lagrange'a}. Wtedy
przy czym można wykazać, że
Twierdzenie O błędzie aproksymacji pochodnej za pomocą pochodnej wielomianu interpolacyjnego
Niech będzie wielomianem interpolującym funkcję w równoodległych węzłach , gdzie . Wtedy zachodzi
Wszystkie wprowadzone powyżej metody interpolacji oparte na wielomianie Taylora w rzeczywistości dadzą się sprowadzić do pochodnej wielomianu interpolacyjnego. Rzeczywiście,
- różnica w przód to aproksymacja pochodną wielomianu opartego na węzłach i ,
- różnica w tył to aproksymacja pochodną wielomianu opartego na węzłach i ,
- różnica centralna to aproksymacja pochodną wielomianu opartego na węzłach i ; w tym ostatnim przypadku widzimy także, że powyższe twierdzenie nie zawsze jest ostre, bo dla różnicy centralnej byliśmy w stanie uzyskać wyższy niż minimalny gwarantowany przez twierdzenie rząd aproksymacji.
Łatwo także --- korzystając z powyższego --- wyprowadzić nowe wzory na aproksymację, przykładowo,
korzysta tylko z wartości na lewo od (jest to więc różniczkowanie wstecz) i też daje kwadratową aproksymację.
Analogicznie możemy aproksymować pochodne wyższych rzędów, np.
Tę formułę możemy znów uzyskać na wiele sposobów:
- wprost ze wzoru Taylora, raz dla , a raz dla ,
- jako drugą pochodną wielomianu interpolacyjnego,
- jako złożenie różnicy dzielonej w przód z różnicą dzieloną w tył (co ma naśladować matematyczną zależność, że .
Namawiamy czytelnika do sprawdzenia, że faktycznie powyższy wzór można tak wyprowadzić.
Uwarunkowanie
Kłopoty numeryczne
Rozważmy przykładowo różnicę w przód dla . Gdyby arytmetyka której używamy miała nieskończoną precyzję, to oczywiście zachodzi
i przybliżenie byłoby tym lepsze, im mniejsze byłoby . Jednak w praktyce tak nie będzie, ze względu na fakt, że działamy w arytmetyce skończonej precyzji:
- dla małych , mamy , a więc zachodzi duże ryzyko utraty cyfr przy odejmowaniu
- dla małych , może zdarzyć się, że numerycznie i w konsekwencji .
Można więc postawić sobie pytanie, jak dobrać na tyle małe, by mieć możliwie dobrą aproksymację , a jeszcze nie odczuć zgubnych skutków wpływu arytmetyki zmiennoprzecinkowej. Formalnie, możemy pytanie postawić w sposób następujący:
Przypuśćmy, że zamiast
wyznaczane jest
, przy czym
. Jak dobrać do
parametr
w taki sposób, by aproksymacja
była jak najlepsza?
Mamy:
Ponieważ pierwszy człon wyrażenia daje się oszacować (dla dostatecznie regularnej funkcji ) przez , to ostatecznie dostajemy
Wyrażenie po prawej stronie jest minimalizowane dla i stąd inżynierska reguła:
Jeśli chcesz używać różnicy w przód, powinieneś wziąć równe co najmniej .