Taylorreihen und ihre Implementierung mit JAVA Ac 2016-2018k- ?· Taylorreihen und ihre Implementierung…

Download Taylorreihen und ihre Implementierung mit JAVA Ac 2016-2018k- ?· Taylorreihen und ihre Implementierung…

Post on 24-Jul-2018

212 views

Category:

Documents

0 download

Embed Size (px)

TRANSCRIPT

<ul><li><p>Taylorreihen und ihre Implementierung mit JAVA Ac 2016-2018</p><p>Taylorpolynome sind ganzrationale Funktionen T(x), welche eine bestimmte andere Funktion f(x) in der Umgebung einer vorgegebenen Stelle x0 approximieren. </p><p> 2 3</p><p>0 0 1 0 2 0 3 0 00</p><p>( ) ( ) ( ) ( ) ( ) ... ( )n</p><p>k nk n</p><p>kT x a x x a a x x a x x a x x a x x</p><p>=</p><p>= - = + - + - + - + + - </p><p>Je hher der Grad n des Polynoms, desto besser wird die Approximation in der Umgebung von x0 .Fr n = spricht man von einer Taylorreihe, welche identisch ist mit der Funktion f . </p><p>Erzeugung eines Taylorpolynoms:</p><p>Das Prinzip fr die Bildung des Taylorpolynoms T ist, dass jede Ableitung von T(x) an der Stelle x0 mit der entsprechenden Ableitung von f(x) bereinstimmen muss . </p><p>Es gilt also fr i von 0 bis n : ( ) ( )0 0( ) ( )i iT x f x=</p><p>Daraus folgen :</p><p>f (0) (x0) = a0 f (1) (x) = a1 + 2a2(x-x0) + 3a3(x-x0)2 + 4a4(x-x0)3 + + nan(x-x0)n-1 f (1) (x0) = a1 f (2) (x) = 2a2 + 6a3(x-x0) + 12a4(x-x0)2 + 20a5(x-x0)3 + + n(n-1)an(x-x0)n-2 f (2) (x0) = 2a2 f (3) (x) = 6a3 + 24a4(x-x0) + 60a5(x-x0)2 + + n(n-1)(n-2)an(x-x0)n-3 f (3) (x0) = 6a3 </p><p>Allgemein gilt: f (i) (x0) = i! ai bzw. ( )</p><p>0( )!</p><p>i</p><p>if xa</p><p>i= </p><p>Dann ist ( )</p><p>00</p><p>0</p><p>( )( ) ( )!</p><p>knk</p><p>k</p><p>f xT x x xk=</p><p>= - Taylorpolynom fr f , entwickelt an der Stelle x0 </p><p>Hierfr ein Beispiel: f(x) = sin(x); x0 = 0 . ( genauere Analyse weiter unten )</p><p>f ' (x) = cos(x) f '' (x) = -sin(x) f ''' (x) = -cos(x) f (4) (x) = sin(x) = f(x)</p><p>Also ist f ' (0) = 1 f '' (0) = 0 f ''' (0) = -1 f (4) (0) = 0 usw.</p><p>Jedes 2. Glied fllt weg und fr die restlichen Glieder alternieren die Vorzeichen.</p><p>Das Taylorpolynom fr sin(x) lautet dann: </p><p> 3 5 7</p><p>2 1</p><p>0</p><p>( 1)sin( ) ( ) ...(2 1)! 6 120 5040</p><p>knk</p><p>k</p><p>x x xx T x x xk</p><p>+</p><p>=</p><p>- = = - + - </p><p>+</p></li><li><p>Grafische Veranschaulichung:</p><p>Anmerkungen:</p><p>T2 ist das Polynom fr k = 0 bis 2, also bis zum Term x5 / 120 . T3 ist das Polynom fr k = 0 bis 3, also bis zum Term x7 / 5040 .</p><p>Fazit: Je hher der Grad n gewhlt wird, um so besser ist die Approximation !</p><p>Weitere Beispiele fr Taylorreihen :</p><p>2 2 4 6</p><p>0cos( ) ( 1) 1 ... ;</p><p>(2 )! 2! 4! 6!</p><p>kk</p><p>k</p><p>x x x xx xk</p><p>=</p><p>= - = - + - </p><p>2 1 3 5 7</p><p>0arctan( ) ( 1) ... ; 1</p><p>2 1 3 5 7</p><p>kk</p><p>k</p><p>x x x xx x xk</p><p>+</p><p>=</p><p>= - = - + - +</p><p>2 3 41</p><p>1ln(1 ) ( 1) ... ; 1 1</p><p>2 3 4</p><p>kk</p><p>k</p><p>x x x xx x xk</p><p>+</p><p>=</p><p>+ = - = - + - - &lt; Achtung: Hier beginnt der Summenindex mit k=1 . </p><p>Die Reihen fr arctan(x) und ln(1+x) konvergieren sehr langsam. </p><p>Weiter unten werden schnellere Alternativen erlutert.</p></li><li><p>Computerprogrammierung:</p><p>Zur Berechnung von Approximationswerten mit dem Computer muss ein Programm die Potenzsummen der Taylorreihe bilden knnen, was aber mit einer for-Schleife recht einfach erledigt werden kann. Da mit grer werdendem Exponenten die (Potenz-) Summanden in der Regel immer kleiner werden, ist es aus numerischen Grnden ratsam, die Summanden von hinten nach vorne abzuarbeiten.</p><p>Beispiel zur Verdeutlichung des numerischen Problems (JAVA 7):</p><p>17</p><p>01,0100501670841682</p><p>!</p><p>k</p><p>k</p><p>xk== , aber </p><p>0</p><p>171,0100501670841680</p><p>!</p><p>k</p><p>k</p><p>xk==</p><p>Das auf 17 Dezimalen genaue Ergebnis ist brigens: 1,01005016708416805</p><p>JAVA-Methode:</p><p>public static double f(double x, int k) {// Beispielfunktion fr Taylorreihen// hier: ln(x)return 2.0 / (2 * k + 1) * Math.pow((x - 1) / (x + 1), 2 * k + 1);</p><p>}</p><p>public static double taylorReihe(double x, int n) {// berechnet sum(f(x,k),k,0,n)double sum = 0;for (int k = n; k &gt;= 0; k--)</p><p>sum = sum + f(x, k);return sum;</p><p>}</p></li><li><p>1) Die Taylorreihe fr e x :</p><p>2 3 4 5</p><p>01 ... ; 0</p><p>! 2 6 24 120 !</p><p>k nx</p><p>nk</p><p>x x x x x xe x R xk n</p><p>=</p><p>= = + + + + + + + + &gt; </p><p>Fr x &lt; 0 verwende man e-x = 1/ex .</p><p>Anmerkung: Ersetzt man x durch xln(a), so kann man mit der Formel </p><p>auch ln( )x a xe a = berechnen. </p><p>Die ex-Formel lsst sich geschickt umformen, so dass man ohne die Fakulttenund Potenzen auskommt:</p><p> 01 (1 (1 (1 (1 ... (1 )))) ; 0</p><p>! 1 2 3 4 1</p><p>kx</p><p>nk</p><p>x x x x x x xe R xk n n</p><p>=</p><p>= = + + + + + + + + &gt;-</p><p>Fr das sog. "Restglied" Rn gilt: 1</p><p>0 1( 1)!</p><p>nx</p><p>nxR e mit</p><p>nJ J</p><p>+= &lt; 0,2 whlen . Dann gilt: x/m 0,2 .</p><p>Man berechnet also erst 0,2xme e mit der Summenformel und potenziert das Ergebnis mit m .</p><p>Fr den Fall 0,2e ist der maximale Fehler laut Restglied 1 1</p><p>0,2 0,21</p><p>0,2 0,2 1,222( 1)! ( 1)! 5 ( 1)!</p><p>n n</p><p>ne en n nJ</p><p>+ +</p><p>+ &lt; + + +</p><p>Will man z.B. e0,2 auf 15 Dezimalen ( = Nachkommastellen) genau berechnen, so gilt der Ansatz:</p><p> 16 1 15</p><p>11,222 5 10 5 ( 1)! 2,444 10</p><p>5 ( 1)!n</p><p>n nn- +</p><p>+ &lt; + &gt; + </p><p>Durch Probieren findet man, dass fr diese gewnschte Genauigkeit n = 11 ausreicht .Es zeigt sich, dass sogar n = 10 gengt, weil die Abschtzung doch sehr grozgig war !</p><p>Mit Java7 (und n = 10) ergibt sich e0,2 = 1.2214027581601694 (In der Tat: 15 Dezimalen genau !).</p><p>Fr ex mit x &gt; 1 reicht n = 10 nicht mehr aus, wie man an den folgenden Beispielen erkennen kann:</p><p>e2 = 7,389056098930625 13 Dezimalen korrekt (richtig: 7,38905609893065022723...) e3 = 20,085536923187565 12 Dezimalen korrekt (richtig: 20,0855369231876677409...) e10 = 22026,465794806336 9 Dezimalen korrekt (richtig: 22026,4657948067165169...)</p><p>Bei diesen Exponenten x pflanzt sich der Fehler um ein Vielfaches fort, da ja das Ergebnis von e 0,2 noch mit m potenziert werden muss (Potenzierung vergrert den Fehler um ca. Faktor m !).</p><p>Eine Erhhung des n-Wertes auf n = 11 bringt eine Verbesserung bei e2 = 7.389056098930651 (14 richtige Dezimalen). Dies wird jedoch auch durch weitere Erhhung von n nicht mehr genauer.hnlich bei e3 = 20,08553692318767 </p></li><li><p>Hinweis:</p><p>Setzt man in der ex - Formel x = 1, so erhlt man die Eulersche Zahl e 2,7182818284590452353 .</p><p>Beispielrechnung fr e mit Restgliedabschtzung:</p><p>Das Restglied lsst sich speziell fr e ( ex mit x = 1) geschickt abschtzen:</p><p>Fr x = 1 gilt: 1 0 1 ;</p><p>( 1)! ( 1)!n neR e mit R</p><p>n nJ J= &lt; &lt; . Durch Probieren findet man n 17 .</p><p>In der Tat ist 17</p><p>0</p><p>1 2,7182818284590455 ( 7)!k</p><p>JAVAk== auf 15 Dezimalen genau !</p><p>Die 16. Dezimale ist allerdings falsch .</p><p>JAVA-Methode fr e x :</p><p>public static double expReihe(double x, int n) {// berechnet sum(x^k/k!,k,0,n)</p><p>if (x == 0)return 1;</p><p>boolean xNegativ = (x &lt; 0);if (xNegativ)</p><p>x = -x;boolean reduziert = (x &gt; 0.2);int j = 1;if (reduziert) { </p><p> // falls x &gt; 0.2: e^x = (e^(x/j))^j ; j = [5x]j = (int) (5 * x);x = x / j;</p><p>}</p><p>// Beginn der Iterationdouble sum = 0.0;for (int k = n + 1; k &gt; 0; k--)</p><p>sum = sum / k * x + 1.0;</p><p>if (reduziert)sum = Math.pow(sum, j);</p><p>if (xNegativ)sum = 1 / sum;</p><p>return sum;}</p></li><li><p>2 ) Die Taylorreihe fr ln(x) bzw. ln(1 + x):</p><p>2 3 41</p><p>1ln(1 ) ( 1) ... ; 1 1</p><p>2 3 4</p><p>kk</p><p>k</p><p>x x x xx x xk</p><p>+</p><p>=</p><p>+ = - = - + - - &lt; </p><p>Da diese Reihe sehr langsam konvergiert, konstruiert man mittels ln(1+x) - ln(1-x) = ln((1+x) / (1-x)) eine neue, besser konvergierende Reihe.</p><p>2 3 2 31 1</p><p>1 1</p><p>( ) ( ) ( )ln(1 ) ln(1 ) ( 1) ( 1) ... ( ...)2 3 2 3</p><p>k kk k</p><p>k k</p><p>x x x x x xx x x xk k</p><p> + +</p><p>= =</p><p>- - -+ - - = - - - = - + - - - + m m</p><p>Man erkennt, dass sich Potenzen mit geraden Exponenten wegsubtrahieren. Daher bleibt folgendes:</p><p>3 5 7 2 1</p><p>0</p><p>1ln( ) ln(1 ) ln(1 ) 2( ...) 21 3 5 7 2 1</p><p>k</p><p>k</p><p>x x x x xx x xx k</p><p>+</p><p>=</p><p>+= + - - = + + + + = </p><p>- +</p><p>Die Substitution 1 11 1</p><p>x yy xx y</p><p>+ -= =</p><p>- + liefert </p><p>2 1</p><p>0</p><p>1 1ln( ) 22 1 1</p><p>k</p><p>k</p><p>yyk y</p><p>+</p><p>=</p><p> -= + + </p><p>Durch Umbenennung erhlt man endlich die ln(x) - Reihe:</p><p>2 1 3 2 1</p><p>0</p><p>1 1 1 1 1 1 1ln( ) 2 2 ( ... ) ; 02 1 1 1 3 1 2 1 1</p><p>k n</p><p>n nk</p><p>x x x xx R R xk x x x n x</p><p>+ +</p><p>=</p><p>- - - - = + = + + + + &gt; + + + + + + </p><p>Fr das Restglied gilt: </p><p>Diese Reihe lsst sich mittels der Substitution z = (x-1) / (x+1) einfacher notieren:</p><p>Die Reihe konvergiert am besten in der Nhe von x = 1 . </p><p>Deswegen sollte man x in Faktoren zerlegen, die in der Nhe von 1 liegen, falls x &gt; 2 1,414.</p><p>Vorgehensweise:</p><p>Man zerlegt x in 2m2-mx mit geeignetem m. So erhlt man wegen ln(x) = ln(ab)=ln(a)+ln(b) folgendes:</p><p>ln(x) = ln(2m) + ln(x/2m) = ln(22m/2) + ln(x/2m) = 2mln(21/2) + ln(x/2m) = 2mln(2) + ln(x/2m) .Dabei sollte x/2m zwischen 1/2 und 2 liegen . Wie erreicht man das ?Am besten dividiert man x so lange durch 2, bis das Ergebnis unter 2 liegt.</p><p>22( 1) 12 1</p><p>n</p><p>nx xR</p><p>x x- - = + </p><p>2 1 3 5 2 1</p><p>0</p><p>1ln( ) 2 2 ( ... ...) mit2 1 3 5 2 1 1</p><p>k n</p><p>k</p><p>z z z z xx z zk n x</p><p>+ +</p><p>=</p><p>-= = + + + + + =</p><p>+ + +</p></li><li><p>Beispiel: x = 2500 </p><p>2500/2 = 1250 1250/2 = 1125 1125/2 = 562,5 . Ergebnis: 2500/2 11 = 1,2207... &lt; 2Mit m=11 erhalten wir: ln(2500/211) = 22 ln(2) + ln(2500/211 )</p><p>Tipp: Falls 0 &lt; x &lt; 1, dann verwende man ln(1/x) = ln(1) ln(x) = -ln(x) bzw ln(x) = -ln(1/x)</p><p>Beispielrechnung fr ln(2) mit Restgliedabschtzung:</p><p>Wir wollen ln(2) auf 15 Dezimalen genau berechnen, d.h. 21 1</p><p>2 2 3</p><p>n</p><p>nR = </p><p>Aus dem Ansatz Rn &lt; 510-16 folgt:</p><p> 2</p><p>16 2 151 1 1 1 15 lg(2)5 10 3 10 2 lg(3) lg( ) 15 15,44 3 2 2 2 lg(3)</p><p>nn n n- - &lt; &gt; &gt; + &gt; </p><p>Daher sollte n=16 fr die vorgegebene Genauigkeit gengen. Wir berechnen also (mit JAVA 7)</p><p> 2 116</p><p>0</p><p>2 1ln(2) 0.69314718055994552 1 3</p><p>k</p><p>k k</p><p>+</p><p>=</p><p> = + . Dies ist auf 15 Dezimalen genau !</p><p>Beispielrechnung fr ln(100) mit Restgliedabschtzung:</p><p>2 2216 1399 99 101 101 13 lg(9801)5 10 9801 10 2 lg( ) lg(9801) 13 978,11012 100 101 99 99 2 lg( )</p><p>99</p><p>n n</p><p>n n- + &lt; &gt; &gt; + &gt; </p><p>Immerhin mssen wir hier schon bis n=979 rechnen, um die vorgegebene Genauigkeit zu erreichen. </p><p>Wir berechnen also (mit JAVA 7) 2 1979</p><p>0</p><p>2 99ln(100) 4.605170185988092 1 101</p><p>k</p><p>k k</p><p>+</p><p>=</p><p> = + . </p><p>14 Dezimalen sind genau, die 15. wird nicht angezeigt (msste aber definitiv 1 sein !)</p><p>Fazit: Die oben angegebene Transformation ln(x) = 2mln(2) + ln(x/2m) ist aus Geschwindigkeitsgrnden auf jeden Fall der direkten Methode vorzuziehen.</p><p>Die Berechnung mit Transformation liefert fr n = 9 (10; 11; ...) jeweils das gleiche Ergebnis: ln(100) = 4.605170185988093 (14 Stellen genau; in der 15.Stelle 3 statt richtigerweise 1) </p><p>Alternativ: Man kann auch ln(x) = 2ln(x) verwenden (evtl. mehrmals), um x zu verkleinern !</p></li><li><p>JAVA-Methode:</p><p>public static double lnReihe(double x, int n) {// ln(x) = 2*sum(z^(2k+1)/(2k+1),k,0,n); z=(x-1)/(x+1)if (x 1.414);if (reduziert) {</p><p>// ln(x) = 2mln(sqrt(2)) + ln(x/2^m)do {</p><p>x = x / 2;m = m + 1;</p><p>} while (x &gt; 1.414);}double z = (x - 1) / (x + 1);double sum = 0;int expo;for (int k = n; k &gt;= 0; k--) {</p><p>expo = 2 * k + 1;sum = sum + Math.pow(z, expo) / expo;</p><p>}sum = 2 * sum;if (reduziert) {</p><p>double sum2 = 0;x = Math.sqrt(2);z = (x-1)/(x+1);for (int k = n; k &gt;= 0; k--) {</p><p>expo = 2 * k + 1;sum2 = sum2 + Math.pow(z, expo) / expo;</p><p>}sum = sum + 4 * m * sum2;</p><p>}if (kleiner1)</p><p>sum = -sum;return sum;</p><p>}</p></li><li><p>3 ) Die Taylorreihe fr sin(x) :</p><p>2 1 3 5 7 2 1</p><p>0sin( ) ( 1) ... ( 1) ;</p><p>(2 1)! 3! 5! 7! (2 1)!</p><p>k nk k</p><p>nk</p><p>x x x x xx x R xk n</p><p>+ +</p><p>=</p><p>= - = - + - + - + + + </p><p> Grafik auf Seite 2 !</p><p>Fr das sog. Restglied Rn gilt: 2 1</p><p>( 1) cos( ) 0 1(2 1)!</p><p>nn</p><p>nxR x mitn</p><p>J J+</p><p>= - &lt; = doppelPi)</p><p>x = x - doppelPi;if (x &gt;= PI) {</p><p>x = x - PI;negativ = !negativ;</p><p>}if (x &gt; halbePi)</p><p>x = PI - x;}if (x == 0)</p><p>return 0;int vz = 1;double sum = 0.0;for (int k = 0; k </p></li><li><p>4 ) Die Taylorreihe fr arctan (x) :</p><p>2 1 3 5 7 2 1</p><p>0arctan( ) ( 1) ... ( 1) ; 1</p><p>2 1 3 5 7 2 1</p><p>k nk k</p><p>nk</p><p>x x x x xx x R xk n</p><p>+ +</p><p>=</p><p>= - = - + - + - + + +</p><p>Fr das sog. Restglied Rn gilt:</p><p> 2 1</p><p>21( 1) 0 1</p><p>2 1 1</p><p>nn</p><p>nxR mitn x</p><p>JJ</p><p>+</p><p>= - &lt; </p><p>+ ( evtl. gengt ein kleineres n )</p><p>Whlt man jedoch x &lt; 0,1 , dann ist der Fehler kleiner als 2 1</p><p>2 10,1 12 1 (2 1) 10</p><p>n</p><p>nn n</p><p>+</p><p>+=+ + . </p><p>Fr nk Nachkommastellen gilt dann: ( 1) 2 1</p><p>2 11 5 10 (2 1) 10 2 10</p><p>(2 1) 10nk n nk</p><p>n nn- + +</p><p>+ &lt; + &gt; + bzw.</p><p>lg(2 1) 2 1 lg(2) lg(2 1) 2 lg(2) 1n n nk n n nk + + + &gt; + + + &gt; + -</p><p>Die folgende Tabelle zeigt, wie gro der maximale Folgenindex n mindestens sein muss, damit nk Dezimalen richtig sind (Voraussetzung x &lt; 0,1 ) :</p><p>nk 8 9 10 11 12 13 14 15 16 17 18 19 20n 4 4(5) 5 5 6 6 7 7 8 8 9 9 10</p><p>Fazit: Offensichtlich muss man fr diesen Fall n = nk div 2 whlen .</p><p>Wie aber bekommt man die x-Werte unter die Grenze von 0,1 ??</p><p>Zur Transformation von |x| &gt; 1 auf den Bereich ]0;1[ verwendet man 2</p><p>arctan( ) 2 arctan1 1</p><p>xxx</p><p> = + + </p><p>Die Quadratwurzel lsst sich nach Heron schnell berechnen .</p><p>In der Regel ist eine mehrfache Anwendung der Formel erforderlich. Zum Beispiel gilt</p></li><li><p>( ) ( ) ( ) ( )2</p><p>5arctan(5) 2 arctan 2 arctan 0,81... 4 arctan 0,35... 8 arctan 0,17... 16 arctan 0,08...1 1 5</p><p> = = = = = + + </p><p>Fr groe x kann man auch auf 1arctan( ) arctan2</p><p>xx</p><p>p = - </p><p> zurckgreifen, muss dann aber p kennen.</p><p>Beispielrechnung fr arctan(5) mit Restgliedabschtzung:</p><p>x=5 muss zuerst transformiert werden (siehe oben). arctan(5) = 16arctan(0.08604899056617473) .</p><p>Wir wollen arctan(5) auf 15 Dezimalen genau berechnen, d.h.</p><p> 2 1</p><p>160,08604899.. 1 5 102 1 1 0</p><p>n</p><p>n</p><p>+- &lt; </p><p>+ + Laut obiger Tabelle reicht n = 7 . Daher ist zu berechnen: </p><p> 2 17</p><p>0</p><p>0,0840848515...arctan(5) 16 ( 1) 1,37340076694501572 1</p><p>kk</p><p>k k</p><p>+</p><p>=</p><p> - =+</p><p> 15 Stellen (JAVA 7) sind korrekt !</p><p>JAVA-Methode:</p><p>public static double arctanReihe(double x, int n) {// berechnet sum((-1)^k*x^(2k+1)/(2k+1),k,0,n)if (x == 0)</p><p>return 0;double faktor = 1;boolean negativ = (x &lt; 0);if (negativ)</p><p>x = -x;while (x &gt; 0.1) {</p><p>// transformierex = x / (1 + Math.sqrt(1 + x * x));faktor = faktor * 2;</p><p>}int vz = 1;double sum = 0.0;for (int k = 0; k </p></li></ul>

Recommended

View more >