/*
   This file is part of Numerix.  Numerix is free software; you can
   redistribute it and/or modify it under the terms of the GNU General
   Public License as published by the Free Software Foundation; either
   version 2 of the License, or (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
   USA 
*/

/* +------------------------------------------------------------------------+
   |                                                                        |
   |                            Mesures de vitesse                          |
   |                                                                        |
   +------------------------------------------------------------------------+ */

/* M. Quercia, le 08/02/2001 */


#include <stdlib.h>
#include <stdio.h>
#include "c-long_int.h"


                     /* +--------------------+
                        |  Entier aléatoire  |
                        +--------------------+ */

void xx_random(xint *a, long bits) {

  int i;
  xint x = xx(of_int)(1);
  xx(shl)(a, x, bits);
  for (i=0; i < bits/HW; i++) (*a)->e.val[i] = random() & (BASE-1);
  xx(free)(&x);

}

                    /* +-----------------------+
                       |  Programme principal  |
                       +-----------------------+ */

int main(int argc, char **argv) {
  long bits=100;
  int  all=0, mul=0, sqr=0, quomod=0, quo=0, sqrt=0, gcd=0, gcd_ex=0, help=0;
  int  nrep=1,i;
  char *cmd = argv[0];
  xint a    = xx(new)();
  xint b    = xx(new)();
  xint c    = xx(new)();
  xint t    = xx(new)();
  xint u    = xx(new)();
  xint v    = xx(new)();
  xint p    = xx(new)();
  xint q    = xx(new)();

  argv++;
  while (*argv) {
    if      (strcmp(*argv,"-h")      == 0)   help   = 1;
    else if (strcmp(*argv,"-r")      == 0)   {argv++; if (argv) nrep=strtol(argv[0],NULL,0); else help=1;}
    else if (strcmp(*argv,"-mul")    == 0)   mul    = 1;
    else if (strcmp(*argv,"-sqr")    == 0)   sqr    = 1;
    else if (strcmp(*argv,"-quomod") == 0)   quomod = 1;
    else if (strcmp(*argv,"-quo")    == 0)   quo    = 1;
    else if (strcmp(*argv,"-sqrt")   == 0)   sqrt   = 1;
    else if (strcmp(*argv,"-gcd")    == 0)   gcd    = 1;
    else if (strcmp(*argv,"-gcd_ex") == 0)   gcd_ex = 1;
    else if (strcmp(*argv,"-all")    == 0)   all    = 1;
    else if (strcmp(*argv,"-test")   == 0)   {all=1; bits=10000;}
    else bits = strtol(argv[0],NULL,0);
    argv++;
  }

  if (help) printf("usage: %s [bits] [-r nrep] [-mul] [-sqr] [-quomod] [-quo] [-sqrt] [-gcd] [-gcd_ex] [-all]\n",cmd);
  else {

    xx_random(&a,  bits);
    xx_random(&b,  bits);
    xx_random(&c,2*bits);

    /* pour tester cfrac */
    xx_random(&p,2*bits);
    xx_random(&q,2*bits);
    xx_random(&u,2*bits);
    xx_random(&v,2*bits);
    xx_random(&t,2*bits);

    chrono("début");
    if ((all) || (mul))    {for (i=0; i<nrep; i++) xx(mul)(&t,a,b);          chrono("mul");}
    if ((all) || (sqr))    {for (i=0; i<nrep; i++) xx(sqr)(&t,a);            chrono("sqr");}
    if ((all) || (quomod)) {for (i=0; i<nrep; i++) xx(quomod)(&t,&u,c,b);    chrono("quomod");}
    if ((all) || (quo))    {for (i=0; i<nrep; i++) xx(quo)   (&t,c,b);       chrono("quo");}
    if ((all) || (sqrt))   {for (i=0; i<nrep; i++) xx(sqrt)  (&t,c);         chrono("sqrt");}
    if ((all) || (gcd))    {for (i=0; i<nrep; i++) xx(gcd)   (&t,a,b);       chrono("gcd");}
    if ((all) || (gcd_ex)) {for (i=0; i<nrep; i++) xx(gcd_ex)(&t,&u,&v,a,b); chrono("gcd_ex");}

    xx(free)(&a);
    xx(free)(&b);
    xx(free)(&c);
    xx(free)(&t);
    xx(free)(&u);
    xx(free)(&v);
    xx(free)(&p);
    xx(free)(&q);

  }
  fflush(stdout); fflush(stderr);
  return(0);
}

