# Sine (Sin) Algorithm Help

Show 80 post(s) from this thread on one page
Page 1 of 4 1234 Last
• 05-09-2008
StaticKyle
Sine (Sin) Algorithm Help
So I'm a college student down in Texas and I'm crunching for time atm with finals coming up and programs due in a few days.

Anyways, my professor gave me this:

double sin( float value angle){
Compute the sine of angle using as many terms in the series as required till two successive approximations differ by no more than 0.00000001. Hint: see the example for computing square roots. The sine of a number may be found using the following series.
Sin( x ) = x  x3/3! + x5/5!  x7/7! + ●●●
}

To figure out the sin function for my program I need to figure out the algorithm to calc a sin.

We were also given this snipet of code to help us try to do this, but it is wiht square roots and is very little help to me if I can't figure out how to put the Sin(x)... into algorithm format.
Here is the code snipet.

/
Code:

/ #define EPSILON 0.000001 // Traditional constant definition.
const double EPSILON = 0.000001;

double sqrt( double n) {
double guess;
if (n >= 0.0) {  //verify legal input
for (guess = n;
!( fabs(guess * guess  n) < EPSILON);
guess = ( ( n + guess * guess) / (2.0 * guess) )
) /* null body for loop */ ;

return(guess);
}
else
return (-1.0); //error flag
}

Thanks a lot, and if you need anymore details on this, I'd be glad to try to explain better.
• 05-09-2008
laserlight
Express this in summation notation:
Sin( x ) = x – x3/3! + x5/5! – x7/7! + ...

This will give you the formula for one term. With that formula, you can easily write a for loop. Instead of looping to infinity, loop to some arbitrary maximum. Test that your implementation works. Only when you have checked that your implementation at this point is correct then begin to think about how to implement the requirement to terminate when "two successive approximations differ by no more than 0.00000001".
• 05-09-2008
StaticKyle
Oops! Looks like it didn't format it correctly.

Sin( x ) = x  x^3/3! + x^5/5!  x^7/7! + ●●●

So instead of it being x times 3, it is x up to the third power. Sorry about that. But what do you mean summation notation?

I'm guessing it is something like this, except this is for the square root function.
R(n+1) = (X + R(n)**2) / (2 * R(n))

Thanks for the quick reply :D
• 05-09-2008
laserlight
Quote:

But what do you mean summation notation?
You should have learnt this in elementary mathematics, but perhaps you are not familiar with the term: Summation Notation

Quote:

I'm guessing it is something like this, except this is for the square root function.
R(n+1) = (X + R(n)**2) / (2 * R(n))
That is a recurrence relation, not a sum expressed in summation notation.
• 05-09-2008
StaticKyle
Would it be something like this (Sorry, I remember what it is, but I have never been good at creating them.. Never actually been taught on how to even try to do it, so here goes.)

Summation of ((x^n)/n!) - ((x^n+2)/(n+2)!) ? Or something close to it?

Thanks again.
• 05-09-2008
laserlight
Quote:

Summation of ((x^n)/n!) - ((x^n+2)/(n+2)!) ? Or something close to it?
You're close, but the problem is that that is two terms. You can still write a for loop with 2 terms, but it will affect the "two successive approximations differ by no more than 0.00000001" requirement since you would only be able to terminate when two successive pairs of approximations differ by no more than some value.
• 05-09-2008
StaticKyle
So maybe this... (x^n/n!) * -1?

I'm really trying to understand this.. I just can't seem to understand how to get it going from x^3 to x^5 ... in increments of two, and also the whole adding and subtracting thing.
• 05-09-2008
laserlight
Quote:

So maybe this... (x^n/n!) * -1?
Ah, you have the right idea. It would be more like:
n = 0 to infinity
sine(x) = (-1)^n * (x^(2n+1) / (2n+1)!)

Now, note that you do not actually need to compute (-1)^n. Rather, note that when n is even you add to the sum, and when it is odd, you subtract from the sum.

You also do not need to compute x^(2n+1) in full on each iteration of the loop. Rather, note that on the previous iteration you already calculated x^(2n-1), so now you just need to multiply that with x^2. Likewise, you do not need to compute (2n+1)! in full on each iteration of the loop.
• 05-09-2008
StaticKyle
Awesome! Now lets see if I can actually write out the loop and then figure out the other part.
Code:

for (i = 1; i < 10; i++)
{
if (i % 2 == 0)
{
x = x + (x^(2i+1)/(2n+1)!);
}
else
{
x = x - (x^(2i+1)/(2n+1)!);
}
}

I think this will work, it just wont be as effective as your suggestion, but again, it is like 6 am and I had troubles understanding how to get it to the initial value to be able to just do x^2.
• 05-09-2008
matsp
Obviously, you don't want to update x (as that is your input of the angle in radians), but I take that's a typo.

You can do the if(i % 2 == 0) "automatically" by just having a variable sign that you set to 1 to begin with, then alternate the sign as you loop through (sign = -sign), and multiply into the calculation. That is highly likely to be faster than the %2 check (even if the compiler optimizes it to better than "divide by two").

You can also calculate the (2n+1)! as part of your loop, rather than doing a factorial each iteration. d = d * i * (i +1) or something like that.

--
Mats
• 05-09-2008
StaticKyle
Yeah, that was a typo, so here is maybe a better one.
Code:

int d = 1;
double y = x;
double m = -1;
for (i = 1; i < 10; i++)
{
k = 2*i+1;
d = d * k * (k-1);
y = y + m*(y^k/d);
}
return y;

How is this? I'm still trying to get it to the beginning part. but I think this is a better start.
• 05-09-2008
matsp
You still accumulate in the same variable that you have as input to the calculation.

Code:

y = y + m*(x^k/d);
Edit: And ^ is not "raised to the power of". Again, you can achieve this by having a "x2p1" variable that is intialized with x, and then multiplied by -1*x*x.

--
Mats
• 05-09-2008
StaticKyle
I'm sorry if this is frustrating, but I really don't know what a x2p1 variable is. But yeah, I'm sorry about the ^ thing, meant to put **, but oh well. Bleh, I actually feel more confused now.
• 05-09-2008
matsp
Well ** doesn't work in C either - but if you are just writing it symbolically, then that's fine.

The x2p1 is "x to the power of 2n+1" - perhaps there is a better name for that, but my point is that you don't need to calculate x**(2n+1) each time you do the loop, but instead, you can calculate x**(2n+1) iteratively by just multiplying the current value by x *x - and to fix up the sign, multiply by -1 as well.

--
Mats
• 05-09-2008
StaticKyle
The ** doesn't work in C? Lol.. I've been programming in Ada for too long then.

So, instead of the x**(2n+1) I just use x*x *-1, or would it be y = y *x*x*-1? (Again, sorry if it is annoying, I'm just trying to learn C, and to pass my class with an understanding of the language. But C is very new to me)
Show 80 post(s) from this thread on one page
Page 1 of 4 1234 Last