double spx_update_gamma(SPXLP *lp, SPXSE *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_q, delta_q, e, r, s, t1, t2; xassert(se->valid); xassert(1 <= p && p <= m); xassert(1 <= q && q <= n-m); /* compute gamma[q] in current basis more accurately; also * compute auxiliary vector u */ k = head[m+q]; /* x[k] = xN[q] */ gamma_q = delta_q = (refsp[k] ? 1.0 : 0.0); for (i = 1; i <= m; i++) { k = head[i]; /* x[k] = xB[i] */ if (refsp[k]) { gamma_q += tcol[i] * tcol[i]; u[i] = tcol[i]; } else u[i] = 0.0; } bfd_btran(lp->bfd, u); /* compute relative error in gamma[q] */ e = fabs(gamma_q - gamma[q]) / (1.0 + gamma_q); /* compute new gamma[q] */ gamma[q] = gamma_q / (tcol[p] * tcol[p]); /* compute new gamma[j] for all j != q */ for (j = 1; j <= n-m; j++) { if (j == q) continue; if (-1e-9 < trow[j] && trow[j] < +1e-9) { /* T[p,j] is close to zero; gamma[j] is not changed */ continue; } /* compute r[j] = T[p,j] / T[p,q] */ r = trow[j] / tcol[p]; /* compute inner product s[j] = N'[j] * u, where N[j] = A[k] * is constraint matrix column corresponding to xN[j] */ s = 0.0; k = head[m+j]; /* x[k] = xN[j] */ ptr = lp->A_ptr[k]; end = lp->A_ptr[k+1]; for (; ptr < end; ptr++) s += lp->A_val[ptr] * u[lp->A_ind[ptr]]; /* compute new gamma[j] */ t1 = gamma[j] + r * (r * gamma_q + s + s); t2 = (refsp[k] ? 1.0 : 0.0) + delta_q * r * r; gamma[j] = (t1 >= t2 ? t1 : t2); } return e; }
void spx_eval_rho(SPXLP *lp, int i, double rho[/*1+m*/]) { int m = lp->m; int j; xassert(1 <= i && i <= m); /* compute rho = inv(B') * e[i] */ for (j = 1; j <= m; j++) rho[j] = 0.0; rho[i] = 1.0; bfd_btran(lp->bfd, rho); return; }
void spx_eval_pi(SPXLP *lp, double pi[/*1+m*/]) { int m = lp->m; double *c = lp->c; int *head = lp->head; int i; double *cB; /* construct cB */ cB = pi; for (i = 1; i <= m; i++) cB[i] = c[head[i]]; /* compute pi = inv(B) * cB */ bfd_btran(lp->bfd, pi); return; }
void glp_btran(glp_prob *lp, double x[]) { int m = lp->m; GLPROW **row = lp->row; GLPCOL **col = lp->col; int i, k; /* B'*x = b ===> (SB*B'*R)*(inv(R)*x) = SB*b ===> (B")'*x" = b", where b" = SB*b, x = R*x" */ if (!(m == 0 || lp->valid)) xerror("glp_btran: basis factorization does not exist\n"); /* b" := SB*b */ 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; } /* x" := inv[(B")']*b" */ if (m > 0) bfd_btran(lp->bfd, x); /* x := R*x" */ for (i = 1; i <= m; i++) x[i] *= row[i]->rii; return; }