General Discussion > Math and Science

Approximating Tangent

<< < (2/2)

Xeda112358:

--- Quote from: pimathbrainiac on November 20, 2014, 03:56:13 pm ---Good job! Do you think this can have applications in z80 programming (is it faster, more memory efficient, etc.)?

--- End quote ---
This would not be the best way to compute tangent (though it is decent). For 21 bits of accuracy, there are probably much better ways :P It's just neat and if you've never seen Horner's method, it can get you thinking about math programming in the future.

--- Quote from: ben_g on November 20, 2014, 04:14:14 pm ---I think that if you really want speed, you should use a LUT for the sine function, calculate the cosine as sine+90°, and calculate the tangent as sine/cosine. This does require a bit of memory and isn't really related to math though.

Related: I previously had no idea how the sine, cosine and tangent were actually calculated, and good job on simplifying it so much!

EDIT: while the z80 will probably not be able to calculate that at high speed for use in games, I guess it might be usefull for CAS-related programs.

--- End quote ---
Yeah, LUT's are the fastest method. There are fairly efficient ways to use small LUTs to compute the fun functions (trig and exponentials, among others). Glad to show you something new!

--- Quote from: Hooloovoo on November 21, 2014, 01:30:45 am ---This is really cool! I found using ries that the constant is arctan(pi)/pi (if it turns out to be a constant, which seems to be the case).

EDIT: that is probably not correct. I just saw that first and it had a tangent in it. Looking at the others, 4/(pi^2) looks like it could be promising. But those are all approximations anyway.

--- End quote ---
Yeah, 4/pi2 looks most promising, but it might not converge to anything nice. Then again, I have lots of identities that I've derived about the Bernoulli numbers, so who knows! For example, if you sum them up to get 'C', then do c/(c-1), you get euler's number, and if you sum the absolute value of the terms, you get a function involving cotangent!
--- Quote from: TheCoder1998 on November 21, 2014, 01:38:49 am ---Wow this topic is really interesting!
It's pretty funny that I'm reading this now, because it's Math-day at school today :)

--- End quote ---
Math day is best day.


I worked on this a little last night, and I will probably work on this some more. I might actually figure out the constant and I would be more inclined to believe that it has something to do with e.

Xeda112358:
The best part about being friends with mathematicians a gazillion times smarter than me? They look at a problem and are like, "why don't you just use stuff you learned in Calc 2?" .__. Anyways, I figured out the main stuff, but one of my professor friends made the final, "obvious" observation. The constant does go to 4/pi2 and here is how it works:

Say we have a Maclaurin series of the form ##\sum\limits_{k=0}^{\infty}{c_{k}x^{2k+1}}=c_{0}x+c_{1}x^{3}+c_{2}x^{5}+...##MathJax.Hub.Queue(["Typeset", MathJax.Hub, document.getElementById("bbclatex664c6a5636221")]);console.log("Queued!");. Then applying Horner's Method:
##c_{0}x+c_{1}x^{3}+c_{2}x^{5}+c_{3}x^{7}+c_{4}x^{9}+...##MathJax.Hub.Queue(["Typeset", MathJax.Hub, document.getElementById("bbclatex664c6a5636231")]);console.log("Queued!");
##=c_{0}x(1+\frac{c_{1}}{c_{0}}x^{2}+\frac{c_{2}}{c_{0}}x^{4}+\frac{c_{3}}{c_{0}}x^{6}+\frac{c_{4}}{c_{0}}x^{8}+...##MathJax.Hub.Queue(["Typeset", MathJax.Hub, document.getElementById("bbclatex664c6a563623c")]);console.log("Queued!");
##=c_{0}x(1+\frac{c_{1}}{c_{0}}x^{2}(1+\frac{c_{2}c_{0}}{c_{0}c_{1}}x^{2}+\frac{c_{3}c_{0}}{c_{0}c_{1}}x^{4}+\frac{c_{4}c_{0}}{c_{0}c_{1}}x^{6}+...##MathJax.Hub.Queue(["Typeset", MathJax.Hub, document.getElementById("bbclatex664c6a5636247")]);console.log("Queued!");
##=c_{0}x(1+\frac{c_{1}}{c_{0}}x^{2}(1+\frac{c_{2}}{c_{1}}x^{2}+\frac{c_{3}}{c_{1}}x^{4}+\frac{c_{4}}{c_{1}}x^{6}+...##MathJax.Hub.Queue(["Typeset", MathJax.Hub, document.getElementById("bbclatex664c6a5636252")]);console.log("Queued!");
...
##=c_{0}x(1+\frac{c_{1}}{c_{0}}x^{2}(1+\frac{c_{2}}{c_{1}}x^{2}(1+\frac{c_{3}}{c_{2}}x^{2}(1+\frac{c_{4}}{c_{3}}x^{2}(1+...##MathJax.Hub.Queue(["Typeset", MathJax.Hub, document.getElementById("bbclatex664c6a563625c")]);console.log("Queued!");

Here is the last piece of the puzzle:

--- Quote ---Me: So I know this converges because I am basically using the ratio test of the Maclaurin Series for tangent, which I already know converges.
Dr. B: Well Zeda, you know that the limit of the ratio test is inversely related to the radius of convergence, and you know that the radius of converges for tangent about 0 is pi/2 before it gets wonky.

--- End quote ---
So if we were finding the radius of convergence, we would want to get r in the following:
##\lim\limits_{n\rightarrow\infty}{|\frac{c_{n+1}(x-r)^{2n+3}}{c_{n}(x-r)^{2n+1}}|}=1##MathJax.Hub.Queue(["Typeset", MathJax.Hub, document.getElementById("bbclatex664c6a563627e")]);console.log("Queued!");
However, we know r, and we know it is centered about x=0 (because we are using a Maclaurin series), so we get:
##\lim\limits_{n\rightarrow\infty}{|\frac{c_{n+1}(0-r)^{2}}{c_{n}}|}=1##MathJax.Hub.Queue(["Typeset", MathJax.Hub, document.getElementById("bbclatex664c6a563628a")]);console.log("Queued!");
##\lim\limits_{n\rightarrow\infty}{r^{2}|\frac{c_{n+1}}{c_{n}}|}=1##MathJax.Hub.Queue(["Typeset", MathJax.Hub, document.getElementById("bbclatex664c6a5636295")]);console.log("Queued!");
##\lim\limits_{n\rightarrow\infty}{|\frac{c_{n+1}}{c_{n}}|}=\frac{1}{r^{2}}##MathJax.Hub.Queue(["Typeset", MathJax.Hub, document.getElementById("bbclatex664c6a56362a0")]);console.log("Queued!");
Also, it happens to be that all the coefficients in the Maclaurin series of tan(x) are positive, so getting rid of the absolute value:
##\lim\limits_{n\rightarrow\infty}{\frac{c_{n+1}}{c_{n}}}=\frac{4}{\pi^{2}}##MathJax.Hub.Queue(["Typeset", MathJax.Hub, document.getElementById("bbclatex664c6a56362ab")]);console.log("Queued!");

Yay :D For extra fun, instead of using the shorthand cn to refer to the coefficients, let's plug in actual values:
##\lim\limits_{n\rightarrow\infty}{-\frac{B_{2n+4}4^{n+2}(4^{n+2}-1)(2n+2)!}{B_{2n+2}4^{n+1}(4^{n+1}-1)(2n+4)!}}=\frac{4}{\pi^{2}}##MathJax.Hub.Queue(["Typeset", MathJax.Hub, document.getElementById("bbclatex664c6a56362be")]);console.log("Queued!");
##\lim\limits_{n\rightarrow\infty}{-\frac{B_{2n+4}4(4^{n+2}-1)(2n+2)!}{B_{2n+2}(4^{n+1}-1)(2n+4)!}}=\frac{4}{\pi^{2}}##MathJax.Hub.Queue(["Typeset", MathJax.Hub, document.getElementById("bbclatex664c6a56362c9")]);console.log("Queued!");
##\lim\limits_{n\rightarrow\infty}{-4\frac{B_{2n+4}(4^{n+2}-1)}{B_{2n+2}(4^{n+1}-1)(2n+3)(2n+4)}}=\frac{4}{\pi^{2}}##MathJax.Hub.Queue(["Typeset", MathJax.Hub, document.getElementById("bbclatex664c6a56362d4")]);console.log("Queued!");
##\lim\limits_{n\rightarrow\infty}{-4\frac{B_{2n+4}4}{B_{2n+2}(2n+3)(2n+4)}}=\frac{4}{\pi^{2}}##MathJax.Hub.Queue(["Typeset", MathJax.Hub, document.getElementById("bbclatex664c6a56362df")]);console.log("Queued!");
##\lim\limits_{n\rightarrow\infty}{-16\frac{B_{2n+4}}{B_{2n+2}(2n+3)(2n+4)}}=\frac{4}{\pi^{2}}##MathJax.Hub.Queue(["Typeset", MathJax.Hub, document.getElementById("bbclatex664c6a56362ea")]);console.log("Queued!");
##\lim\limits_{n\rightarrow\infty}{-\frac{B_{2n+4}}{B_{2n+2}(2n+3)(2n+4)}}=\frac{1}{4\pi^{2}}##MathJax.Hub.Queue(["Typeset", MathJax.Hub, document.getElementById("bbclatex664c6a56362f6")]);console.log("Queued!");
##\lim\limits_{n\rightarrow\infty}{-\frac{B_{2n+2}(2n+3)(2n+4)}{B_{2n+4}}}=4\pi^{2}##MathJax.Hub.Queue(["Typeset", MathJax.Hub, document.getElementById("bbclatex664c6a5636301")]);console.log("Queued!");
##\lim\limits_{n\rightarrow\infty}{-\frac{B_{2n}(2n+1)(2n+2)}{B_{2n+2}}}=4\pi^{2}##MathJax.Hub.Queue(["Typeset", MathJax.Hub, document.getElementById("bbclatex664c6a563630e")]);console.log("Queued!");


From this you can get that ##B_{2n+2}\approx -\frac{B_{2n}(2n+1)(2n+2)}{4\pi^{2}}##MathJax.Hub.Queue(["Typeset", MathJax.Hub, document.getElementById("bbclatex664c6a563631a")]);console.log("Queued!");. And further:
##B_{2n+4}\approx -\frac{B_{2n+2}(2n+3)(2n+4)}{(2\pi)^{2}}\approx \frac{B_{2n}(2n+1)(2n+2)(2n+3)(2n+4)}{(2\pi)^{4}}##MathJax.Hub.Queue(["Typeset", MathJax.Hub, document.getElementById("bbclatex664c6a5636327")]);console.log("Queued!");
And in general:

##B_{2n+2m}\approx \frac{B_{2n}(2n+2m)!(-1)^{m}}{(2\pi)^{2m}(2n)!}##MathJax.Hub.Queue(["Typeset", MathJax.Hub, document.getElementById("bbclatex664c6a5636334")]);console.log("Queued!");


So let's put that into practice. Say we know B20=-174611/330 and we want to estimate B30:


##B_{20+2\cdot 5}\approx \frac{B_{20}(30)!(-1)^{5}}{(2\pi)^{10}(20)!}##MathJax.Hub.Queue(["Typeset", MathJax.Hub, document.getElementById("bbclatex664c6a563634f")]);console.log("Queued!");
##= \frac{174611/330(30)!}{(2\pi)^{10}(20)!}##MathJax.Hub.Queue(["Typeset", MathJax.Hub, document.getElementById("bbclatex664c6a563635c")]);console.log("Queued!");
##= \frac{55016531182.1502685546875}{\pi^{10}}##MathJax.Hub.Queue(["Typeset", MathJax.Hub, document.getElementById("bbclatex664c6a5636369")]);console.log("Queued!");
##B_{30}\approx 601581447.225687068979178849893094649083608778571...##MathJax.Hub.Queue(["Typeset", MathJax.Hub, document.getElementById("bbclatex664c6a5636376")]);console.log("Queued!"); according to Wolfram Alpha.  Meanwhile the actual value:
##B_{30}\approx 601580873.900642368384303868174835916771400642368...##MathJax.Hub.Queue(["Typeset", MathJax.Hub, document.getElementById("bbclatex664c6a5636384")]);console.log("Queued!");


This is a useful identity since the Bernoulli numbers are used in many applications, but they are tough to compute efficiently.  I am pretty sure I have seen this identity before, and I've actually hypothesized it earlier in the year (in one of my previous notebooks), but it is awesome to actually prove it!

Navigation

[0] Message Index

[*] Previous page

Go to full version