#if defined (LARGE_INT) 
#include "pq_defs.h"
#include "pcp_vars.h"
#include "pga_vars.h"
#include "constants.h"
#include "pq_functions.h"
#include "global.h"
#include "standard.h"

/* update the order of the automorphism group */

int update_autgp_order (orbit_length, pga, pcp)
int orbit_length;
struct pga_vars *pga;
struct pcp_vars *pcp;
{
#include "define_y.h"

   register int d, nmr_cent;
   MP_INT prime, nmr_centrals, orbit_size;

   /* divide existing automorphism group order by size of orbit */
   mpz_init_set_si (&orbit_size, orbit_length);
   mpz_div (&(pga->aut_order), &(pga->aut_order), &orbit_size);

   /* multiply existing order by order of new central automorphisms */
   if (pga->final_stage) {

      d = y[pcp->clend + 1];
      nmr_cent = y[pcp->clend + pcp->cc] - y[pcp->clend + pcp->cc - 1];

      mpz_init_set_si (&prime, pcp->p);
      mpz_init (&nmr_centrals);
      mpz_pow_ui (&nmr_centrals, &prime, nmr_cent * d);
      mpz_mul (&(pga->aut_order), &(pga->aut_order), &nmr_centrals);

   }
}

/* report the group and automorphism group order */

void report_autgp_order (pga, pcp)
struct pga_vars *pga;
struct pcp_vars *pcp;
{
   int p, n;
   char *s;

   if (StandardPresentation) return;

   p = pcp->p;
   n = pcp->lastg;

   if (pga->print_automorphism_order && (pga->capable || pga->terminal)) {
      s = pga->upper_bound ? "at most " : "";
      printf ("Order of group is %d^%d;", p, n);
      printf (" automorphism group order is %s", s); 
      mpz_out_str (stdout, 10, &(pga->aut_order));
      printf ("\n");
   }
}

/* compute (an upper bound for) the order of the automorphism group */

int autgp_order (pga, pcp)
struct pga_vars *pga;
struct pcp_vars *pcp;
{
#include "define_y.h"

   MP_INT diff, prime, nmr_centrals, sub, large;
   register int i, d, n, p;
   char *s;

   p = pcp->p;
   d = y[pcp->clend + 1];
   n = y[pcp->clend + pcp->cc - 1];

   mpz_init_set_si (&(pga->aut_order), 1);  
   mpz_init_set_si (&prime, pcp->p);

   /* large = p^d */
   mpz_init (&large);
   mpz_pow_ui (&large, &prime, d);

   mpz_init_set_si (&sub, 1);

   for (i = 0; i < d; ++i) {
      mpz_init (&diff);
      mpz_sub (&diff, &large, &sub);
      mpz_mul (&(pga->aut_order), &(pga->aut_order), &diff); 
      mpz_mul (&sub, &sub, &prime);
   }

   mpz_init (&nmr_centrals);
   mpz_pow_ui (&nmr_centrals, &prime, (n - d) * d);
   mpz_mul (&(pga->aut_order), &(pga->aut_order), &nmr_centrals);

   /* if d < n, we only have an upper bound for the order */
   pga->upper_bound = (d < n);

   if (StandardPresentation) {
      s = pga->upper_bound ? "at most " : "";
      printf ("Starting group has order %d^%d;", p, n);
      printf (" its automorphism group order is %s", s); 
      mpz_out_str (stdout, 10, &(pga->aut_order));
      printf (" \n");
   }
}
#endif 
