Beispiel #1
0
/* Logarithm.  Computes log(x) in double-double precision.
   This is a natural logarithm (i.e., base e).            */
double2
dd_log(const double2 a)
{
    /* Strategy.  The Taylor series for log converges much more
       slowly than that of exp, due to the lack of the factorial
       term in the denominator.  Hence this routine instead tries
       to determine the root of the function

           f(x) = exp(x) - a

       using Newton iteration.  The iteration is given by

           x' = x - f(x)/f'(x)
              = x - (1 - a * exp(-x))
              = x + a * exp(-x) - 1.

       Only one iteration is needed, since Newton's iteration
       approximately doubles the number of digits per iteration. */
    double2 x;

    if (dd_is_one(a)) {
        return DD_C_ZERO;
    }

    if (a.x[0] <= 0.0) {
        dd_error("(dd_log): Non-positive argument.");
        return DD_C_NAN;
    }

    x = dd_create_d(log(a.x[0])); /* Initial approximation */

    /* x = x + a * exp(-x) - 1.0; */
    x = dd_add(x, dd_sub(dd_mul(a, dd_exp(dd_neg(x))), DD_C_ONE));
    return x;
}
Beispiel #2
0
double2
dd_nroot(const double2 a, int n)
{
    /* Strategy:  Use Newton iteration for the function

            f(x) = x^(-n) - a

       to find its root a^{-1/n}.  The iteration is thus

            x' = x + x * (1 - a * x^n) / n

       which converges quadratically.  We can then find
      a^{1/n} by taking the reciprocal.
    */
    double2 r, x;

    if (n <= 0) {
        dd_error("(dd_nroot): N must be positive.");
        return DD_C_NAN;
    }

    if (n % 2 == 0 && dd_is_negative(a)) {
        dd_error("(dd_nroot): Negative argument.");
        return DD_C_NAN;
    }

    if (n == 1) {
        return a;
    }
    if (n == 2) {
        return dd_sqrt(a);
    }

    if (dd_is_zero(a))
        return DD_C_ZERO;

    /* Note  a^{-1/n} = exp(-log(a)/n) */
    r = dd_abs(a);
    x = dd_create_d(exp(-log(r.x[0]) / n));

    /* Perform Newton's iteration. */
    x = dd_add(
        x, dd_mul(x, dd_sub_d_dd(1.0, dd_div_dd_d(dd_mul(r, dd_npwr(x, n)),
                                                  DD_STATIC_CAST(double, n)))));
    if (a.x[0] < 0.0) {
        x = dd_neg(x);
    }
    return dd_inv(x);
}
Beispiel #3
0
void dd_set_global_constants()
{
    dd_init(dd_zero);
    dd_init(dd_minuszero);
    dd_init(dd_one);
    dd_init(dd_minusone);
    dd_init(dd_purezero);

    time(&dd_statStartTime); /* cddlib starting time */
    dd_statBApivots=0;  /* basis finding pivots */
    dd_statCCpivots=0;  /* criss-cross pivots */
    dd_statDS1pivots=0; /* phase 1 pivots */
    dd_statDS2pivots=0; /* phase 2 pivots */
    dd_statACpivots=0;  /* anticycling (cc) pivots */

    dd_choiceLPSolverDefault=dd_DualSimplex;  /* Default LP solver Algorithm */
    dd_choiceRedcheckAlgorithm=dd_DualSimplex;  /* Redundancy Checking Algorithm */
    dd_choiceLexicoPivotQ=dd_TRUE;    /* whether to use the lexicographic pivot */

#if defined GMPRATIONAL
    dd_statBSpivots=0;  /* basis status checking pivots */
    mpq_set_ui(dd_zero,0U,1U);
    mpq_set_ui(dd_purezero,0U,1U);
    mpq_set_ui(dd_one,1U,1U);
    mpq_set_si(dd_minusone,-1L,1U);
    ddf_set_global_constants();
#elif defined GMPFLOAT
    mpf_set_d(dd_zero,dd_almostzero);
    mpf_set_ui(dd_purezero,0U);
    mpf_set_ui(dd_one,1U);
    mpf_set_si(dd_minusone,-1L,1U);
#else
    dd_zero[0]= dd_almostzero;  /*real zero */
    dd_purezero[0]= 0.0;
    dd_one[0]= 1L;
    dd_minusone[0]= -1L;
#endif
    dd_neg(dd_minuszero,dd_zero);
}
Beispiel #4
0
dd_MatrixPtr dd_FourierElimination(dd_MatrixPtr M,dd_ErrorType *error)
/* Eliminate the last variable (column) from the given H-matrix using 
   the standard Fourier Elimination.
 */
{
  dd_MatrixPtr Mnew=NULL;
  dd_rowrange i,inew,ip,in,iz,m,mpos=0,mneg=0,mzero=0,mnew;
  dd_colrange j,d,dnew;
  dd_rowindex posrowindex, negrowindex,zerorowindex;
  mytype temp1,temp2;
  dd_boolean localdebug=dd_FALSE;

  *error=dd_NoError;
  m= M->rowsize;
  d= M->colsize;
  if (d<=1){
    *error=dd_ColIndexOutOfRange;
    if (localdebug) {
      printf("The number of column is too small: %ld for Fourier's Elimination.\n",d);
    }
    goto _L99;
  }

  if (M->representation==dd_Generator){
    *error=dd_NotAvailForV;
    if (localdebug) {
      printf("Fourier's Elimination cannot be applied to a V-polyhedron.\n");
    }
    goto _L99;
  }

  if (set_card(M->linset)>0){
    *error=dd_CannotHandleLinearity;
    if (localdebug) {
      printf("The Fourier Elimination function does not handle equality in this version.\n");
    }
    goto _L99;
  }

  /* Create temporary spaces to be removed at the end of this function */
  posrowindex=(long*)calloc(m+1,sizeof(long));
  negrowindex=(long*)calloc(m+1,sizeof(long));
  zerorowindex=(long*)calloc(m+1,sizeof(long));
  dd_init(temp1);
  dd_init(temp2);

  for (i = 1; i <= m; i++) {
    if (dd_Positive(M->matrix[i-1][d-1])){
      mpos++;
      posrowindex[mpos]=i;
    } else if (dd_Negative(M->matrix[i-1][d-1])) {
      mneg++;
      negrowindex[mneg]=i;
    } else {
      mzero++;
      zerorowindex[mzero]=i;
    }
  }  /*of i*/

  if (localdebug) {
    dd_WriteMatrix(stdout, M);
    printf("No of  (+  -  0) rows = (%ld, %ld, %ld)\n", mpos,mneg, mzero);
  }

  /* The present code generates so many redundant inequalities and thus
     is quite useless, except for very small examples
  */
  mnew=mzero+mpos*mneg;  /* the total number of rows after elimination */
  dnew=d-1;

  Mnew=dd_CreateMatrix(mnew, dnew);
  dd_CopyArow(Mnew->rowvec, M->rowvec, dnew);
/*  set_copy(Mnew->linset,M->linset);  */
  Mnew->numbtype=M->numbtype;
  Mnew->representation=M->representation;
  Mnew->objective=M->objective;


  /* Copy the inequalities independent of x_d to the top of the new matrix. */
  for (iz = 1; iz <= mzero; iz++){
    for (j = 1; j <= dnew; j++) {
      dd_set(Mnew->matrix[iz-1][j-1], M->matrix[zerorowindex[iz]-1][j-1]);
    }
  } 

  /* Create the new inequalities by combining x_d positive and negative ones. */
  inew=mzero;  /* the index of the last x_d zero inequality */
  for (ip = 1; ip <= mpos; ip++){
    for (in = 1; in <= mneg; in++){
      inew++;
      dd_neg(temp1, M->matrix[negrowindex[in]-1][d-1]);
      for (j = 1; j <= dnew; j++) {
        dd_LinearComb(temp2,M->matrix[posrowindex[ip]-1][j-1],temp1,\
          M->matrix[negrowindex[in]-1][j-1],\
          M->matrix[posrowindex[ip]-1][d-1]);
        dd_set(Mnew->matrix[inew-1][j-1],temp2);
      }
      dd_Normalize(dnew,Mnew->matrix[inew-1]);
    }
  } 


  free(posrowindex);
  free(negrowindex);
  free(zerorowindex);
  dd_clear(temp1);
  dd_clear(temp2);

 _L99:
  return Mnew;
}