
Vlastní implementace funkce arcsin(x)
Všechny Vás tu zdravím a zároveň úzkostlivě žádám nějakého dobrého programátora a nespíš i matematika, který by mi byl schopen pomoci.
Mám naprogramovat v jazyku C vlastní funkci arcus sinus, podle Taylorovy řady, což mám, jenže, v případě konvergence Taylorovy řady pro arcsin je u mezních hodnot |x|≈1 velmi pomalá. Např. pro výpočet arcsin(1) trvá 10 - 15 minut. Vím že se dá nějak udělat, že funkci rozvinu u nějakého čísla, které dobře konverguje, např. 0.5, jenže uživatel zadá např. arcsin(0.9) a já nevím, jak z čísla dostat výsledek 1.11976951 s tím, že provedu konvergenci ve vhodnějším intervalu.
Např. momentálně mé výpočty jsou takovéto:
asin(0.1) = 0.10016742116 6 iterací
asin(0.5) = 0.52359877560 17 iterací
asin(0.9) = 1.1197695150 94 iterací
asin(0.9999) = 1.5566540689 50590 iterací
no a já potřebuji např. výsledek i pro asin(0.9999999999999999), co že několik miliónů iterací a trvá to strašně dlouho.
Prý jde se nějak posunout do rozsahu, kde funkce konverguje rychleji, jenže nevím jak.
Může nějaká moc hodná duše poradit.
Předem díky a kdyžtak se ptejte na doplňující informace.
okrem toho co uz bolo pisane, ked ti milion iteracii trva 15minut, tak to je naprogramovane totalne neefektivne, to tam mas nejake cakacie slucky medzitym? :)
Mohl by být užitečný tip (hned bod 1) odsud :
http://mathoverflow.net/questions/104321/numerical -computation-of-arcsin-and-arctan-for-real-numbers
Ale nezkoušel jsem, takže z fleku nevím, zda není lepší rada výše (Manyk).
Co se týče Taylorovy řady arcsin , zkus se zamyslet nad rekurzívním naprogramováním podílů 1.3.5/2.4.6 atd. - to by mohlo výpočet zefektivnit.
rekurzivnim v tomto pripade urcite ne (nekontrolovatelne riziko stack overflow). Asi si chcel napisat "iterovanym naprogramovanim". Presne na to som narazal v mojom prispevku.
V tomto smyslu: pokud se už spočetlo 1.3.5/2.4.6 a máme spočíst 1.3.5.7/2.4.6.8, není nutné násobit a dělit všechno znovu.
ano. Len treba davat pozor na maximalne mozne hodnoty v datovom datovom type, alebo pri pouziti double na vznikajuce nepresnosti. U celych cisel ale nevznikaju nepresnosti ani u double, nepresnosti zacnu vznikat az ked ten double zacne naberat velmi velkych hodnot, takze sa to da pre zaciatok zanedbat. Ona ale funkcia na faktorial ale asi rata stejne len nasobenim double v cykle, takze ma stejnu nepresnost jak ked si to clovek sam iteruje postupne. To neni rekurzia, to slovo ma iny vyznam (volanie tej samej funkcie v ktorej som)
A pocitanie stylom (povodny)*(7/8) neni z haldiska presnosti to same jak pocitanie stylom (povodnyvrchny*7)/(povodnyspodny*8), to druhe by mohlo byt presnejsie na zaciatku, ale nepresnejsie po vela iteraciach, ale neviem teraz zhlavy to by sa muselo poriadne matematicky presetrit ze pri ktorom postupe vznika jaka nepresnost u takehoto nasobenia a delenia datoveho typu double.
P.S> to moze byt konieckoncov aj jeho problem, ze mu tam po milion iteraciach vznikaju tak obrovske cisla ze ten faktorial ak je v premennej double ma nenormalnu nepresnost. Mozno by bolo dokonca aj lepsie pocitat stylom (povodny)*(7/8) aby tam nevznikali sialene velke cisla = velka nepresnost datoveho typu. To si musi skusit.
Ano.
Reprezentace funkce Taylorovým polynomem patří určitě k lehčím partiím ve vš matematice.
I já jsem žil léta v domnění, že v případě potřeby není problém spočítat hodnotu se žádanou přesností.
To jsem si tedy myslel pěknou blbost.
Před časem jsem si umanul (popíchnut kolegou), že napíšu program, který spočte cifru pí třeba na 100000 místě.
Což o to, numerické metody existují a lze je snadno vyhledat. Taky příslušné cykly není problém v základu napsat.
Ale pak přijde vystřízlivění, když se řeší problémy, o nichž píšeš Ty i tazatel.
Cifru pí na 100000 místě sice spočítat umím, ale musel bych PC nechat zapnuté asi 14 dní nebo měsíců (teď nevím přesně). Ještě jsem tento problém nedořešil.
a samozrejme x na n-tu sa nerata dementne funkciou pow, ale ze si na zaciatku nastavim x_na_ntu = 1; a potom na zaciatku kazdej iteracie urobim x_na_ntu *= x;
Pri velkom pocte iteracii je to trilionkrat efektivnejsie. Ja som myslel ze to ich mali naucit v skole (ze zlozitost O(n^neco) je fuj a O(n) je mnam :)