Are you aware of how you can use the period and symmetry of the sine function to aid computation ?
G'day everyone..
Not sure if this question is in the right forum but here goes...
I currently trying to write some computer code to generate Sine(x).
I have found a site explaining the Taylor series approximation method.
As follows
sin(x) = x - (x^3)/3! + (x^5)/5! - (x^7)/7! + ...
Keep in mind that x is in radians and not in degrees!
Also, notice that it is not practical to compute x^3, x^5, x^7,... Instead, re-write the Taylor series in a nested form
sin(x) = x*(1 - (x^2)/3! + (x^4)/5! - (x^6)/7! + ...)
sin(x) = x*(1 - (x^2)*(1/3! - (x^2)/5! + (x^4)/7! -) ...)
Or, dropping the higher order terms
sin(x) ~ x*(1 - (x^2)*(1/3! - (x^2)(1/5! - (x^2)/7! )))
Finally, the factorial terms may be factored:
sin(x) ~ x*(1 - (x^2)*(1 - (x^2)(1 - (x^2)/(6*7) ) / (4*5) ) /(2*3) )
Ok so i used the last factored out formula (Above) to then extrapolate a series of multiplies, devides and subtractions to derrive the answer.
Unfortunatly 3 terms in this series is not enough to give the required accuracy
and from what i have read i need at least 6 so the new longer formula is
sin(x) = x -(x^3)/3! + (x^5)/5! - (x^7)/7! +(x^9)/9! -(x^11)/11!+(x^13)/13!
My problem is how do i factor this out the same as they did above. I am ok at doing equasions but hopless at algerbra. I simply canot figure how they got
sin(x) ~ x*(1 - (x^2)*(1 - (x^2)(1 - (x^2)/(6*7) ) / (4*5) ) /(2*3) )[/
from
sin(x) = x - (x^3)/3! + (x^5)/5! - (x^7)/7!
It took me a while to realise the signifigance of the ! in the equasion but even with this i still can't work it out.
I guess i would like someone to do it for me but if you can explain it as well that would be great!!
Thanks
Leeroy
If you bothered to find out how to compute the sin function you would
have discovered that you need only compute it for a very restricted
range of x. The sin for angles outside this range are reduced to the range
using the periodicity of sin, its antisymmetry, and fractional angle angle
formulae.
Then inside the restricted range a minmax polynomial approximation is
used to evaluate the sin, not the Taylor series.
RonL
G'day guys
First up, Topsquark, let me please apologise for posting in the wrong forum and for the double post. I was so keen to get my message posted that i am guilty of not reading the rules for this forum, so again, sorry guys it won't happen again..
Ok so back to Sine(x)..
I am aware that you can only use the Taylor series with 6 terms for a low value of x, say up to 90 deg with an accuracy of arround 6 decimal places. This accuracy level is more than enough, however i would like (for ease of programming) to be able to calculate Sine(x) up to 360 deg. Ie compute a negitive value for angles >180 deg. I am trying to write some microcontroller code to to some trig calculations. The compiler i am using supports 32 bit floating point numbers however i can only do +, -, *, / and print my result. The compiler dosn't allow for conditional checking with floating point data type. Ie i can't use an expression like (x being floating point)
IF X> 90 then X=180-X
The above expression would be great as i could then calculate any angle up to 180 deg (or more with further expressions) using a max X value of 90 deg, but it's a no go..
I have also looked at the cordic method for compuiting sine but failed to find an explanation that i could truly understand.. Or code that that i could implement, given the above compiler limitations.
At this point i will happily stick my hand in the air and admit i remember almost nothing about calculus or algebra from high school.. 20 years ago...
I'm just a lowly machinist who happens to enjoy diy computer programming and electronics..
So if if any one can show me a better way to calculate sine i am all ears, but please try and keep it in fairly laymans terms so i can bend my brain arround it..
Cheers
Leeroy
If you have the means of extracting the sign bit of the float (ieee #
representation its bit 31 for single precission and 63 for a double) you
can test if this is ==1 (that is negative) That will give you the ability
to compare floats (though you will still have to worry about the
NaNs/infinities in the representation).
RonL
CaptianBlack, yep recon that will probably do the trick!. If i can do x-180
and then check if the result is negitive or not. I will look into this.. I' not sure what method of Floating point representation the author of the software has used (there are several) but if i can read the sign bit then this will solve my problem..
This just leaves the factorisation of the 6 term series, no one has yet given any clues on how i can do this. I have to say that i found calculus and algerbra pretty boring in high school, but much more interesting now!!
Cheers
Leeroy
G'day CaptianBlack
I found the section 4.3.97 from Abramowitz and Stegun.
However i am still haing dificalty arriving at the right answer!
I have done several calculations for sine using
Using the number set shown in the paper and i get a correct answer every time. :-)
However when i try to use the nested form below i can't get the correct answer. Of the three examples i tried the answer was only good for 1-2 decimal places..
I think it's the way i do the equasion so let me show you what i did and you can tell me where i went wrong.
For example lets do Sine(x) for 25.55 deg.
25.55 DEG = RAD 0.445931623
So x=RAD
I have re-written the equasion to look like
The answer i get is 0.423992833
When the correct answer is 0.431298587
Am i correct in re-arranging the equasion this way or is this why i get an incorrect answer?
Cheers
Leeroy
The nested product does not rearrange to the form you have been using.
The following shows the correct method:
RonLCode:>A=random(1,5); ..random set of coefficients > >.. define function test(x,A) using the nested method >function test(x,A) $ x2=x*x; $ lng=length(A); $ B=A(1)|A(2:lng)/A(1:lng-1); $ pp=1+B(lng)*x2; $ for idx=lng-1 to 1 step -1 $ pp=pp*B(idx)*x2+1; $ end $ return pp $endfunction > > >..define function test2 using the direct method >function test2(x,A) $ ss=1; $ xp=1; $ for idx=1 to length(A) $ xp=xp*x*x; $ ss=ss+A(idx)*xp; $ end; $ return ss $endfunction > > > > >test(0.2,A) 1.01198 > >test2(0.2,A) 1.01198 >