#include "pq_defs.h"
#include "pcp_vars.h"
#include "pga_vars.h"
#include "pq_functions.h"

/* for each automorphism, compute its inverse */

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

   register int alpha;
   int ***inverse;
   int nmr_of_bytes = pcp->lastg;
   int **Power;
   int string = pcp->lused + pcp->lastg;
   int cp = pcp->submlg - pcp->lastg - 2;
   register int i, j;

   inverse = allocate_array (pga->m, pcp->lastg, pcp->lastg, TRUE); 
   Power = allocate_matrix (pcp->lastg, pcp->lastg, 1, FALSE); 

   for (alpha = 1; alpha <= pga->m; ++alpha) { 
      printf ("Processing alpha_%d\n", alpha);

      Copy_Matrix (auts[alpha], inverse[alpha], pcp->lastg, nmr_of_bytes);
      Copy_Matrix (auts[alpha], Power, pcp->lastg, nmr_of_bytes);

      while (!is_identity (Power, pcp->lastg, 1)) {

         Copy_Matrix (Power, inverse[alpha], pcp->lastg, nmr_of_bytes);

         for (i = 1; i <= pcp->lastg; ++i) {
            image_to_word (string, Power[i], pcp);
            for (j = 1; j <= pcp->lastg; ++j)
               y[cp + j] = 0;
            /* collect_image_of_string (string, cp, auts[alpha], pcp); */
            for (j = 1; j <= pcp->lastg; ++j)
               Power[i][j] = y[cp + j];
         }
      }
   }

   return inverse;
}

/* convert image of generator to word with base address string */

void image_to_word (string, image, pcp)
int string;
int *image;
struct pcp_vars *pcp;
{
#include "define_y.h"

   register int i; 
   register int length = 0;

   for (i = 1; i <= pcp->lastg; ++i)
      if (image[i] != 0) {
         ++length;
         y[string + length + 1] = PACK2 (image[i], i);
      }
   y[string + 1] = length + 1;
}

void Copy_Matrix (A, B, nmr_of_rows, nmr_of_bytes)
int **A;
int **B;
int nmr_of_rows;
int nmr_of_bytes;
{
   register int i, j;
   for (i = 1; i <= nmr_of_rows; ++i)
      for (j = 1; j <= nmr_of_bytes; ++j)
         B[i][j] = A[i][j];

   /* memcpy (B[i], A[i], nmr_of_bytes); */
}
