Qbasicnews.com

QbasicNews.Com => Challenges => Topic started by: oracle on May 14, 2003, 09:56:07 PM



Title: Trigonometry
Post by: oracle on May 14, 2003, 09:56:07 PM
Make a program that calculates the sine of an angle without using the SIN function. Here are the rules:

No SIN function (duh)
Like the statistical challenge, make it as a function
Hardware stuff is allowed, libs are not
It should be accurate to at least 8sf
Points will be awarded for speed and size of code as well as accuracy

Do not post code here just yet, or post hints, but email me the prog (twotowers@ihug.co.nz).

If there is little interest, the rules will change. Have fun!


Title: Trigonometry
Post by: wizardlife on May 14, 2003, 11:44:16 PM
Um, that's really easy if you can use the other trig ratios...


Title: Trigonometry
Post by: na_th_an on May 14, 2003, 11:49:54 PM
Yep. TAN(a) = SIN(a)/COS(a), so it is not a very difficult task.

Also, having to email the proggie is a bummer ... :( why not posting it here? (I have to open hotmail, blah blah blah and it always works bad)


Title: Trigonometry
Post by: wizardlife on May 15, 2003, 12:21:55 AM
Quote from: "na_th_an"
Yep. TAN(a) = SIN(a)/COS(a), so it is not a very difficult task.

Also, having to email the proggie is a bummer ... :( why not posting it here? (I have to open hotmail, blah blah blah and it always works bad)


OH NOES!11!!!11!

OMG you gave away the secret answer!!!1!!1!



Actually I'd forgotten that QB actually has a TAN function. I think the Pascal manual instructs you to calculate a TAN using SIN/COS, which I always thought of as rather inefficient... fortunately you'd never in a practical situation use anything but SIN, COS, and ATN.


Title: Trigonometry
Post by: toonski84 on May 15, 2003, 12:48:08 AM
well, while we're giving away "secret" trig identities, here's a good one:

sin(theta) = cos(.5pi - theta)


Title: Trigonometry
Post by: relsoft on May 15, 2003, 12:55:34 AM
Paging Glenn......
Paging Glenn......

Paging Glenn..... To post his "False Positioning" method of solving Trig functions..... Paging Glenn.....


:*)


Title: Trigonometry
Post by: wizardlife on May 15, 2003, 01:02:43 AM
Quote from: "toonski84"
well, while we're giving away "secret" trig identities, here's a good one:

sin(theta) = cos(.5pi - theta)


OH NOES!!11!!1!!! (http://www.rage3d.com/board/images/smilies/eek.gif)


sin ^ 2 = 1 - cos ^ 2


Title: Trigonometry
Post by: oracle on May 15, 2003, 06:39:29 PM
OK, since you guys are being such smarta$$e$... sorry, it's really my fault. Revised rules:

No trig functions. I want to see the *real* way that the sin function is calculated. Go out and Google (http://www.google.com/) it to see if you can find the real way.

The reason I don't want people posting code is because once someone finds the *real* way then everyone else is gonna just rip it.

Wait, no... I forgot.

I am rating this challenge through an arbitary method where each entry gains "challenge points". This simply means that if you submit a good entry, you will gain many challenge points, and if you submit something bad you won't gain as many. The measure is *completely* arbitary, so don't go submitting something really bad loads of times to try to get heaps of points. In any event, you can now post code here, but do it quick cos the actual formula is worth loads of challenge points.

Toonski84 is the leader, he submitted the code that made me realise that the challenge rules wern't up to scratch. But it works so he has 3 challenge points, he is winning.

ps: alternatively, you can submit code to me, I will review it and tell you how much you get, and your method stays secret. However, you risk someone else finding the formula and displaying it to the world and gaining big points if you do this.

Once again, sorry about the rules. Now get posting!


Title: Trigonometry
Post by: relsoft on May 16, 2003, 12:15:35 AM
too late!!! Glenn did that already. Wonder why he isn't replying.


Title: Trigonometry
Post by: oracle on May 16, 2003, 01:07:04 AM
Maybe he sent it in privately. Or maybe he didn't...

Just send them in guys!

I'm reviewing toonski's second entry as I do this!


Title: Trigonometry
Post by: oracle on May 19, 2003, 10:36:34 PM
There ain't much interest in this, so if I don't recieve another entry within 3 days of now then toonski wins. But its easy to improve what he has done, someone else challenge him.


Title: My code
Post by: Meg on May 20, 2003, 12:28:32 AM
Code:
DECLARE FUNCTION GetSin# (a#) '*** CHALLENGE ENTRY ***
DECLARE FUNCTION fact# (count&) '*** NEEDED ROUTINE ***

CLS
INPUT "Enter angle in degrees (0 to 360), you wish to calculate sine for: ", a#

si# = GetSin#(a#)

PRINT "QB VALUE= "; SIN(a#)  '*** SHOW QB ANSWER ***
PRINT "MY VALUE= "; si# '*** SHOW MY FUNCTION'S ANSWER ***

WHILE INKEY$ <> "": WEND '*** PAUSE ***
WHILE INKEY$ = "":WEND
SYSTEM

FUNCTION fact# (count&) '*** CALCULATE (2n-1)! ***
     f# = 1
     FOR x& = count& TO 2 STEP -1
          f# = f# * x&
     NEXT x&

     fact# = f#
END FUNCTION

FUNCTION GetSin# (a#)
     pi# = 3.141592653589793#
     a# = a# * (pi# / 180) '*** CONVERT DEGREES TO RADIANS ***

     DO
          n& = n& + 1
         
          p1# = (-1) ^ (n& - 1) '*** DETERMINE + OR - ***
          p2# = a# ^ (2 * (n&) - 1) '*** DETERMINE NUMERATOR ***
          p3# = fact#((2 * (n&)) - 1) '*** DETERMINE DENOMINATOR ***

          s# = s# + p1# * (p2# / p3#) '*** ADJUST SUM ***
     LOOP UNTIL n& > 70

     '*** THE HIGHER n& GOES, THE MORE ACCURATE MY FUNCTION IS***
     '*** HOWEVER, HIGHER n& WILL OVERFLOW THE FACTORIAL :( ***

     GetSin = s#
END FUNCTION


*peace*

Meg.


Title: Trigonometry
Post by: oracle on May 20, 2003, 03:17:41 AM
I have seen it, no time at the mo to give detailed result.


Title: Trigonometry
Post by: oracle on May 20, 2003, 11:43:31 PM
Right, have reviewed it. It's very accurate, but quite long, especially compared to toonski84's entry, which he pm'ed me. Meg gets 21 challenge pts. From this post, everyone has 3 days again to improve, but at the moment toonski84 is still winning.


Title: question
Post by: Meg on May 21, 2003, 01:22:10 AM
long code-wise, or long running-time wise?  it'd be really easy to make the code shorter (but somewhat less readable).

*peace*

Meg.


Title: Trigonometry
Post by: oracle on May 21, 2003, 02:01:10 AM
Both, but code-wise more.


Title: Trigonometry
Post by: toonski84 on May 21, 2003, 09:02:46 AM
without the main sub (which mine didn't include), meg's is about the same length in code size.


Title: I think the code some of you are referring to are...
Post by: Glenn on May 22, 2003, 03:36:26 PM
my routines to calculate *ARC*SIN and *ARC*COS.  At any rate, not that I'm doing anything but relieving boredom, I emailed Oracle my version of the type of routine he seemed to be looking for.  (Oracle, hopefully you've noticed that some of my comments statements wrapped in the email.  You'll have to fix those.  I should've zipped it.)


Title: Trigonometry
Post by: oracle on May 22, 2003, 07:25:49 PM
Yeah, I've got it. I'll fix it and post a score here soon.

toonski: you are still winning, but perhaps not for long now you have Glenn on your case  :wink: . Try making your one shorter. Same with you, Meg.


Title: Trigonometry
Post by: oracle on May 27, 2003, 09:37:57 PM
Right, no more interest recently, so you all have untill friday morning my time (GMT + 1200, about 40 hours) to submit final entries else toonski wins.


Title: Trigonometry
Post by: toonski84 on May 28, 2003, 02:27:28 AM
Say, do I get a cookie or something if I win?


Title: This works...8 sig figs...
Post by: Mango on May 28, 2003, 01:50:01 PM
Code:
DEFDBL A-Z              'Joe Campbell-2003
pi = 3.141592653589793#
CLS
DO
 
  sinex = 0
  sign% = 1
  INPUT "Enter an angle(degree), I'll calculate it's Sine!", angledeg
  a = angledeg
  DO WHILE a >= 360           'force angle between -360 to 360 deg
     a = a - 360
  LOOP
  DO WHILE a <= -360
     a = a + 360
  LOOP
  angrad = a * (pi / 180)     'to radians
  FOR x = 1 TO 31 STEP 2      '31 iterations is more than enough precision for 8 sig-figs
   xfac = 1    'reset between visits...

   FOR t = 1 TO x
    xfac = t * xfac           'calculate x!
   NEXT t

   sinex = sinex + (sign% * ((angrad ^ x) / xfac))  'Taylor series
   sign% = sign% * -1                               'toggle +/-
 
  IF ABS(ABS(oldsine) - ABS(sinex)) < .0000000001# THEN EXIT FOR 'stop at 9 sig-figs
  oldsine = sinex                                   'to compare to determine when to stop
 NEXT x

PRINT "SIN("; angledeg;:PRINT USING ") = #.########"; sinex             'print 8 sig-figs
LOOP
END

EDIT...oops...I didn't read the original post closely enough...I didn't make it  a function.  I'd be easy enough to make a function, though.


Title: SignIt function
Post by: Mango on May 28, 2003, 04:28:35 PM
Code:
DEFDBL A-Z              'Joe Campbell-2003
COMMON SHARED sigfig
COMMON SHARED Pi
DECLARE FUNCTION sineIt# (deg#)
CLS

sigfig = 11 'Make this smaller for less precision
Pi = 3.141592653589793#

DO
 
  INPUT "Enter an angle(degrees), I'll calculate it's Sine!", deg
  PRINT
  PRINT "SIN "; deg; " ="
  PRINT USING "#.########"; sineIt(deg); : PRINT "          rounded to 8 sig-figs"
  PRINT sineIt(deg); " All available digits"
  PRINT SIN(deg * Pi / 180); " QBasic SIN result"
  PRINT
LOOP

END

FUNCTION sineIt (deg)
sign% = 1

  sinex = 0
  sign% = 1
  a = deg
  DO WHILE a >= 360           'force angle between -360 to 360 deg
     a = a - 360
  LOOP
  DO WHILE a <= -360
     a = a + 360
  LOOP
  angrad = a * (Pi / 180)     'to radians
  FOR x = 1 TO 31 STEP 2      '31 iterations is more than enough precision for 8 sig-figs
   xfac = 1

   FOR t = 1 TO x
    xfac = t * xfac           'calculate x!
   NEXT t

   sinex = sinex + (sign% * ((angrad ^ x) / xfac))  'Taylor series
   sign% = sign% * -1                               'toggle +/-

  IF ABS(ABS(oldsine) - ABS(sinex)) < 10 ^ (-1 * sigfig) THEN EXIT FOR 'stop series when required precision is attained
  oldsine = sinex
 NEXT x
sineIt = sinex
END FUNCTION


Title: Trigonometry
Post by: toonski84 on May 28, 2003, 04:41:44 PM
y'know, i wonder if there's a way to do this without using a taylor series.  i wish there was a formula like the pi one where you can extract the nth digit.


Title: Trigonometry
Post by: Mango on May 28, 2003, 04:48:25 PM
Quote
y'know, i wonder if there's a way to do this without using a taylor series.


It can be done using the half angle formula.  This way...starting with one you can figure out (ie sin 45=(2^0.5)/2 or 30=.5 or 60 = (3^.5)/2) you can calculate enough half angles and add them together to figure out the sin of an arbitrary angle.

However, the Taylor series seems a lot more straight forward.


Title: Well of course there's a way to do it without...
Post by: Glenn on May 28, 2003, 05:03:49 PM
the Taylor series (or using trig formulas).  Tell Oracle to send you the convoluted thing I emailed him.  :)  (And you'll be real sorry you asked that.)


Title: Trigonometry
Post by: oracle on May 29, 2003, 07:34:39 PM
Heeh, I was just about to post with your method...  :wink:

I have tested Mango's method. It's pretty good also, very accurate (you needn't have rounded it to 8sf, it works up to 11sf ok), and quite fast (unlike Glenn's one, eh Glenn  :wink: ), but toonski already did the taylor series so he is still winning. I'll continue this contest for another 3 days so you guys have a chance of catching toonski.

Here's Glenn's method:

Code:
'
'  This function calculates the SINE of X by numerically solving the
' differential equation y''(x) + y = 0 via 2nd order Runge-Kutta, where
' y'' signifies the second derivitive of y(x) (and y(x) = sin(x)).
'
FUNCTION SINE#(X AS DOUBLE)
DIM Y AS DOUBLE,DYDX AS DOUBLE,DX AS DOUBLE,DYDX1 AS DOUBLE,N AS LONG
DIM I AS LONG,Y1 AS DOUBLE,Y0 AS DOUBLE,DYDX0 AS DOUBLE,DYDX2 AS DOUBLE
'
'  Find a value for the differential stepsize as close as possible to
' .000005 in magnitude that divides X integrably.
'
DX=.000005#*SGN(X)
IF DX=0# THEN DX=.000005#
'
'  N = number of iterations.
'
N=INT(X/DX)
IF N<1& THEN N=1&
DX=X/CDBL(N)
'
'  Initialize iterations.  (DYDX = first derivitive of y with respect
to
' x.)
'
Y=0#
DYDX=1#
'
'  Don't try to calcucate SIN(0).  That value is known.
'
IF ABS(X)>ABS(DX/10#) THEN
FOR I=1& TO N
Y0=Y
DYDX0=DYDX
'
'  DYDX1 and DYDX2 are for Runge-Kutta update of DYDX.  DYDX1 is for
step
' 1 and DYDX2 is for step 2.
'
DYDX1=-Y*DX
DYDX=DYDX+DYDX1
'
'  Do step 1 of Y's iteration and step 2 of DYDX's.
'
Y=DYDX0*DX
DYDX2=-(Y+Y0)*DX
'
'  Do step 2 of Y's iterations.
'
Y1=DYDX*DX
'
'  Update Y and DYDX.
'
Y=Y0+(Y1+Y)/2#
DYDX=DYDX0+(DYDX1+DYDX2)/2#
NEXT I
END IF
SINE=Y
END FUNCTION


Careful of any line wrap... and it's the slowest possible way to calculate sine ever! Special award for Glenn!


Title: Don't *make* me write a routine...
Post by: Glenn on May 29, 2003, 07:47:05 PM
to do it by summing a bunch of Bessel functions.  :)


Title: Trigonometry
Post by: Mango on May 29, 2003, 08:55:46 PM
Quote from: "oracle"
Heeh, I was just about to post with your method...  :wink:

I have tested Mango's method. It's pretty good also, very accurate (you needn't have rounded it to 8sf, it works up to 11sf ok), and quite fast (unlike Glenn's one, eh Glenn  :wink: ), but toonski already did the taylor series so he is still winning.


WOW!!!   I got penalized for using the same method as toonski, yet his code/method weren't made public??!!!  I say this whole bizness is rigged!! :lol:

Seriously, since you requested code not be posted, how can you give time preference to an earlier entry?  My skin's pretty thick, though...no hard feelings.

Glen...I'm pretty new here and have been somewhat offput by some of your posts...until now...I understand the zen of your ways.

Cheers...


Title: Trigonometry
Post by: toonski84 on May 29, 2003, 09:43:07 PM
It's okay, i'll split my cookie with you if i win.  I dont really know why my peice of crap code I got from plugging in a formula without optimizing it is winning.


Title: Trigonometry
Post by: oracle on May 29, 2003, 10:41:59 PM
Yeah, yeah, it's just that toonski came up with the idea *way* before you, mango  :wink: . You didn't get penalized much (as I said in the rules).

I said that code should not be posted, then in a later post after everyone had been saying how smart they were for using COS instead I changed the rules to getting more points if posted but still being able to post your method secretly, like toonski did. Glenn already guessed that toonski used the taylor series though... so not too secret, eh :wink:

Toonski: you got bonus points for "off the top of your head" (remember that? :wink: )


Title: Trigonometry
Post by: oracle on June 01, 2003, 11:10:51 PM
Right, that's it, toonski wins. Here is his program:

Code:
DECLARE FUNCTION sine# (theta#)
DECLARE FUNCTION factorial# (x#)
CLS
pi# = 4 * ATN(1)
q# = sine#(pi# * 2)
PRINT q#

FUNCTION factorial# (x#)
z# = 1
FOR y# = 2 TO x#
  z# = z# * y#
NEXT y#
factorial# = z#
END FUNCTION

FUNCTION sine# (theta#)
x# = 3
z# = theta#
WHILE lz# <> z#
  lz# = z#
  z# = z# - ((theta# ^ x#) / factorial#(x#))
  x# = x# + 2
  z# = z# + ((theta# ^ x#) / factorial#(x#))
  x# = x# + 2
WEND

sine# = z#
END FUNCTION


Congratulations, toonski  :king:  :king:  :bounce:  :bounce:

What would you like for winning? Here's a cookie  :wink:

Anyone got any complaints?


Title: Trigonometry
Post by: toonski84 on June 01, 2003, 11:12:12 PM
yeah, the cookie's really yello and has a freakish face on it...

I'd also like 10 bucks.  My address has been pm'd to you.


Title: Trigonometry
Post by: Mango on June 02, 2003, 12:05:53 AM
Quote from: "oracle"
Right, that's it, toonski wins. Here is his program:

Code:
DECLARE FUNCTION sine# (theta#)
DECLARE FUNCTION factorial# (x#)
CLS
pi# = 4 * ATN(1)
q# = sine#(pi# * 2)
PRINT q#

FUNCTION factorial# (x#)
z# = 1
FOR y# = 2 TO x#
  z# = z# * y#
NEXT y#
factorial# = z#
END FUNCTION

FUNCTION sine# (theta#)
x# = 3
z# = theta#
WHILE lz# <> z#
  lz# = z#
  z# = z# - ((theta# ^ x#) / factorial#(x#))
  x# = x# + 2
  z# = z# + ((theta# ^ x#) / factorial#(x#))
  x# = x# + 2
WEND

sine# = z#
END FUNCTION


Toonski...just to be a punk...This code only calculates sin of 360 deg...and it reports something like 1ee-15 instead of ZERO!!!

And furthermore...if you modified the main module to accept user input for the angle (converted to radians, of course), it still won't work if the angle is not between -360 & 360.  Man...this is punk...I don't just want part of toonski's cookie...I WANT IT ALL!!! :bounce:


Title: Trigonometry
Post by: oracle on June 02, 2003, 03:15:25 AM
1e-15 basically is zero if you think about it... if your using this function to calculate sines and plot points you'd need 10^15 horizontal pixels to make the answer wrong by one pixel. You could have some of toonski's cookie: if you had sent in your program earlier...  :wink:

toonski: $10 new zealand sound good?


Title: Punk, punk program
Post by: Mango on June 02, 2003, 11:47:39 AM
Quote from: "oracle"
1e-15 basically is zero if you think about it... if your using this function to calculate sines and plot points you'd need 10^15 horizontal pixels to make the answer wrong by one pixel. You could have some of toonski's cookie: if you had sent in your program earlier...  :wink:

toonski: $10 new zealand sound good?


I hope no one asks oracle for a SINE value...your $10 program ain't worth jack.  Try modifying the main module of toonskies prog as follows so that it will actually accept user input in degrees:
Code:
DECLARE FUNCTION sine# (theta#)
DECLARE FUNCTION factorial# (x#)
CLS
pi# = 4 * ATN(1)
DO

INPUT "enter an angle in degrees"; a#
angledeg# = a# * pi# / 180   'convert to radians

q# = sine#(angledeg#)
PRINT q#
LOOP


Now...input 45...all is well  .707

now input 30....looking good  .49999999

Now...input a number like...oh...say 2910.  This is equivalent to 30 deg...remember...sin is a periodic function...the size of the input angle size *shouldn't* matter.  Also recall that the concept of SIN is based on the unit circle with radius of 1.  This radius is the hypotinuse of a right triangle...sin is the opposite length/1.  Since 1 is the longest side of a right triangle, one of the shorter sides divided by one cannot possibly be greater than one!!!  

Did you do it...and enter 2910 (aka 30)?  The winning program (after modification to make it accept user input), oh...wait it needs (*another * modification to convert the angle to radians) returns a value of   80,328...an incorrect answer by 4.9 orders of magnitude...

All I can say is  :barf:

Now, oracle...I hate to inform you...you spent your sawbuck on snake-oil!

BTW...just having a bit-of-fun ...no serious insults intended...we're all hoping to learn something here, right??!!!


Title: Trigonometry
Post by: toonski84 on June 02, 2003, 01:56:58 PM
Only if it's after taxes, oracle.

(and pssst.  i wouldnt mark someone off for using a used method.  There's only a few good ways to calculate sine, and that's the easiest)


Title: Trigonometry
Post by: oracle on June 02, 2003, 11:53:28 PM
He only got marked down slightly... and besides he submitted ages after the comp started...

Unfortunately due to the US not giving us a trade deal there is a tax on everything we send you guys, so you'll have to make do with $7