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; }
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; }
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; }
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; }