예제 #1
0
파일: alkvalue.cpp 프로젝트: KDE/alkimia
AlkValue AlkValue::abs() const
{
  AlkValue result;
  mpq_abs(result.d->m_val.get_mpq_t(), d->m_val.get_mpq_t());
  result.d->m_val.canonicalize();
  return result;
}
예제 #2
0
void lps_scale(const Lps* lp)
{
   Con*   con;
   Nzo*   nzo;
   mpq_t  maxi;
   mpq_t  v;

   assert(lps_valid(lp));
      
   mpq_init(maxi);
   mpq_init(v);
   
   for(con = lp->con_root; con != NULL; con = con->next)
   {
      if ((con->flags & LP_FLAG_CON_SCALE) > 0)
      {
         mpq_set_ui(maxi, 0, 1);  /* = 0 */

         for(nzo = con->first; nzo != NULL; nzo = nzo->con_next)
         {
            mpq_abs(v, nzo->value);
            
            if (mpq_cmp(v, maxi) > 0)
               mpq_set(maxi, v);
         }
         mpq_inv(con->scale, maxi); /* scale = 1 / maxi */

         if (HAS_RHS(con))
            mpq_mul(con->rhs, con->rhs, con->scale);

         if (HAS_LHS(con))
            mpq_mul(con->lhs, con->lhs, con->scale);
            
         for(nzo = con->first; nzo != NULL; nzo = nzo->con_next)
            mpq_mul(nzo->value, nzo->value, con->scale);
      }
   }
   mpq_clear(v);
   mpq_clear(maxi);
}
예제 #3
0
APLRAT PrimFnMonDownStileRisR
    (APLRAT     aplRatRht,
     LPPRIMSPEC lpPrimSpec)

{
    APLRAT mpqRes   = {0},
           mpqFloor = {0},
           mpqCeil  = {0},
           mpqTmp1  = {0},
           mpqTmp2  = {0},
           mpqNear  = {0};

    // Check for PoM infinity
    if (IsMpqInfinity (&aplRatRht))
        // Copy to the result
        mpq_init_set  (&mpqRes, &aplRatRht);
    else
    {
        // Initialize the temps
        mpq_init (&mpqRes);
        mpq_init (&mpqFloor);
        mpq_init (&mpqCeil );
        mpq_init (&mpqTmp1);
        mpq_init (&mpqTmp2);
        mpq_init (&mpqNear);

        // Get the exact floor and ceiling
        mpq_floor (&mpqFloor, &aplRatRht);
        mpq_ceil  (&mpqCeil , &aplRatRht);

        // Calculate the integer nearest the right arg

        mpq_sub (&mpqTmp1, &aplRatRht, &mpqFloor);
        mpq_sub (&mpqTmp2, &mpqCeil  , &aplRatRht);

        // Split cases based upon the signum of the difference between
        //   (the number and its floor) and (the ceiling and the number)
        switch (signumint (mpq_cmp (&mpqTmp1, &mpqTmp2)))
        {
            case  1:
                mpq_set (&mpqNear, &mpqCeil);

                break;

            case  0:
                mpq_abs (&mpqTmp1, &mpqFloor);
                mpq_abs (&mpqTmp2, &mpqFloor);

                // They are equal, so use the one with the larger absolute value
                mpq_set (&mpqNear, ((mpq_cmp (&mpqTmp1, &mpqTmp2) > 0) ? &mpqFloor
                                                                       : &mpqCeil));
                break;

            case -1:
                mpq_set (&mpqNear, &mpqFloor);

                break;

            defstop
                break;
        } // End SWITCH

        // If Near is < Rht, return Near
        if (mpq_cmp (&mpqNear, &aplRatRht) < 0)
            mpq_set (&mpqRes, &mpqNear);
        else
        {
            // If Near is non-zero, and
            //   Rht is tolerantly-equal to Near,
            //   return Near; otherwise, return Near - 1
            if (mpq_sgn (&mpqNear) NE 0)
            {
                mpq_set (&mpqRes, &mpqNear);

                if (!PrimFnDydEqualBisRvR (aplRatRht,
                                           mpqNear,
                                           NULL))
                    mpq_sub_ui (&mpqRes, &mpqRes, 1, 1);
            } else
            {
                // mpfNear is zero

                // Get -[]CT as a VFP
                mpq_set_d (&mpqTmp1, -GetQuadCT ());

                // If Rht is between (-[]CT) and 0 (inclusive),
                //   return 0; otherwise, return -1
                if (mpq_cmp (&mpqTmp1, &aplRatRht) <= 0
                 && mpq_sgn (&aplRatRht)           <= 0)
                    mpq_set_si (&mpqRes,  0, 1);
                else
                    mpq_set_si (&mpqRes, -1, 1);
            } // End IF/ELSE
        } // End IF/ELSE

        // We no longer need this storage
        Myq_clear (&mpqNear);
        Myq_clear (&mpqTmp2);
        Myq_clear (&mpqTmp1);
        Myq_clear (&mpqCeil);
        Myq_clear (&mpqFloor);
    } // End IF/ELSE

    return mpqRes;
} // End PrimFnMonDownStileRisR
예제 #4
0
void ssx_chuzr(SSX *ssx)
{     int m = ssx->m;
      int n = ssx->n;
      int *type = ssx->type;
      mpq_t *lb = ssx->lb;
      mpq_t *ub = ssx->ub;
      int *Q_col = ssx->Q_col;
      mpq_t *bbar = ssx->bbar;
      int q = ssx->q;
      mpq_t *aq = ssx->aq;
      int q_dir = ssx->q_dir;
      int i, k, s, t, p, p_stat;
      mpq_t teta, temp;
      mpq_init(teta);
      mpq_init(temp);
      xassert(1 <= q && q <= n);
      xassert(q_dir == +1 || q_dir == -1);
      /* nothing is chosen so far */
      p = 0, p_stat = 0;
      /* look through the list of basic variables */
      for (i = 1; i <= m; i++)
      {  s = q_dir * mpq_sgn(aq[i]);
         if (s < 0)
         {  /* xB[i] decreases */
            k = Q_col[i]; /* x[k] = xB[i] */
            t = type[k];
            if (t == SSX_LO || t == SSX_DB || t == SSX_FX)
            {  /* xB[i] has finite lower bound */
               mpq_sub(temp, bbar[i], lb[k]);
               mpq_div(temp, temp, aq[i]);
               mpq_abs(temp, temp);
               if (p == 0 || mpq_cmp(teta, temp) > 0)
               {  p = i;
                  p_stat = (t == SSX_FX ? SSX_NS : SSX_NL);
                  mpq_set(teta, temp);
               }
            }
         }
         else if (s > 0)
         {  /* xB[i] increases */
            k = Q_col[i]; /* x[k] = xB[i] */
            t = type[k];
            if (t == SSX_UP || t == SSX_DB || t == SSX_FX)
            {  /* xB[i] has finite upper bound */
               mpq_sub(temp, bbar[i], ub[k]);
               mpq_div(temp, temp, aq[i]);
               mpq_abs(temp, temp);
               if (p == 0 || mpq_cmp(teta, temp) > 0)
               {  p = i;
                  p_stat = (t == SSX_FX ? SSX_NS : SSX_NU);
                  mpq_set(teta, temp);
               }
            }
         }
         /* if something has been chosen and the ratio test indicates
            exact degeneracy, the search can be finished */
         if (p != 0 && mpq_sgn(teta) == 0) break;
      }
      /* if xN[q] is double-bounded, check if it can reach its opposite
         bound before any basic variable */
      k = Q_col[m+q]; /* x[k] = xN[q] */
      if (type[k] == SSX_DB)
      {  mpq_sub(temp, ub[k], lb[k]);
         if (p == 0 || mpq_cmp(teta, temp) > 0)
         {  p = -1;
            p_stat = -1;
            mpq_set(teta, temp);
         }
      }
      ssx->p = p;
      ssx->p_stat = p_stat;
      /* if xB[p] has been chosen, determine its actual change in the
         adjacent basis (it has the same sign as q_dir) */
      if (p != 0)
      {  xassert(mpq_sgn(teta) >= 0);
         if (q_dir > 0)
            mpq_set(ssx->delta, teta);
         else
            mpq_neg(ssx->delta, teta);
      }
      mpq_clear(teta);
      mpq_clear(temp);
      return;
}
예제 #5
0
void Rational::abs()
{
   mpq_abs(number, number);
}