|
Post by noodlesoup on May 4, 2012 5:03:36 GMT
Okay, so maybe asking for it already in assembly is asking too much, but what I'm looking for is an equation(s) that approximates sin(x) and/or arcsin(x), preferably with controllable accuracy. Thanks.
|
|
|
Post by Fringe Pioneer on May 4, 2012 5:30:45 GMT
I presume you can't just use existing assembly instructions to calculate the Taylor polynomial of sin(x) to some determined degree, centered at some arbitrary value a (i.e. using x=a as a reference point for calculation)?
f(x) = f(a)*(x + a)0/0! + f'(a)*(x + a)1/1! + f''(a)*(x + a)2/2! + f'''(a)*(x + a)3/3! + f''''(a)*(x + a)4/4! + ...
Sine of x centered at some arbitrary a: sin(x) = sin(a) + cos(a)*(x + a) - sin(a)*(x2 + 2xa + a2)/2 - cos(a)*(x3 + 3x2a + 3xa2 + a3)/6 + sin(a)*(x4 + 4x3a + 6x2a2 + 4xa3 + a4)/24 + ...
Sine of x centered at 0: sin(x) = 0 + x - 0 - x3/6 + 0 + x5/120 - 0 - x7/5040 + ... sin(x) = sum((-1)nx2n + 1/(2n + 1)!, 0, infinity)
|
|
|
Post by noodlesoup on May 5, 2012 2:36:24 GMT
Ah hah! So each prime mark on function f means the derivative, which explains why it goes sine-cosine-negative sine-negative cosine... Thanks for showing me how2Taylor, Veers. so cos(x): cos(x) = cos(0)*(x)^0/0! - sin(0)*(x)^1/1! - cos(0)*(x)^2/2! + sin(0)*(x)^3/3! + cos(0)*(x)^4/4! - sin(0)*(x)^5/5! - cos(0)*(x)^6/6! + sin(0)*(x)^7/7!... cos(x) = 1 - 0 - x^2/2! + 0 +x^4/4! - 0 - x^6/6! + 0 cos(x) = 1 - x 2/2! + x 4/4! - x 6/6!... cos(x) = 1 - x 2/2 + x 4/24 - x 6/720 ... I would say accuracy is fine from -pi/2 <= x <= pi/2
tan(x): tan(x) = [tan(0)*(x)^0/0!] + [sec^2(0)*(x)^1/1!] + [2tan(0)sec^2(0)*(x)^2/2!] - [2(cos(0)-2)sec^4(0)*(x)^3/3!] - [2(sin(0) - 11sin(0))sec^5(0)*(x)^4/4!] + [2(-26cos(0) + cos(0) +33)sec^6(0)*(x)^5/5!] + [2(302sin(0) - 57sin(0) + sin(0))sec^7(0)*(x)^6/6!] - [2(1191cos(0)-120cos(0)+cos(0)-1208)sec^8(0)*(x)^7/7!] - [2(-15619sin(0)+4293sin(0)-247sin(0)+sin(0))sec^9(0)*(x)^8/8!] + [2(-88234cos(0)+14608cos(0)-502cos(0)+cos(0)+78095)sec^10(0)*(x)^9/9!]... tan(x) = 0 + x + 0 - 2x^3/3! - 0 + 16x^5/5! + 0 -274x^7/7! - 0 + 7936x^9/9!... tan(x) = x - 2x 3/3! + 16x 5/5! - 274x 7/7! + 7936x 9/9! Accuracy sucks past x=0.2, maybe using double-angle formula will help? Or dividing sine by cosine? They are relatively accurate... I will tackle the inverse functions next.
|
|
|
Post by Qwerty on May 5, 2012 3:23:15 GMT
This math is making my brain hurt, but I think I understand it. Should be useful if we have to calculate gravitational trajectories.
|
|
|
Post by noodlesoup on May 5, 2012 4:02:42 GMT
Or navigation, and possibly projectile/laser weapons in DCPU-16 Also Wolfram Alpha did a better job with approximating tan(x): tan(x) = x + x 3/3 + x 5/5... tan(x) = x + x 3/3 + x 5/5: Using the function only for the range -pi/4 <= x <=pi/4 and then using the double-angle formula would probably be better than using the function for all values of x. for x=1.2: using the graph only:tan(1.2) - [1.2 + 1.2 3/3 + 1.2 5/5] = 0.2984876221 percent error = .2984876221/tan(1.2) = .11604 = 11.604%using the graph to find f(.6) then using the double-angle formula:f(.6) = [0.6 + 0.6 3/3 + 0.6 5/5] = .687552 double-angle formula: tan(2x) = 2tan(x) / (1-tan 2(x)): f(1.2) = 2(.687552) / (1-.687552 2) = 2.607958236 tan(1.2) - f(1.2) = -0.03580661397 percent error = |(-0.03580661397)|/tan(1.2) = .01392 = 1.392% Inverse Trigonometric Functions:Arcsin(x) = x + 1 2x 3/3! + 3 2x 5/5! + 15 2x 7/7! + 105 2x 9/9! + 945 2x 11/11!... Arctan(x) = x - x 3/3 + x 5/5 - x 7/7 + x 9/9...
|
|
|
Post by ~Memzak~ on May 8, 2012 21:08:24 GMT
Assembly I see... DCPU I see... Missiles I see...
Someone is preparing for 0x10c... >.> I understood some of the math behind your last couple posts, but didn't put much effort into reading/thinking about all of it. As for doing it in assembly... Yea... good luck with that.
|
|
|
Post by Fringe Pioneer on May 8, 2012 22:23:42 GMT
Let me warn you about one thing, although you probably already know this: don't repeatedly alternate between taking the function of and the inverse function of some value, lest the error quickly build up and not return anything close to your starting value.
sin(sin-1(sin(sin-1(sin(sin-1(sin(sin-1(x))))))) should equal x if you have the exact functions for sin(x) and sin-1(x) for any number of repetitions, but will diverge from the value of x if your error is sufficiently large enough...
|
|
|
Post by Hachi1 on Jun 21, 2012 9:27:46 GMT
wow I have no idea what you are all talking about... the most complex trig I know is simple identities
|
|
|
Post by Fringe Pioneer on Jun 21, 2012 11:06:35 GMT
Well, the subject here, as you should have been able to get from M4's post nearly two months ago, was finding ways to approximate trigonometric functions so that he can find the sine or cosine of something in DCPU Assembly, an in-game programming language for a game by Mojang AB. I knew that non-polynomial functions could be approximated with Taylor polynomials, so I told him what a Taylor polynomial was and how to take the Taylor polynomial of any function. Everything past that point was either M4 trying to approximate many other trigonometric functions or others indicating that this is above their heads...
|
|
|
Post by Qwerty on Jun 21, 2012 22:09:57 GMT
Veers, I don't think that'll help much...
M4 wanted to simulate a certain math function on a game that didn't support that function. Veers showed him a way to approximate said function using other functions.
|
|
|
Post by ganondorfchampin on Jun 22, 2012 15:48:48 GMT
wow I have no idea what you are all talking about... the most complex trig I know is simple identities The techniques being used here are calculus, not trig.
|
|
|
Post by Qwerty on Jun 22, 2012 18:30:25 GMT
It's using calculus to simulate trigonometry.
|
|
|
Post by Hachi1 on Jun 23, 2012 7:21:05 GMT
Well that's perfect. It proves I have no idea what you're all talking about. Then I should say, 'the most complex calculus I know is basic integration to find areas under a curve'
|
|
|
Post by Fringe Pioneer on Jun 23, 2012 11:42:26 GMT
Well, if you know of integrals, then surely you know of derivatives?
Generally, if you know one point on a curve and you know the derivative at that point on the curve, you can approximate where a nearby point will be if you don't know anything else about the curve.
As you know, the derivative at a point is approximately equal to the rise over the run of the tangent line from that point to a point some very small difference away. δy/δx ~ y'(x)
Multiply both sides by the difference in x. δy ~ y'(x)(δx)
Take the change in x to be the difference between some known x-value a and some x value whose y-value we wish to find. Substitute y(x) - y(a) for δy and substitute x - a for δx. y(x) - y(a) ~ (x - a)y'(x)
Add both sides by y(x - a). y(x) = y(a) + (x - a)y'(x)
Instead of merely tangent lines, you get closer approximations near your starting point if instead you use tangent parabolas, tangent cubics, tangent quartics, and so on. A pattern is revealed: this pattern is a Taylor polynomial. y(x) = y(a) + (x - a)y'(x) + (x - a)2y''(x)/2 + (x - a)3y'''(x)/6 + ...
We have several knowns: x is a value we know, a is a value we know, y(a) is a value we know, and the nth derivative of y(a) is a value we know, from n = 0 onward to infinity. With these values, we merely plug them into the Taylor polynomial, and we get the approximate the value y(x), which we don't know. For example, I want to find a general approximation for x. I know that sin(0) = 0, and I know all the derivatives of the sine function at a = 0. Let's plug the values in... sin(x) = sin(0) + (x - 0)(1) + (x - 0)2(0)/2 + (x - 0)3(-1)/6 + (x - 0)4(0)/24 + (x - 0)5(1)/120 + (x - 0)6(0)/720 + (x - 0)7(-1)/5040 + ... sin(x) = 0 + x + 0 - x3/6 + 0 + x5/120 + 0 - x7/5040 + ... sin(x) ~ x - x3/6 + x5/120 - x7/5040
If I want to find sin(0.5), which should be close to sin(π/6) = 0.5, I just have to plug in 0.5 for x. sin(0.5) ~ 0.5 - 0.53/6 + 0.55/120 - 0.57/5040 sin(0.5) ~ 0.5 - 0.0208333 + 0.0002604 - 0.0000016 sin(0.5) ~ 0.4794255
We were able to approximate that sin(0.25) was very close to 0.4794. The approximation taken directly from the calculator (in radian mode, because derivatives with trigonometric functions assume radians) is 0.4794.
This all I did: help M4 approximate a function by using a polynomial that has derivatives in it...
|
|