sirSolarius 138 Report post Posted July 17, 2005 So I have an "infinite precision calculator," and I want to add more complicated functions like sin/cos/etc. I assume that the way to do this would be with a Taylor series, but the numbers get really big, really quickly because of that factorial. Is there a really good way to do this, or should I just use the error bound formula to get a number of required loops and chug it out with the Taylor Series? 0 Share this post Link to post Share on other sites
AsOne 326 Report post Posted July 17, 2005 There's some forumals here to find sine, cosine, and tangent using calculus and other methods. Clicky! 0 Share this post Link to post Share on other sites
Mantear 251 Report post Posted July 17, 2005 I'm prety sure calculators like the TI line use Taylor series for their calculations. If it's good enough for TI calcs, it's probably good enough for your purposes. 0 Share this post Link to post Share on other sites
Fruny 1658 Report post Posted July 17, 2005 Quote:Original post by sirSolariusI assume that the way to do this would be with a Taylor series, but the numbers get really big, really quickly because of that factorial.It doesn't have to.After all, ifcos(x) = sum(n=0..∞, a_{n}) witha_{n} = (-1)^{n}.x^{2n} / (2n)!Then a_{n+1} = -a_{n} * x*x / ((2n+1)*(2n+2))So you can write:multiprecision cosine(mutiprecision x, unsigned long n){ multiprecision result = 0; multiprecision a = 1; for(unsigned long i=0; i<=n; ++i) { result += a; a *= -(x*x)/((2*n+1)*(2*n+2)); } return result;}No factorials involved. 0 Share this post Link to post Share on other sites
Sagar_Indurkhya 253 Report post Posted July 17, 2005 double sine(double x){ double xsquared = -1 * x * x, last = x; for(int i = 3; i <= 21; x+= last *= xsquared/((i*i-i), i+=2); return x;}There's sine for you. I wrote it(I'm particularily fond of this nifty piece) in a few minutes right after the Calculus BC exam, since it was fresh on my mind. Basically, you can replace the number 21 with any number, with the higher the number, the higher the accuracy. 0 Share this post Link to post Share on other sites
Fruny 1658 Report post Posted July 17, 2005 Sagar_Indurkhya - there's no need for such obfuscation, it won't make your code any faster.double sine(double x){ const double xsquared = -1 * x * x; double last = x; for(int i = 3; i <= 21; i+=2) { x+= last; last *= xsquared/(i*i-i); } return x;} 0 Share this post Link to post Share on other sites
iMalc 2466 Report post Posted July 18, 2005 Quote:Original post by MantearI'm prety sure calculators like the TI line use Taylor series for their calculations. If it's good enough for TI calcs, it's probably good enough for your purposes.Actually, calculators generaly use the faster 'CORDIC' method for trig.Sagar's function above (which Fruny beautified) is how I calculate sine for my multi-precision math library. Cosine is very similiar. This method is 'good enough'.Though to be picky, I'd write -x * x instead of -1 * x * x, and exit the loop only when the answer stops changing. 0 Share this post Link to post Share on other sites
sirSolarius 138 Report post Posted July 18, 2005 Quote:Original post by FrunySagar_Indurkhya - there's no need for such obfuscation, it won't make your code any faster.(code)Ok, I feel stupid since I took BC Calc last year, but where does this come from? I think it's just hard to see in c++ code for me.I just figured that you need more and more loops to get accuracy the further you stray from your "a" value in the Taylor Series. Since the obvious answer is to use McClaurin, I figured that I would find the closest value of 2pi, calculate the offset from that and then put the value between 0 and 2pi. Then I could use McClaurin and add the offset back in.Edit: Tried this, and got like .9794 for sin(.5) when calc.exe says it should be like .479.... ChugNumber GetVal() { ChugNumber x=m_right->GetVal(); const ChugNumber xsquared = -x * x; ChugNumber last=x; int nLoops=21; // change later for(int i=3; i <= nLoops; i+=2) { x+=last; last*= xsquared/(i*i-i); } return x; }[Edited by - sirSolarius on July 18, 2005 1:36:59 PM] 0 Share this post Link to post Share on other sites
Sagar_Indurkhya 253 Report post Posted July 18, 2005 Quote:Original post by sirSolariusQuote:Original post by FrunySagar_Indurkhya - there's no need for such obfuscation, it won't make your code any faster.(code)Ok, I feel stupid since I took BC Calc last year, but where does this come from? I think it's just hard to see in c++ code for me.I just figured that you need more and more loops to get accuracy the further you stray from your "a" value in the Taylor Series. Since the obvious answer is to use McClaurin, I figured that I would find the closest value of 2pi, calculate the offset from that and then put the value between 0 and 2pi. Then I could use McClaurin and add the offset back in.Edit: Tried this, and got like .9794 for sin(.5) when calc.exe says it should be like .479.... not shown hereWell, I am pretty sure I did stuff in my AB/BC class(studied both) your class probably didn't do. It was a self-study, w/o any teachers, at home, etc. Just some prepbooks, a few textbooks(I found the prepbooks better), and me and my computer. Since I have been programming for a long time, longer than I learned calculus, I naturally integrate everything I learn into programming. That probably helped me the most in terms of both my mathematics skills, aswell as my programming skills. So I studied during the year like this:June 2004 -> February 2005 Mulled over differentiation, daydreamed, programmed, forgot about calculus... etc.March 2005 - April 2005 Realized the exam was around the corner, finished diff, started integ. I also did a lot of programming for expression parsers, and built a graphing calculuator application that could do integration and differentiation(numerical). This really helped me.Last two weeks of April 2005 Studied all BC content. Took examWrote my math library(3/4th way).The funny thing is that all these super arrogant BC seniors treated me like some shit on the road, as though I was some ambitious guy who couldn't make it happen. It was pretty depressing, since they effectively shut me out of attending any after school tutorial sessions. I once took home some homework 3 weeks before the exam, and couldn't do a single problem. I took a practice exam(the released 2003 exam), and got about 68%. 2 days later I took the exam and got a 5. It was honestly my most confident exam in my whole life. I actually enjoyed taking it, and got almost every question right(still not clear over problem 3, last part).I was surprised, considering I am the guy who got the lowest score on the 1st semester math exam(precalc) and scraped a C. Calculus helped me a lot. It gave me insight into all my other subjects, and extended my ability to understand more difficult topics. Next year(gonna be a junior, woot!), I look forward to multivariable and graph theory.I know that you probably think that I am just boasting or something(I think I am, sorry), but I feel that if other kids like me come on these forums, they get something out of it. I remember when I use to go and ask for help, people would just tell me to go home, and work on something achievable. It is also something I am extremely proud of myself for. I don't fare well at competitions like AMC or USACO, and after I got a 4 on AP Stats, I was pretty upset, so this really helped me out.Anyway, long post, but let me get to my function:double sine(double x){ double xsquared = -1 * x * x, last = x; for(int i = 3; i <= 21; x+= last *= xsquared/((i*i-i), i+=2); return x;}our taylor function looks something like this:sin(x) = x - (x^3)/(3!) + (x^5)/(5!) - (x^7)/(7!) + ...which you will notice follows the pattern:(x^n)/(n!) where n is odd.so what I did was set xsquared as -1 * x^2and last as x.Now x already holds the value of x, something we can take advantage of.we do x += (last *= xsquared/(i * (i - 1))), and add 2 to i(keeping it odd)which gives us a very accurate answer.Note: you can calculuate accuracy in linear time, which is good( O(n) I believe), where n is degree of accuracy.If you want to use it for any number however, you have to do some tricky manipulation, because all values are essentially between -PI and PI.hmmm... way to long a post. Hope it helped. 0 Share this post Link to post Share on other sites
sirSolarius 138 Report post Posted July 18, 2005 Yeah I definitely did the Taylor Series in my calc class, I just wasn't paying attention to how you were structuring it in your code.And no offense, but the 5 on the AP probably is the same as your 68%. The scale generally gives a 5 for a 60-70%+ score, without counting the written section. You also cannot ever find out your answers, so saying that you got "almost every question right" is misleading because you could have gotten a 70% for all you know =)Anyway, I must have done something stupid in my algorithm, since it's so far off. Argh, I'm going to take a look and see what's up... 0 Share this post Link to post Share on other sites
Sagar_Indurkhya 253 Report post Posted July 18, 2005 Well, it would be misleading for multiple choice questions, but I triple checked, and am pretty sure. Anyway, I know I got it right on the Free Response, cuz I checked out the scores online.Still, I think CORDIC is the way to go for a lot of applications. 0 Share this post Link to post Share on other sites
Guest Anonymous Poster Report post Posted July 18, 2005 just use an infinite lookup table. 0 Share this post Link to post Share on other sites
Code-R 136 Report post Posted July 18, 2005 Quote:Original post by Anonymous Posterjust use an infinite lookup table.That's Just AWESOME! 0 Share this post Link to post Share on other sites