Kezdőoldal » Számítástechnika » Programozás » C# Taylor sorok?

C# Taylor sorok?

Figyelt kérdés

Egyik haverom azt a házit kapta, hogy programozzon egy cosinus számítót a Taylor sorok alapján. Mondtam neki egy megoldást így hirtelen felindulásból, de nem minden számra működik. Arra tippelek, hogy a faktoriálisok miatt pár tíz faktoriális után a számok mérete túllépi a double értéktartományát. Viszont a feladat szerint milliókig ki kell számoltatni a tagok értékét. Milyen változó típust használhatnék, vagy hogy lehetne ezt áthidalni?


eddig jutottam:


using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;


namespace ConsoleApplication1

{

class Program

{

static void Main(string[] args)

{

double eredmeny=0;

double a=Convert.ToDouble(Console.ReadLine());


for (int i = 0; Math.Abs(tag(i, a)) > 0.000001; i++)

{

eredmeny = eredmeny + tag(i, a);



}

Console.WriteLine("{0}", eredmeny);



}

static double faktor(double x)

{

double fakt=1;

x = x*2;

for (int j = 2; j <= x; j++)

{ fakt = fakt * j; }

return fakt;


}

static double tag(double y,double szog)

{

double t;

t = (Math.Pow((-1), y))*Math.Pow(szog,2*y)/faktor(y);

return t;


}


}

}


2011. dec. 4. 23:43
 1/5 anonim ***** válasza:

Én a helyedben double-t használnék, felesleges szívni, inkább használd a Stirling-formulát:

[link]


Ezzel nézd meg. Mondjuk kis értékeknél (<20) ez nem túl korrekt.


Megoldás lehet, hogy valameddig az egzakt formulával számolsz, utána meg a (korrigált) Stirlinggel . Magyarul ketté szeded a ciklusodat. Ha jól tudom (64-biten) 10^308 körüli számokat lehet megjeleníteni double esetén, ez kb. 170!-nak felel meg (170! = 7.257E306). Megnéztem a Wikipédián a Nemes Gergő-féle két módszert: ott a relatív eltérés a közelítés és az egzakt között 1.112E-13, a másodiknál 8.903E-14, ami szerintem már elfogadható :D A sima Stirlingnek elég nagy a relatív hibája (4.901E-4), azt láttam.

2011. dec. 5. 02:39
Hasznos számodra ez a válasz?
 2/5 _Jessy_ ***** válasza:
Ha milliókig akarod számoltatni, akkor az nem egyszerű feladat :) Igaz, hogy a Stirling-formulával kiszámolod n!-t, de ott van még a x^n probléma is. Esetleg próbálkozhatsz a BigInteger-el (.NET 4.0-ban van), az osztást pedig saját fv-el elvégezheted, nameg a végén az összeadást, de sztem. rohadt sok ideig fog számolni, ha millióig akarod futtatni a ciklust :)
2011. dec. 5. 07:35
Hasznos számodra ez a válasz?
 3/5 anonim ***** válasza:

Ez utóbbi valóban igaz, erre nem is gondoltam hirtelenjében. De itt is lehet trükközni pár dologgal, hogy a hatványozás ne szálljon el:


1) periodicitás, ekkor (-pi,pi]-re tudod szűkíteni a teljes számegyenest.

Magyarul képezd x' = mod(x,2*pi) értéket. ha x'>pi, akkor x' -= 2*pi kell.

2) paritás kihasználása [cos(x)==cos(-x)], ekkor [0,pi]-re

x'' = abs(x')

3) eltolási azonosságokkal:

cos(x) = -cos(pi-x)

cos(x) = sin(pi/2-x)


Ekkor kell egy intervallumvizsgálat, hogy eldöntsd, melyik szögfüggvényt érdemes használni:


if (x>=0 && x<pi/4){

t = cosTS(x);

}elseif (x>=pi/4 && x<3*pi/4)

t = sinTS(pi/2-x);

}elseif (x>=3*pi/4 && x<=pi){

t = -cosTS(pi-x);

}else{

printf("Valamit elbaktam!");

}


ahol cosTS és sinTS a Taylor-sort előállító függvények, x a [0,pi]-re leképzett szög.


Tehát át tudod transzformálni x∈(-inf;inf)-et egy X∈[0,pi/4] tartományba, aminek minden eleme kisebb, mint 1. Ez azért jó, mert X^(2n) sorozat konvergens (-> 0) lesz. Tehát megadhatsz bármekkora n-et. Az persze más kérdés, hogy ha n túl nagy, a sor n-edik tagja a számábrázolás miatt 0 lesz, de ez a tag már úgy sem érdekes, hiszen nagyon kicsi (64-bites double esetén 1E-308 alatt, azt hiszem).


Megj.: Mondjuk érdemes még a Lagrange-féle maradéktagot (1E-6) kiemelni a kódból (pl. az elején adni értéket, vagy kívülről adni értéket), hogy flexibilisebb, átláthatóbb stb. legyen a kód, de ez már csak kozmetikai dolog.

2011. dec. 5. 15:03
Hasznos számodra ez a válasz?
 4/5 A kérdező kommentje:
Elvileg haveromék most kezdtek el programozni és egyszerű függvényekkel kéne ezt megoldani. Legalábbis a tanáruk szerint. Lehet félre lett értelmezve valami a feladatban.
2011. dec. 5. 19:44
 5/5 anonim ***** válasza:

Elvileg amit írtam legutóbb, azt egyszerű függvényekkel meg lehet csinálni (for és while ciklus, if-else, meg hatványozás).


[A cosTS meg a sinTS azok saját függvényeid, ahol a Taylor-sorok szerint összegzel egy while-ciklusban.]


Ha a maradéktag 1E-6 körüli, akkor nem kell még Stirling-formula sem, hanem elemi módon, for-ciklussal meg lehet oldani a faktorizálást. Persze ehhez kell, hogy x^n divergens legyen (így lesz a maradéktag is divergens), tehát az intervallum-transzformációt szerintem nem lehet megúszni (De ez is elemi dolog, while-ciklus, kivonás és if-else).


A feladatban szerintem az a kihívás (amiatt nem csak egy while-ciklus az egész), hogy rá kell jönni, hogy ha a konvergenciasugáron kívül vagyunk (|x| >= 1), nem működik a sorfejtés.

2011. dec. 7. 01:42
Hasznos számodra ez a válasz?

Kapcsolódó kérdések:




Minden jog fenntartva © 2025, www.gyakorikerdesek.hu
GYIK | Szabályzat | Jogi nyilatkozat | Adatvédelem | Cookie beállítások | WebMinute Kft. | Facebook | Kapcsolat: info(kukac)gyakorikerdesek.hu

A weboldalon megjelenő anyagok nem minősülnek szerkesztői tartalomnak, előzetes ellenőrzésen nem esnek át, az üzemeltető véleményét nem tükrözik.
Ha kifogással szeretne élni valamely tartalommal kapcsolatban, kérjük jelezze e-mailes elérhetőségünkön!