Re: sine and cosine functions
Re: sine and cosine functions
- Subject: Re: sine and cosine functions
- From: Doug McNutt <email@hidden>
- Date: Fri, 27 Feb 2004 11:49:21 -0700
At 10:44 -0600 2/27/04, ehsan saffari wrote:
>
Thanks Doug, Deivy & Emmanuel
This kind of AppleScripting is fun. I added a test to limit unnecessary loop passes. It works because both the sine and cosine series alternate in sign and the error is known to be less than the last item in the sequence. It's interesting to test speed vs desired accuracy and the loop count versus range of angles. Sines above 45 degrees and cosines between 45 and 90 degrees are slow.
The number of passes can also be reduced by taking advantage of the fact that cos(x) = sin(x+90). Using that formula with only two different Taylor series loops which always calculate a sine or a cosine of an angle between 0 and something near 45 degrees will speed things up at the expense of some logical tests. If the cosine is to be calculated for, say 70 degrees take the sine of 160 instead.
And while you're at it the tests for angles that result in 0, -1, or +1 should be done after conversion to the principal range.
set angle to -361
set increment to 1 / 16
set limit to 1.0E-5 -- limit for the squares test.
set accuracy to 1.0E-12 -- accuracy of the calculations
global accsquare -- for stopping the loops. abs(x) doesn't work.
set accsquare to accuracy ^ 2
global counter -- keeps track of the highest number of passes in the loops.
set counter to 0
repeat while angle < 362
set small to (cosine_of(angle)) ^ 2 + (sine_of(angle)) ^ 2 - 1
set tester to small
if small < 0 then
set tester to -small
end if
if tester > limit then
set aline to "angle = " & (angle as text) & return & "error = " & (small as text)
display dialog aline
end if
set angle to angle + increment
end repeat
display dialog counter
----------------------------
on sine_of(x)
global accsquare
if x is in {-360, -180, 0, 180, 360} then
set answer to 0
else
set x to (x - (((x / 360) div 1) * 360)) * (pi / 180)
set {answer, numerator, denominator, factor} to {0, x, 1, -(x ^ 2)}
repeat with i from 3 to 100 by 2
if i > counter then -- remove
set counter to counter + 1 -- remove
end if -- remove
set addend to numerator / denominator
set answer to answer + addend
set numerator to numerator * factor
set denominator to denominator * i * (i - 1)
if addend ^ 2 < accsquare then
exit repeat
end if
end repeat
end if
return answer
end sine_of
on cosine_of(x)
global accsquare
if x < 0 then set x to -x
if x is in {90, 270} then
set answer to 0
else if x = 0 then
set answer to 1
else
set x to (x - (((x / 360) div 1) * 360)) * (pi / 180)
set {answer, numerator, denominator, factor} to {0, 1, 1, -(x ^ 2)}
repeat with i from 2 to 100 by 2
if i > counter then -- remove
set counter to counter + 1 -- remove
end if -- remove
set addend to numerator / denominator
set answer to answer + addend
set numerator to numerator * factor
set denominator to denominator * i * (i - 1)
if addend ^ 2 < accsquare then
exit repeat
end if
end repeat
end if
return answer
end cosine_of
--
--> There are 10 kinds of people: those who understand binary, and those who don't <--
_______________________________________________
applescript-users mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/applescript-users
Do not post admin requests to the list. They will be ignored.