/*-=-=-=-=-=-=-=-=-=-=-=- RCCL/RCI Notice of Copyright -=-=-=-=-=-=-=-=-=-=-*
 *									    *
 *	Copyright (C) 1987, 1991 by John E. Lloyd and Michael C. Wrinn.	    *
 *									    *
 *	Information on copyright permissions, as well as a complete	    *
 *	disclaimer of warranty, is given in the file COPYRIGHT.		    *
 *									    *
 *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/

#include <math.h>

#include "../h/fastmath.h"

#include "../h/cputime.h"

#define	COMMAND(s)	(strcmp (key_buf, s) == 0)
#define	COMMANDS(s)	(strncmp (key_buf, s, strlen(s)) == 0)
char key_buf [256];

float SQRT();

main()
{
	char *keytree, *tree_match_parse(), *tree_match_err_at();

	int numSamples, range;
	float testX;

	keytree = tree_match_parse("					\
(	quit								\
	test 								\
	 ([SQRT]							\
	  (%d",&range,",0,,		\"sizeof test interval\"	\
	   (%d",&numSamples,",0,,	\"number of samples\")))	\
	time 								\
	 ([SQRT sqrt]							\
	  (%d",&numSamples,",0,,	\"number of iterations\"))	\
	run 								\
	 ([SQRT]							\
	  (%f",&testX,",,,		\"test value\"))		\
)",0);
	if (keytree == 0)
	 { printf ("ERROR/Parse error at %.30s\n", tree_match_err_at());
	   exit (-1);
	 }
	do
 	 { tree_match (keytree, "SQRT TEST> ", key_buf);

	   if (COMMANDS("test"))
	    { double maxDiff = 0.;
	      double check, result, x, worstX;
	      double convert;
	      double error;
	      int i;

	      convert = range/(float)numSamples;
	      worstX = 0.0;

	      if (COMMAND("test SQRT"))
	       { for (i = 0; i<numSamples; i++)
	          { x = i*convert;
	 	    result = SQRT (x);
	 	    check = sqrt (x);

		    if (check == 0.0)
		     { error = fabs(result-check);
		     }
		    else
		     { error = fabs(result-check)/check;
		     }
		    if (error > maxDiff)
		     { maxDiff = error;
		       worstX = x;
		     }
		  }
	       }
	      printf ("Maximum error = %lg at x = %lg\n", maxDiff, worstX);
	    }
	   else if (COMMANDS ("time"))
	    { double time1, time2, looptime;
	      double result;
	      double x = 1.2345;
	      int i;

	      time1 = cputime (User);
	      for (i=numSamples; i>0; i--)
		 ;
	      time2 = cputime (User);
	      looptime = time2 - time1;

	      if (COMMAND ("time sqrt"))
	       { time1 = cputime (User);
		 for (i=numSamples; i>0; i--)
		  { result = sqrt (x);
		  }
		 time2 = cputime (User);
	       }
	      else if (COMMAND ("time SQRT"))
	       { time1 = cputime(User);
		 for (i=numSamples; i>0; i--)
		  { result = SQRT (x);
		  }
		 time2 = cputime(User);
	       }
	      printf ("Execution time = %lg micro seconds\n", 
		       (time2 - time1 - looptime) * 1000000.0/numSamples);
	    }
	   else if (COMMANDS ("run"))
	    { double result;

	      if (COMMAND ("run SQRT"))
	       { result = SQRT(testX);
	         printf ("SQRT: %12lg\n", result);
	         printf ("sqrt: %12lg\n", sqrt(testX));
	       }
	    }
	 }
	while (!(COMMAND("quit")));
}
