' ******************************************************************
' This program measures the execution times of several standard
' mathematical functions, as well as some additional functions
' provided in LIBMATH
'
' The results are stored in the output file SPEED.OUT
'
' The execution time of each function takes into account the
' computation of random arguments. This corresponds to the
' execution time of the function RND
' ******************************************************************

#INCLUDE "fbmath.bi"

CONST NFUNC = 31        ' Number of functions
CONST NMAX  = 10000000  ' Number of evaluations for each function

FUNCTION TimeToEval (N AS INTEGER) AS DOUBLE
' Returns time to evaluate NMAX functions

  DIM AS INTEGER I
  DIM AS DOUBLE  T0, Y

  T0 = TIMER
  SELECT CASE N
    CASE 1
      FOR I = 1 TO NMAX: Y = LOG(RND()): NEXT
    CASE 2
      FOR I = 1 TO NMAX: Y = Ln(RND()): NEXT
    CASE 3
      FOR I = 1 TO NMAX: Y = Log10(RND()): NEXT
    CASE 4
      FOR I = 1 TO NMAX: Y = Log2(RND()): NEXT
    CASE 5
      FOR I = 1 TO NMAX: Y = EXP(RND()): NEXT
    CASE 6
      FOR I = 1 TO NMAX: Y = Expo(RND()): NEXT
    CASE 7
      FOR I = 1 TO NMAX: Y = Exp10(RND()): NEXT
    CASE 8
      FOR I = 1 TO NMAX: Y = Exp2(RND()): NEXT
    CASE 9
      FOR I = 1 TO NMAX: Y = RND() ^ RND(): NEXT
    CASE 10
      FOR I = 1 TO NMAX: Y = SIN(RND()): NEXT
    CASE 11
      FOR I = 1 TO NMAX: Y = COS(RND()): NEXT
    CASE 12
      FOR I = 1 TO NMAX: Y = TAN(RND()): NEXT
    CASE 13
      FOR I = 1 TO NMAX: Y = ASIN(RND()): NEXT
    CASE 14
      FOR I = 1 TO NMAX: Y = ACOS(RND()): NEXT
    CASE 15
      FOR I = 1 TO NMAX: Y = ATN(RND()): NEXT
    CASE 16
      FOR I = 1 TO NMAX: Y = ATAN2(RND(), RND()): NEXT
    CASE 17
      FOR I = 1 TO NMAX: Y = Sinh(RND()): NEXT
    CASE 18
      FOR I = 1 TO NMAX: Y = Cosh(RND()): NEXT
    CASE 19
      FOR I = 1 TO NMAX: Y = Tanh(RND()): NEXT
    CASE 20
      FOR I = 1 TO NMAX: Y = ASinh(RND()): NEXT
    CASE 21
      FOR I = 1 TO NMAX: Y = ACosh(1 + RND()): NEXT
    CASE 22
      FOR I = 1 TO NMAX: Y = ATanh(RND()): NEXT
    CASE 23
      FOR I = 1 TO NMAX: Y = Gamma(RND()): NEXT
    CASE 24
      FOR I = 1 TO NMAX: Y = DiGamma(RND()): NEXT
    CASE 25
      FOR I = 1 TO NMAX: Y = TriGamma(RND()): NEXT
    CASE 26
      FOR I = 1 TO NMAX: Y = IGamma(RND(), RND()): NEXT
    CASE 27
      FOR I = 1 TO NMAX: Y = Beta(RND(), RND()): NEXT
    CASE 28
      FOR I = 1 TO NMAX: Y = IBeta(RND(), RND(), RND()): NEXT
    CASE 29
      FOR I = 1 TO NMAX: Y = Erf(RND()): NEXT
    CASE 30
      FOR I = 1 TO NMAX: Y = Erfc(RND()): NEXT
    CASE 31
      FOR I = 1 TO NMAX: Y = RND(): NEXT
  END SELECT
  TimeToEval = TIMER - T0
END FUNCTION

DIM AS STRING*8 FuncName(1 TO NFUNC) => _
{"Log     ", "Ln      ", "Log10   ", "Log2    ", _
 "Exp     ", "Expo    ", "Exp10   ", "Exp2    ", _
 "Power(^)", "Sin     ", "Cos     ", "Tan     ", _
 "ASin    ", "ACos    ", "Atn     ", "Atan2   ", _
 "Sinh    ", "Cosh    ", "Tanh    ", "ASinh   ", _
 "ACosh   ", "ATanh   ", "Gamma   ", "DiGamma ", _
 "TriGamma", "IGamma  ", "Beta    ", "IBeta   ", _
 "Erf     ", "Erfc    ", "RND     "}

DIM AS INTEGER I
DIM AS DOUBLE  T

OPEN "speed.out" FOR OUTPUT AS #1

PRINT
PRINT "Time in seconds to evaluate "; NMAX; " functions"
PRINT #1, "Time in seconds to evaluate "; NMAX; " functions"
PRINT
PRINT #1, ""

FOR I = 1 TO NFUNC
  T = TimeToEval(I)
  PRINT FuncName(I);
  PRINT USING "####.##"; T
  PRINT #1, FuncName(I);
  PRINT #1, USING "####.##"; T
NEXT I

CLOSE #1

