Beispiel #1
0
void
reducearray ( lrs_mp_vector p, long n )
/* find largest gcd of p[0]..p[n-1] and divide through */
{
  lrs_mp divisor;
  lrs_mp Temp;
  long i = 0L;

  while ( ( i < n ) && zero ( p[i] ) )
    i++;

  if ( i == n )
    return;

  copy ( divisor, p[i] );
  storesign ( divisor, POS );
  i++;

  while ( i < n ) {
    if ( !zero ( p[i] ) ) {
      copy ( Temp, p[i] );
      storesign ( Temp, POS );
      gcd ( divisor, Temp );
    }

    i++;
  }

  /* reduce by divisor */
  for ( i = 0; i < n; i++ )
    if ( !zero ( p[i] ) )
      reduceint ( p[i], divisor );
}       /* end of reducearray */
Beispiel #2
0
void
reduce ( lrs_mp Na, lrs_mp Da ) { /* reduces Na Da by gcd(Na,Da) */
  lrs_mp Nb, Db, Nc, Dc;
  copy ( Nb, Na );
  copy ( Db, Da );
  storesign ( Nb, POS );
  storesign ( Db, POS );
  copy ( Nc, Na );
  copy ( Dc, Da );
  gcd ( Nb, Db );   /* Nb is the gcd(Na,Da) */
  exactdivint ( Nc, Nb, Na );
  exactdivint ( Dc, Nb, Da );
}
Beispiel #3
0
void
atomp ( char s[], lrs_mp a ) { /*convert string to lrs_mp integer */
  lrs_mp mpone;
  long diff, ten, i, sig;
  itomp ( 1L, mpone );
  ten = 10L;

  for ( i = 0; s[i] == ' ' || s[i] == '\n' || s[i] == '\t'; i++ );

  /*skip white space */
  sig = POS;

  if ( s[i] == '+' || s[i] == '-' ) /* sign */
    sig = ( s[i++] == '+' ) ? POS : NEG;

  itomp ( 0L, a );

  while ( s[i] >= '0' && s[i] <= '9' ) {
    diff = s[i] - '0';
    linint ( a, ten, mpone, diff );
    i++;
  }

  storesign ( a, sig );

  if ( s[i] ) {
    fprintf ( stderr, "\nIllegal character in number: '%s'\n", s + i );
    exit ( 1 );
  }

}       /* end of atomp */
Beispiel #4
0
void
mulint ( lrs_mp a, lrs_mp b, lrs_mp c ) /* multiply two integers a*b --> c */

/***Handbook of Algorithms and Data Structures, p239  ***/
{
  long nlength, i, j, la, lb;
  /*** b and c may coincide ***/
  la = length ( a );
  lb = length ( b );
  nlength = la + lb - 2;

  if ( nlength > lrs_digits )
    digits_overflow();

  for ( i = 0; i < la - 2; i++ )
    c[lb + i] = 0;

  for ( i = lb - 1; i > 0; i-- ) {
    for ( j = 2; j < la; j++ )
      if ( ( c[i + j - 1] += b[i] * a[j] ) >
           MAXD - ( BASE - 1 ) * ( BASE - 1 ) - MAXD / BASE ) {
        c[i + j - 1] -= ( MAXD / BASE ) * BASE;
        c[i + j] += MAXD / BASE;
      }

    c[i] = b[i] * a[1];
  }

  storelength ( c, nlength );
  storesign ( c, sign ( a ) == sign ( b ) ? POS : NEG );
  normalize ( c );
}
Beispiel #5
0
void
normalize ( lrs_mp a ) {
  long cy, i, la;
  la = length ( a );
start:
  cy = 0;

  for ( i = 1; i < la; i++ ) {
    cy = ( a[i] += cy ) / BASE;
    a[i] -= cy * BASE;

    if ( a[i] < 0 ) {
      a[i] += BASE;
      cy--;
    }
  }

  while ( cy > 0 ) {
    a[i++] = cy % BASE;
    cy /= BASE;
  }

  if ( cy < 0 ) {
    a[la - 1] += cy * BASE;

    for ( i = 1; i < la; i++ )
      a[i] = ( -a[i] );

    storesign ( a, sign ( a ) == POS ? NEG : POS );
    goto start;
  }

  while ( a[i - 1] == 0 && i > 2 )
    i--;

  if ( i > lrs_record_digits ) {
    if ( ( lrs_record_digits = i ) > lrs_digits )
      digits_overflow();
  };

  storelength ( a, i );

  if ( i == 2 && a[1] == 0 )
    storesign ( a, POS );
}       /* end of normalize */
Beispiel #6
0
void 
itomp (long in, lrs_mp a)
    /* convert integer i to multiple precision with base BASE */
{
  long i;
  a[0] = 2;			/* initialize to zero */
  for (i = 1; i < lrs_digits; i++)
    a[i] = 0;
  if (in < 0)
    {
      storesign (a, NEG);
      in = in * (-1);
    }
  i = 0;
  while (in != 0)
    {
      i++;
      a[i] = in - BASE * (in / BASE);
      in = in / BASE;
      storelength (a, i + 1);
    }
}				/* end of itomp */
Beispiel #7
0
void
divint ( lrs_mp a, lrs_mp b, lrs_mp c ) { /* c=a/b, a contains remainder on return */
  long cy, la, lb, lc, d1, s, t, sig;
  long i, j, qh;

  /*  figure out and save sign, do everything with positive numbers */
  sig = sign ( a ) * sign ( b );

  la = length ( a );
  lb = length ( b );
  lc = la - lb + 2;

  if ( la < lb ) {
    storelength ( c, TWO );
    storesign ( c, POS );
    c[1] = 0;
    normalize ( c );
    return;
  }

  for ( i = 1; i < lc; i++ )
    c[i] = 0;

  storelength ( c, lc );
  storesign ( c, ( sign ( a ) == sign ( b ) ) ? POS : NEG );

  /******************************/
  /* division by a single word: */
  /*  do it directly            */
  /******************************/

  if ( lb == 2 ) {
    cy = 0;
    t = b[1];

    for ( i = la - 1; i > 0; i-- ) {
      cy = cy * BASE + a[i];
      a[i] = 0;
      cy -= ( c[i] = cy / t ) * t;
    }

    a[1] = cy;
    storesign ( a, ( cy == 0 ) ? POS : sign ( a ) );
    storelength ( a, TWO );
    /*      set sign of c to sig  (**mod**)            */
    storesign ( c, sig );
    normalize ( c );
    return;
  } else {
    /* mp's are actually DIGITS+1 in length, so if length of a or b = */
    /* DIGITS, there will still be room after normalization. */
    /****************************************************/
    /* Step D1 - normalize numbers so b > floor(BASE/2) */
    d1 = BASE / ( b[lb - 1] + 1 );

    if ( d1 > 1 ) {
      cy = 0;

      for ( i = 1; i < la; i++ ) {
        cy = ( a[i] = a[i] * d1 + cy ) / BASE;
        a[i] %= BASE;
      }

      a[i] = cy;
      cy = 0;

      for ( i = 1; i < lb; i++ ) {
        cy = ( b[i] = b[i] * d1 + cy ) / BASE;
        b[i] %= BASE;
      }

      b[i] = cy;
    } else {
      a[la] = 0;    /* if la or lb = DIGITS this won't work */
      b[lb] = 0;
    }

    /*********************************************/
    /* Steps D2 & D7 - start and end of the loop */
    for ( j = 0; j <= la - lb; j++ ) {
      /*************************************/
      /* Step D3 - determine trial divisor */
      if ( a[la - j] == b[lb - 1] )
        qh = BASE - 1;
      else {
        s = ( a[la - j] * BASE + a[la - j - 1] );
        qh = s / b[lb - 1];

        while ( qh * b[lb - 2] > ( s - qh * b[lb - 1] ) * BASE + a[la - j - 2] )
          qh--;
      }

      /*******************************************************/
      /* Step D4 - divide through using qh as quotient digit */
      cy = 0;

      for ( i = 1; i <= lb; i++ ) {
        s = qh * b[i] + cy;
        a[la - j - lb + i] -= s % BASE;
        cy = s / BASE;

        if ( a[la - j - lb + i] < 0 ) {
          a[la - j - lb + i] += BASE;
          cy++;
        }
      }

      /*****************************************************/
      /* Step D6 - adjust previous step if qh is 1 too big */
      if ( cy ) {
        qh--;
        cy = 0;

        for ( i = 1; i <= lb; i++ ) { /* add a back in */
          a[la - j - lb + i] += b[i] + cy;
          cy = a[la - j - lb + i] / BASE;
          a[la - j - lb + i] %= BASE;
        }
      }

      /***********************************************************************/
      /* Step D5 - write final value of qh.  Saves calculating array indices */
      /* to do it here instead of before D6 */

      c[la - lb - j + 1] = qh;

    }

    /**********************************************************************/
    /* Step D8 - unnormalize a and b to get correct remainder and divisor */

    for ( i = lc; c[i - 1] == 0 && i > 2; i-- ); /* strip excess 0's from quotient */

    storelength ( c, i );

    if ( i == 2 && c[1] == 0 )
      storesign ( c, POS );

    cy = 0;

    for ( i = lb - 1; i >= 1; i-- ) {
      cy = ( a[i] += cy * BASE ) % d1;
      a[i] /= d1;
    }

    for ( i = la; a[i - 1] == 0 && i > 2; i-- ); /* strip excess 0's from quotient */

    storelength ( a, i );

    if ( i == 2 && a[1] == 0 )
      storesign ( a, POS );

    if ( cy )
      fprintf ( lrs_ofp, "divide error" );

    for ( i = lb - 1; i >= 1; i-- ) {
      cy = ( b[i] += cy * BASE ) % d1;
      b[i] /= d1;
    }
  }
}
Beispiel #8
0
long 
lrs_getfirstbasis2 (lrs_dic ** D_p, lrs_dat * Q, lrs_dic * P2orig, lrs_mp_matrix * Lin, long no_output)
/* gets first basis, FALSE if none              */
/* P may get changed if lin. space Lin found    */
/* no_output is TRUE supresses output headers   */
{
  long i, j, k;

/* assign local variables to structures */

  lrs_mp_matrix A;
  long *B, *C, *Row, *Col;
  long *inequality;
  long *linearity;
  long hull = Q->hull;
  long m, d, lastdv, nlinearity, nredundcol;

  static long ocount=0;


  m = D->m;
  d = D->d;
  lastdv = Q->lastdv;

  nredundcol = 0L;		/* will be set after getabasis        */
  nlinearity = Q->nlinearity;	/* may be reset if new linearity read */
  linearity = Q->linearity;

  A = D->A;
  B = D->B;
  C = D->C;
  Row = D->Row;
  Col = D->Col;
  inequality = Q->inequality;

/* default is to look for starting cobasis using linearies first, then     */
/* filling in from last rows of input as necessary                         */
/* linearity array is assumed sorted here                                  */
/* note if restart/given start inequality indices already in place         */
/* from nlinearity..d-1                                                    */

  for (i = 0; i < nlinearity; i++)      /* put linearities first in the order */
    inequality[i] = linearity[i];


  k = 0;			/* index for linearity array   */

  if (Q->givenstart)
    k = d;
  else
    k = nlinearity;
  for (i = m; i >= 1; i--)
    {
      j = 0;
      while (j < k && inequality[j] != i)
	j++;			/* see if i is in inequality  */
      if (j == k)
	inequality[k++] = i;
    }
  if (Q->debug)
    {
      fprintf (lrs_ofp, "\n*Starting cobasis uses input row order");
      for (i = 0; i < m; i++)
	fprintf (lrs_ofp, " %ld", inequality[i]);
    }

  if (!Q->maximize && !Q->minimize)
    for (j = 0; j <= d; j++)
      itomp (ZERO, A[0][j]);

/* Now we pivot to standard form, and then find a primal feasible basis       */
/* Note these steps MUST be done, even if restarting, in order to get         */
/* the same index/inequality correspondance we had for the original prob.     */
/* The inequality array is used to give the insertion order                   */
/* and is defaulted to the last d rows when givenstart=FALSE                  */

  if (!getabasis2 (D, Q,P2orig, inequality))
          return FALSE;

  if(Q->debug)
  {
    fprintf(lrs_ofp,"\nafter getabasis2");
    printA(D, Q);
  }
  nredundcol = Q->nredundcol;
  lastdv = Q->lastdv;
  d = D->d;

/********************************************************************/
/* now we start printing the output file  unless no output requested */
/********************************************************************/
  if (!no_output || Q->debug)
    {
      fprintf (lrs_ofp, "\nV-representation");

/* Print linearity space                 */
/* Don't print linearity if first column zero in hull computation */

      k = 0;

     if (nredundcol > k)
	{
	  fprintf (lrs_ofp, "\nlinearity %ld ", nredundcol - k);	/*adjust nredundcol for homog. */
	  for (i = 1; i <= nredundcol - k; i++)
	    fprintf (lrs_ofp, " %ld", i);
	}			/* end print of linearity space */

      fprintf (lrs_ofp, "\nbegin");
      fprintf (lrs_ofp, "\n***** %ld rational", Q->n);

    }				/* end of if !no_output .......   */

/* Reset up the inequality array to remember which index is which input inequality */
/* inequality[B[i]-lastdv] is row number of the inequality with index B[i]              */
/* inequality[C[i]-lastdv] is row number of the inequality with index C[i]              */

  for (i = 1; i <= m; i++)
    inequality[i] = i;
  if (nlinearity > 0)		/* some cobasic indices will be removed */
    {
      for (i = 0; i < nlinearity; i++)	/* remove input linearity indices */
	inequality[linearity[i]] = 0;
      k = 1;			/* counter for linearities         */
      for (i = 1; i <= m - nlinearity; i++)
	{
	  while (k <= m && inequality[k] == 0)
	    k++;		/* skip zeroes in corr. to linearity */
	  inequality[i] = inequality[k++];
	}
    }				/* end if linearity */
  if (Q->debug)
    {
      fprintf (lrs_ofp, "\ninequality array initialization:");
      for (i = 1; i <= m - nlinearity; i++)
	fprintf (lrs_ofp, " %ld", inequality[i]);
    }
  if (nredundcol > 0)
    {
      *Lin = lrs_alloc_mp_matrix (nredundcol, Q->n);

      for (i = 0; i < nredundcol; i++)
	{
	  if (!(Q->homogeneous && Q->hull && i == 0))	/* skip redund col 1 for homog. hull */
	    {
	      lrs_getray (D, Q, Col[0], D->C[0] + i - hull, (*Lin)[i]);		/* adjust index for deletions */
	    }

	  if (!removecobasicindex (D, Q, 0L))
	    return FALSE;
	}
    }				/* end if nredundcol > 0 */

      if (Q->verbose)
      {
      fprintf (lrs_ofp, "\nNumber of pivots for starting dictionary: %ld",Q->count[3]);
      ocount=Q->count[3];
      }

/* Do dual pivots to get primal feasibility */
  if (!primalfeasible (D, Q))
    {
     if ( Q->verbose )
      {
          fprintf (lrs_ofp, "\nNumber of pivots for feasible solution: %ld",Q->count[3]);
          fprintf (lrs_ofp, " - No feasible solution");
          ocount=Q->count[3];
      }
      return FALSE;
    }

    if (Q->verbose)
     {
      fprintf (lrs_ofp, "\nNumber of pivots for feasible solution: %ld",Q->count[3]);
      ocount=Q->count[3];
     }


/* Now solve LP if objective function was given */
  if (Q->maximize || Q->minimize)
    {
      Q->unbounded = !lrs_solvelp (D, Q, Q->maximize);

      /* check to see if objective is dual degenerate */
      j = 1;
      while (j <= d && !zero (A[0][j]))
      j++;
      if (j <= d)
	    Q->dualdeg = TRUE;
    }
  else
/* re-initialize cost row to -det */
    {
      for (j = 1; j <= d; j++)
	{
	  copy (A[0][j], D->det);
	  storesign (A[0][j], NEG);
	}

      itomp (ZERO, A[0][0]);	/* zero optimum objective value */
    }


/* reindex basis to 0..m if necessary */
/* we use the fact that cobases are sorted by index value */
  if (Q->debug)
    printA (D, Q);
  while (C[0] <= m)
    {
      i = C[0];
      j = inequality[B[i] - lastdv];
      inequality[B[i] - lastdv] = inequality[C[0] - lastdv];
      inequality[C[0] - lastdv] = j;
      C[0] = B[i];
      B[i] = i;
      reorder1 (C, Col, ZERO, d);
    }

  if (Q->debug)
    {
      fprintf (lrs_ofp, "\n*Inequality numbers for indices %ld .. %ld : ", lastdv + 1, m + d);
      for (i = 1; i <= m - nlinearity; i++)
	fprintf (lrs_ofp, " %ld ", inequality[i]);
      printA (D, Q);
    }



  if (Q->restart)
    {
      if (Q->debug)
	fprintf (lrs_ofp, "\nPivoting to restart co-basis");
      if (!restartpivots (D, Q))
	return FALSE;
      D->lexflag = lexmin (D, Q, ZERO);		/* see if lexmin basis */
      if (Q->debug)
	printA (D, Q);
    }
/* Check to see if necessary to resize */
  if (Q->inputd > D->d)
    *D_p = resize (D, Q);

  return TRUE;
}