示例#1
0
void evaluate_formula (int *queue, int *queue_length, struct pcp_vars *pcp)
{
   register int *y = y_address;

   register int lastg = pcp->lastg;
   register int i;
   int nmr_entries;
   int *weight;
   int total;
   int nmr;

   total = 6 * lastg + 6;
   if (is_space_exhausted (total, pcp))
      return;

   /* fudge the value of submlg because of possible call to power */
   pcp->submlg -= total;

   read_value (TRUE, "Input number of components of formula: ",
	       &nmr_entries, 1);

   weight = allocate_vector (nmr_entries, 1, FALSE);
   first = allocate_vector (nmr_entries + 1, 0, FALSE);
   last = allocate_vector (nmr_entries + 1, 0, FALSE);
   list = allocate_vector (nmr_entries + 1, 0, FALSE);

   printf ("Input weight of each component of formula: ");
   for (i = 1; i < nmr_entries; ++i) {
      read_value (FALSE, "", &weight[i], 1);
   }
   read_value (TRUE, "", &weight[i], 1);

   read_value (TRUE, "Input power of individual component: ",
	       &power_of_entry, 1);
   
   read_value (TRUE, "Input power of word: ", &exponent, 1);
   
   for (i = 1; i <= nmr_entries; ++i) {
      first[i] = y[pcp->clend + weight[i] - 1] + 1;
      last[i] = y[pcp->clend + weight[i]];
   }
      
   /* generate the list of words; evaluate each, echelonise it 
      and build up the queue of redundant generators */
   nmr = 0;
   loop (queue, queue_length, nmr_entries, list, &nmr, 
	 first[nmr_entries], last[nmr_entries], pcp);

   /* reset value of submlg */
   pcp->submlg += total;
 
   free_vector (weight, 1);
   free_vector (first, 0);
   free_vector (last, 0);
   free_vector (list, 0);
}
示例#2
0
void jacobi(int c, int b, int a, int ptr, struct pcp_vars *pcp)
{
   register int *y = y_address;

   register int i;
   register int k;
   register int p1;
   register int cp1;
   register int cp2;
   register int unc;
   register int address;
   register int ycol;
   register int commba;
   register int count;
   register int count2;
   register int offset;

   register int lastg = pcp->lastg;
   register int prime = pcp->p;
   register int pm1 = pcp->pm1;
   register int p_power = pcp->ppower;
   register int p_pcomm = pcp->ppcomm;

#include "access.h"

#if defined(GROUP)
   if (is_space_exhausted(2 * lastg + 3, pcp))
      return;
#endif

   /* cp1 and cp2 are the base addresses for the collected
      part of the lhs and of the rhs, respectively */
   cp1 = pcp->lused;
   cp2 = cp1 + lastg;
   unc = cp2 + lastg + 1;

   for (i = 1; i <= lastg; i++)
      y[cp1 + i] = y[cp2 + i] = 0;

   /* calculate the class pcp->cc part of the jacobi relation
      (b^p) a = b^(p - 1) (ba) */

   if (c == b) {
      ycol = y[p_power + b];
      collect(ycol, cp1, pcp);
      collect(a, cp1, pcp);

      if (b != a) {
         y[cp2 + b] = pm1;
         p1 = y[p_pcomm + b];
         commba = y[p1 + a];
         collect(a, cp2, pcp);
         collect(b, cp2, pcp);
         collect(commba, cp2, pcp);
      } else {
         /* we are processing (a^p) a = a (a^p) */
         ycol = y[p_power + a];
         y[cp2 + a] = 1;
         collect(ycol, cp2, pcp);
      }
   } else {
      if (b - a > 0) {
#if defined(GROUP)
         /* calculate the class pcp->cc part of the jacobi relation
            (cb) a = c (ba); set up a as the collected part for lhs */
         y[cp1 + c] = 1;
         collect(b, cp1, pcp);
         collect(a, cp1, pcp);
         y[cp2 + c] = 1;
         collect(a, cp2, pcp);
         collect(b, cp2, pcp);
         p1 = y[p_pcomm + b];
         commba = y[p1 + a];
         collect(commba, cp2, pcp);
#endif
      } else {
         /* calculate the class pcp->cc part of the jacobi relation
            (ca) a^(p - 1) = c (a^p); first collect rhs */
         ycol = y[p_power + a];
         y[cp2 + c] = 1;
         collect(ycol, cp2, pcp);

         /* collect lhs; set up c as collected part */
         y[cp1 + c] = 1;
         collect(a, cp1, pcp);
         y[unc] = 1;
         y[unc + 1] = PACK2(pm1, a);
         collect(-unc + 1, cp1, pcp);
      }
   }

   /* the jacobi collections are completed */

   if ((p1 = ptr) > 0) {
      /* we are filling in the tail on y[p1]; convert the class pcp->cc
         part to string form in y[cp1 + 2 + 1] to y[cp1 + 2 + count]
         where count is the string length */

      count = 0;
      for (i = pcp->ccbeg; i <= lastg; i++) {
         k = y[cp1 + i] - y[cp2 + i];
         if (k != 0) {
            if (k < 0)
               k += prime;
            ++count;
            y[cp1 + 2 + count] = PACK2(k, i);
         }
      }

      if (count > 0) {
         /* y[p1] was trivial to class pcp->cc - 1 so create a new entry */
         if (y[p1] >= 0) {
            y[p1] = -(cp1 + 1);
            y[cp1 + 1] = p1;
            y[cp1 + 2] = count;
            pcp->lused += count + 2;
         } else {
            /* the class pcp->cc part is nontrivial so make room for
               lower class terms */
            address = -y[p1];
            count2 = y[address + 1];

            /* move class pcp->cc part up */
            offset = cp1 + count + 3;
            for (i = 1; i <= count; i++)
               y[offset + count2 - i] = y[offset - i];

            /* copy in lower class terms */
            for (i = 1; i <= count2; i++)
               y[cp1 + 2 + i] = y[address + i + 1];

            /* create new header block */
            y[cp1 + 1] = y[address];
            y[cp1 + 2] = count + count2;

            /* deallocate old entry */
            y[address] = 0;

            /* set up pointer to new entry */
            y[p1] = -(cp1 + 1);
            pcp->lused += count + count2 + 2;
         }
      }
   } else {
      /* we are checking consistency equations */
      echelon(pcp);
      if ((pcp->fullop && pcp->eliminate_flag) || pcp->diagn)
         text(9, c, b, a, 0);
   }
}
void collect_relations (struct pcp_vars *pcp)
{
   register int *y = y_address;

   register int i;
   register int j;
   register int k;
   register int p1;
   register int length;
   register int cp, cp1, cp2;

   register int relp = pcp->relp;
   register int ndrel = pcp->ndrel;
   register int lastg = pcp->lastg;

   for (i = 1; i <= ndrel; ++i) {

      /* space is required for two collected parts set up here 
	 and possibly for 5 * pcp->lastg in collect_def_comm */
      if (is_space_exhausted (7 * lastg + 7, pcp))
	 return;

      cp1 = pcp->lused;
      cp2 = cp1 + lastg;

      /*  original zero out -- bug reported by John Cannon October 1998 */
/* 
      for (j = 1; j <= lastg; ++j)  
	 y[cp1 + j] = y[cp2 + j] = 0;
*/

      for (j = 1; j <= 2; ++j) {
	 p1 = y[++relp];
	 if (p1 != 0) {
	    cp = (j == 1) ? cp1 : cp2;
            /* bug fix */
            for (k = 1; k <= lastg; ++k)  
                y[cp + k] = 0;
	    length = y[p1];
	    /* is the relation a word or a commutator? */
	    if (length > 0)
	       collect_gen_word (p1, length, cp, pcp);
	    else if (length < 0) {
	       /* we may need to update pcp->lused, as space immediately 
		  above it is used in commutator routines */
	       if (j == 2) pcp->lused += lastg;
	       collect_def_comm (p1, cp, pcp);
	       if (j == 2) pcp->lused -= lastg;
	    }
	    if (!pcp->valid)
	       return;
	 }
      }

      echelon (pcp);
      if ((pcp->fullop && pcp->eliminate_flag) || pcp->diagn)
	 text (1, i, 0, 0, 0);
      if (pcp->overflow || pcp->complete != 0)
	 return;
   }
}
示例#4
0
void complete_echelon(Logical trivial, int redgen, struct pcp_vars *pcp)
{
   register int *y = y_address;

   int k;
   int i, j, jj, exp;
   int p1;
   int factor;
   int count, count1, count2;
   int predg;
   int offset;
   int temp;
   int value;
   int bound;
   int l;
   int p = pcp->p;

#include "access.h"

   if (trivial) {
      /* delete all occurrences of redgen from other equations */
      for (k = redgen + 1, bound = pcp->lastg; k <= bound; k++) {
         if (y[pcp->structure + k] >= 0)
            continue;
         p1 = -y[pcp->structure + k];
         count = y[p1 + 1];
         for (j = 1; j <= count; j++)
            if ((temp = FIELD2(y[p1 + j + 1])) >= redgen)
               break;
         if (j > count || temp > redgen)
            continue;

         /* redgen occurs in this relation, so eliminate it;
            is redgen in the last word? */
         count1 = count - 1;

         if (j < count) {
            /* no, so pack up relation */
            for (jj = j; jj <= count1; jj++)
               y[p1 + jj + 1] = y[p1 + jj + 2];
         }

         if (j < count || (j >= count && count1 > 0)) {
            /* deallocate last word and fix count in header block */
            y[p1 + count + 1] = -1;
            y[p1 + 1] = count1;
            continue;
         }

         /* old relation is to be eliminated (it was 1 word long) */
         y[p1] = 0;
         y[pcp->structure + k] = 0;
      }
   } else {
      p1 = -y[pcp->structure + redgen];
      count = y[p1 + 1];

      /* eliminate all occurrences of redgen from the other relations
         by substituting its value */
      for (k = redgen + 1, bound = pcp->lastg; k <= bound; k++) {
         if (y[pcp->structure + k] >= 0)
            continue;
         if (is_space_exhausted(pcp->lastg + 1, pcp))
            return;
         p1 = -y[pcp->structure + k];
         count1 = y[p1 + 1];
         for (j = 1; j <= count1; j++)
            if ((temp = FIELD2(y[p1 + j + 1])) >= redgen)
               break;
         if (j > count1 || temp > redgen)
            continue;

         /* redgen occurs in this relation, so eliminate it */
         factor = FIELD1(y[p1 + j + 1]);
         predg = -y[pcp->structure + redgen];

         /* merge old relation with factor * (new relation), deleting redgen;
            old relation is longer than new relation since it contains redgen */

         /* commence merge */
         count2 = 0;
         offset = pcp->lused + 2;
         for (i = 1, l = 1;;) {
            temp = FIELD2(y[p1 + i + 1]) - FIELD2(y[predg + l + 1]);
            if (temp < 0) {
               count2++;
               y[offset + count2] = y[p1 + i + 1];
               i++;
            } else if (temp > 0) {
               count2++;
               /* integer overflow can occur here; see comments in collect */
               value = y[predg + l + 1];
               y[offset + count2] =
                   PACK2((factor * FIELD1(value)) % p, FIELD2(value));
               if (++l > count)
                  break;
            } else {
               /* integer overflow can occur here; see comments in collect */
               value = y[p1 + i + 1];
               exp = (FIELD1(value) + factor * FIELD1(y[predg + l + 1])) % p;
               if (exp > 0) {
                  count2++;
                  y[offset + count2] = PACK2(exp, FIELD2(value));
               }
               i++;
               if (++l > count)
                  break;
            }
         }

         /* all of the value of redgen has been merged in;
            copy in the remainder of the old relation with redgen deleted */
         offset = pcp->lused + 2;
         for (jj = i; jj <= count1; jj++)
            if (jj != j) {
               count2++;
               y[offset + count2] = y[p1 + jj + 1];
            }

         /* new relation is now in y[lused + 2 + 1] to y[lused + 2 + count2] */

         /* new relation indicates generator k is trivial; deallocate old */
         if (count2 <= 0) {
            y[p1] = 0;
            y[pcp->structure + k] = 0;
            continue;
         }

         /* new relation is nontrivial */

         if (count2 < count1) {
            /* new relation is shorter than old; copy in new relation */
            for (i = 1; i <= count2; i++)
               y[p1 + i + 1] = y[pcp->lused + 2 + i];

            /* reset count field for new relation */
            y[p1 + 1] = count2;

            /* deallocate rest of old relation */
            if (count1 == count2 + 1)
               y[p1 + count2 + 2] = -1;
            else {
               y[p1 + count2 + 2] = 0;
               y[p1 + count2 + 3] = count1 - count2 - 2;
            }
         } else if (count1 == count2) {
            /* new relation has same length as old; overwrite old relation */
            offset = pcp->lused + 2;
            for (i = 1; i <= count2; i++)
               y[p1 + i + 1] = y[offset + i];
         } else {
            /* new relation is longer than old; deallocate old relation */
            y[p1] = 0;

            /* set up pointer to new relation and header block */
            y[pcp->structure + k] = -(pcp->lused + 1);
            y[pcp->lused + 1] = pcp->structure + k;
            y[pcp->lused + 2] = count2;
            pcp->lused += count2 + 2;
         }
      }
   }
}