예제 #1
0
double spy_update_gamma(SPXLP *lp, SPYSE *se, int p, int q,
      const double trow[/*1+n-m*/], const double tcol[/*1+m*/])
{     int m = lp->m;
      int n = lp->n;
      int *head = lp->head;
      char *refsp = se->refsp;
      double *gamma = se->gamma;
      double *u = se->work;
      int i, j, k, ptr, end;
      double gamma_p, delta_p, e, r, t1, t2;
      xassert(se->valid);
      xassert(1 <= p && p <= m);
      xassert(1 <= q && q <= n-m);
      /* compute gamma[p] in current basis more accurately; also
       * compute auxiliary vector u */
      k = head[p]; /* x[k] = xB[p] */
      gamma_p = delta_p = (refsp[k] ? 1.0 : 0.0);
      for (i = 1; i <= m; i++)
         u[i] = 0.0;
      for (j = 1; j <= n-m; j++)
      {  k = head[m+j]; /* x[k] = xN[j] */
         if (refsp[k] && trow[j] != 0.0)
         {  gamma_p += trow[j] * trow[j];
            /* u := u + T[p,j] * N[j], where N[j] = A[k] is constraint
             * matrix column corresponding to xN[j] */
            ptr = lp->A_ptr[k];
            end = lp->A_ptr[k+1];
            for (; ptr < end; ptr++)
               u[lp->A_ind[ptr]] += trow[j] * lp->A_val[ptr];
         }
      }
      bfd_ftran(lp->bfd, u);
      /* compute relative error in gamma[p] */
      e = fabs(gamma_p - gamma[p]) / (1.0 + gamma_p);
      /* compute new gamma[p] */
      gamma[p] = gamma_p / (tcol[p] * tcol[p]);
      /* compute new gamma[i] for all i != p */
      for (i = 1; i <= m; i++)
      {  if (i == p)
            continue;
         /* compute r[i] = T[i,q] / T[p,q] */
         r = tcol[i] / tcol[p];
         /* compute new gamma[i] */
         t1 = gamma[i] + r * (r * gamma_p + u[i] + u[i]);
         k = head[i]; /* x[k] = xB[i] */
         t2 = (refsp[k] ? 1.0 : 0.0) + delta_p * r * r;
         gamma[i] = (t1 >= t2 ? t1 : t2);
      }
      return e;
}
예제 #2
0
void spx_eval_tcol(SPXLP *lp, int j, double tcol[/*1+m*/])
{     int m = lp->m;
      int n = lp->n;
      int *A_ptr = lp->A_ptr;
      int *A_ind = lp->A_ind;
      double *A_val = lp->A_val;
      int *head = lp->head;
      int i, k, ptr, end;
      xassert(1 <= j && j <= n-m);
      k = head[m+j]; /* x[k] = xN[j] */
      /* compute tcol = - inv(B) * N[j] */
      for (i = 1; i <= m; i++)
         tcol[i] = 0.0;
      ptr = A_ptr[k];
      end = A_ptr[k+1];
      for (; ptr < end; ptr++)
         tcol[A_ind[ptr]] = -A_val[ptr];
      bfd_ftran(lp->bfd, tcol);
      return;
}
예제 #3
0
void spx_eval_beta(SPXLP *lp, double beta[/*1+m*/])
{     int m = lp->m;
      int n = lp->n;
      int *A_ptr = lp->A_ptr;
      int *A_ind = lp->A_ind;
      double *A_val = lp->A_val;
      double *b = lp->b;
      double *l = lp->l;
      double *u = lp->u;
      int *head = lp->head;
      char *flag = lp->flag;
      int j, k, ptr, end;
      double fj, *y;
      /* compute y = b - N * xN */
      /* y := b */
      y = beta;
      memcpy(&y[1], &b[1], m * sizeof(double));
      /* y := y - N * f */
      for (j = 1; j <= n-m; j++)
      {  k = head[m+j]; /* x[k] = xN[j] */
         /* f[j] := active bound of xN[j] */
         fj = flag[j] ? u[k] : l[k];
         if (fj == 0.0 || fj == -DBL_MAX)
         {  /* either xN[j] has zero active bound or it is unbounded;
             * in the latter case its value is assumed to be zero */
            continue;
         }
         /* y := y - N[j] * f[j] */
         ptr = A_ptr[k];
         end = A_ptr[k+1];
         for (; ptr < end; ptr++)
            y[A_ind[ptr]] -= A_val[ptr] * fj;
      }
      /* compute beta = inv(B) * y */
      xassert(lp->valid);
      bfd_ftran(lp->bfd, beta);
      return;
}
예제 #4
0
void glp_ftran(glp_prob *lp, double x[])
{     int m = lp->m;
      GLPROW **row = lp->row;
      GLPCOL **col = lp->col;
      int i, k;
      /* B*x = b ===> (R*B*SB)*(inv(SB)*x) = R*b ===>
         B"*x" = b", where b" = R*b, x = SB*x" */
      if (!(m == 0 || lp->valid))
         xerror("glp_ftran: basis factorization does not exist\n");
      /* b" := R*b */
      for (i = 1; i <= m; i++)
         x[i] *= row[i]->rii;
      /* x" := inv(B")*b" */
      if (m > 0) bfd_ftran(lp->bfd, x);
      /* x := SB*x" */
      for (i = 1; i <= m; i++)
      {  k = lp->head[i];
         if (k <= m)
            x[i] /= row[k]->rii;
         else
            x[i] *= col[k-m]->sjj;
      }
      return;
}