void ILLratio_longdII_test (lpinfo * lp, int lindex, int lvstat, ratio_res * rs) { int j, k, indx = 0, tctr = 0; int col, ecol; int vs, bnd_exist = 0; int *perm = lp->upd.perm; int *ix = lp->upd.ix; int b_indx = -1; EGlpNum_t *t = lp->upd.t; EGlpNum_t *l, *u, *xb, *zAj = 0, x, y, t_j, z_max, t_max, t_z, theta, rcost, delta, zb_val, tb_val, az_max, azb_val, azAj; EGlpNum_t *pftol = &(lp->tol->pfeas_tol); EGlpNum_t *dftol = &(lp->tol->dfeas_tol); EGlpNum_t *pivtol = &(lp->tol->pivot_tol); EGlpNumInitVar (x); EGlpNumInitVar (azAj); EGlpNumInitVar (y); EGlpNumInitVar (t_j); EGlpNumInitVar (z_max); EGlpNumInitVar (az_max); EGlpNumInitVar (t_max); EGlpNumInitVar (t_z); EGlpNumInitVar (theta); EGlpNumInitVar (rcost); EGlpNumInitVar (delta); EGlpNumInitVar (zb_val); EGlpNumInitVar (azb_val); EGlpNumInitVar (tb_val); EGlpNumZero (t_j); EGlpNumZero (delta); EGlpNumZero (zb_val); EGlpNumZero (azb_val); EGlpNumCopy (tb_val, NINFTY); //#warning not sure about THIS line EGlpNumZero (rs->pivotval); rs->coeffch = 0; rs->eindex = -1; rs->ratio_stat = RATIO_FAILED; ILL_IFTRACE2 ("%s:tctr %d\n", __func__, 0); lp->upd.tctr = 0; lp->upd.i = 0; EGlpNumZero (lp->upd.tz); EGlpNumZero (lp->upd.piv); EGlpNumZero (lp->upd.c_obj); EGlpNumZero (lp->upd.dty); xb = &(lp->xbz[lindex]); col = lp->baz[lindex]; l = &(lp->lz[col]); u = &(lp->uz[col]); //rcost = (lvstat == STAT_LOWER) ? l - xb : xb - u; if (lvstat == STAT_LOWER) EGlpNumCopyDiff (rcost, *l, *xb); else EGlpNumCopyDiff (rcost, *xb, *u); for (k = 0, EGlpNumCopy (t_max, INFTY); k < lp->zA.nzcnt; k++) { zAj = &(lp->zA.coef[k]); if (EGlpNumIsEqual (*zAj, zeroLpNum, *pivtol)) continue; EGlpNumCopy (t_j, INFTY); j = lp->zA.indx[k]; col = lp->nbaz[j]; if (lp->vtype[col] == VARTIFICIAL || lp->vtype[col] == VFIXED) continue; if (lp->vtype[col] == VBOUNDED) { bnd_exist++; continue; } GET_XY_DRATIOTEST; if (EGlpNumIsLess (zeroLpNum, y)) { //t_j = (x + dftol) / y; //#warning Using tolerances to add to result, is it right? EGlpNumCopySum (t_j, x, *dftol); EGlpNumDivTo (t_j, y); } else { if (lp->vstat[col] == STAT_ZERO) EGlpNumCopyDiffRatio (t_j, x, *dftol, y); } if (EGlpNumIsEqqual (t_j, INFTY)) continue; if (EGlpNumIsLess (t_j, t_max)) EGlpNumCopy (t_max, t_j); } if (EGlpNumIsLess (t_max, zeroLpNum)) { /*printf ("dIIhell, %.4f\n", t_max); */ rs->ratio_stat = RATIO_NEGATIVE; ILL_CLEANUP; } if (bnd_exist == 0 && EGlpNumIsLeq (INFTY, t_max)) { rs->ratio_stat = RATIO_UNBOUNDED; /* * printf ("x = %.8f, b = %.2f \n", lp->xbz[lindex], (lvstat == STAT_LOWER ) ? lp->lz[lp->baz[lindex]] : lp->uz[lp->baz[lindex]]); */ ILL_CLEANUP; } if (bnd_exist != 0) { for (k = 0; k < lp->zA.nzcnt; k++) { zAj = &(lp->zA.coef[k]); if (EGlpNumIsEqual (*zAj, zeroLpNum, *pivtol)) continue; EGlpNumCopy (t_j, INFTY); j = lp->zA.indx[k]; col = lp->nbaz[j]; if (lp->vtype[col] != VBOUNDED) continue; GET_XY_DRATIOTEST; if (EGlpNumIsLess (zeroLpNum, y)) { EGlpNumCopyFrac (t_j, x, y); if (EGlpNumIsLeq (t_j, t_max)) { EGlpNumCopy (t[tctr], t_j); ix[tctr] = k; tctr++; } } } } if (tctr != 0) { for (j = 0; j < tctr; j++) perm[j] = j; ILLutil_EGlpNum_perm_quicksort (perm, t, tctr); for (j = 0; j < tctr; j++) { EGlpNumCopy (t_j, t[perm[j]]); /* we use x as temporal storage */ //lp->upd.c_obj += (t_j - delta) * rcost; EGlpNumCopy (x, t_j); EGlpNumSubTo (x, delta); EGlpNumAddInnProdTo (lp->upd.c_obj, x, rcost); EGlpNumCopy (delta, t_j); /*HHH*/ k = ix[perm[j]]; zAj = &(lp->zA.coef[k]); indx = lp->zA.indx[k]; col = lp->nbaz[indx]; l = &(lp->lz[col]); u = &(lp->uz[col]); vs = lp->vstat[col]; //theta = (vs == STAT_UPPER) ? (l - u) * zAj : (u - l) * zAj; EGlpNumCopyDiff (theta, *l, *u); EGlpNumMultTo (theta, *zAj); if (vs != STAT_UPPER) EGlpNumSign (theta); if (lvstat == STAT_LOWER) EGlpNumAddTo (rcost, theta); else EGlpNumSubTo (rcost, theta); if (EGlpNumIsLeq (rcost, *pftol)) { rs->eindex = indx; EGlpNumCopy (rs->tz, t_j); EGlpNumCopy (rs->pivotval, *zAj); rs->ratio_stat = RATIO_BCHANGE; if (EGlpNumIsLess (rs->tz, zeroLpNum)) { EGlpNumZero (rs->tz); rs->coeffch = 1; //rs->ecoeff = lp->cz[col] - lp->dz[indx]; EGlpNumCopyDiff (rs->ecoeff, lp->cz[col], lp->dz[indx]); //lp->upd.c_obj += (rs->tz - delta) * rcost; note ts->tz == 0; EGlpNumSubInnProdTo (lp->upd.c_obj, delta, rcost); } ILL_IFTRACE2 ("%s:tctr %d\n", __func__, tctr); lp->upd.tctr = tctr; lp->upd.i = j; EGlpNumCopy (lp->upd.tz, rs->tz); ILL_CLEANUP; } } ILL_IFTRACE2 ("%s:tctr %d\n", __func__, tctr); lp->upd.tctr = tctr; lp->upd.i = tctr; EGlpNumCopy (lp->upd.tz, t_j); EGlpNumCopy (zb_val, *zAj); EGlpNumCopyAbs (azb_val, zb_val); EGlpNumCopy (tb_val, t_j); b_indx = indx; } if (bnd_exist != 0 && EGlpNumIsLeq (INFTY, t_max)) { rs->ratio_stat = RATIO_UNBOUNDED; /* printf ("rcost: %.8f\n", rcost); */ ILL_CLEANUP; } EGlpNumZero (z_max); EGlpNumZero (az_max); indx = -1; EGlpNumZero (t_z); for (k = 0; k < lp->zA.nzcnt; k++) { zAj = &(lp->zA.coef[k]); EGlpNumCopyAbs (azAj, *zAj); if (EGlpNumIsEqual (*zAj, zeroLpNum, *pivtol)) continue; EGlpNumCopy (t_j, INFTY); j = lp->zA.indx[k]; col = lp->nbaz[j]; if (lp->vtype[col] == VARTIFICIAL || lp->vtype[col] == VFIXED || lp->vtype[col] == VBOUNDED) continue; GET_XY_DRATIOTEST; if (EGlpNumIsLess (zeroLpNum, y) || lp->vstat[col] == STAT_ZERO) EGlpNumCopyFrac (t_j, x, y); if (EGlpNumIsLeq (t_j, t_max)) { if (EGlpNumIsLess (az_max, azAj)) { EGlpNumCopy (z_max, *zAj); EGlpNumCopy (az_max, azAj); indx = j; EGlpNumCopy (t_z, t_j); } } } if (indx < 0) { rs->ratio_stat = RATIO_FAILED; ILL_CLEANUP; } if ((tctr == 0) || (EGlpNumIsLess (tb_val, zeroLpNum)) || (tctr != 0 && EGlpNumIsLeq (tb_val, t_z) && EGlpNumIsLeq (azb_val, az_max))) { /* we use x as temporal vvariable */ /* lp->upd.c_obj += (t_z - delta) * rcost; */ EGlpNumCopyDiff (x, t_z, delta); EGlpNumAddInnProdTo (lp->upd.c_obj, x, rcost); EGlpNumCopy (delta, t_z); rs->eindex = indx; EGlpNumCopy (rs->tz, t_z); EGlpNumCopy (rs->pivotval, z_max); rs->ratio_stat = RATIO_BCHANGE; } /* For now */ else if (tctr != 0) { rs->eindex = b_indx; EGlpNumCopy (rs->tz, tb_val); EGlpNumCopy (rs->pivotval, zb_val); rs->ratio_stat = RATIO_BCHANGE; lp->upd.i -= 1; } if (EGlpNumIsLess (rs->tz, zeroLpNum)) { /* if (tctr != 0) printf ("despite long step\n"); */ /* rs->tz = fabs (t_max / 20.0); */ EGlpNumCopyAbs (rs->tz, t_max); EGlpNumDivUiTo (rs->tz, 20); rs->coeffch = 1; ecol = lp->nbaz[indx]; if (lp->vstat[ecol] == STAT_LOWER) { /*rs->ecoeff = lp->cz[ecol] - lp->dz[indx] + rs->tz * fabs (z_max); */ EGlpNumCopy (rs->ecoeff, az_max); EGlpNumMultTo (rs->ecoeff, rs->tz); EGlpNumAddTo (rs->ecoeff, lp->cz[ecol]); EGlpNumSubTo (rs->ecoeff, lp->dz[indx]); } else if (lp->vstat[ecol] == STAT_UPPER) { /*rs->ecoeff = lp->cz[ecol] - lp->dz[indx] - rs->tz * fabs (z_max); */ EGlpNumCopy (rs->ecoeff, az_max); EGlpNumMultTo (rs->ecoeff, rs->tz); EGlpNumSign (rs->ecoeff); EGlpNumAddTo (rs->ecoeff, lp->cz[ecol]); EGlpNumSubTo (rs->ecoeff, lp->dz[indx]); } else { /*rs->ecoeff = lp->cz[ecol] - lp->dz[indx]; */ EGlpNumCopyDiff (rs->ecoeff, lp->cz[ecol], lp->dz[indx]); EGlpNumZero (rs->tz); } /* we use x as temporal storage */ /*lp->upd.c_obj += (rs->tz - delta) * rcost; */ EGlpNumCopy (x, rs->tz); EGlpNumSubTo (x, delta); EGlpNumAddInnProdTo (lp->upd.c_obj, x, rcost); } CLEANUP: ILLfct_update_counts (lp, CNT_DIIPIV, 0, rs->pivotval); EGlpNumCopy (lp->upd.piv, rs->pivotval); EGlpNumClearVar (x); EGlpNumClearVar (y); EGlpNumClearVar (t_j); EGlpNumClearVar (z_max); EGlpNumClearVar (az_max); EGlpNumClearVar (t_max); EGlpNumClearVar (t_z); EGlpNumClearVar (theta); EGlpNumClearVar (rcost); EGlpNumClearVar (delta); EGlpNumClearVar (zb_val); EGlpNumClearVar (azb_val); EGlpNumClearVar (tb_val); EGlpNumClearVar (azAj); }
void ILLratio_dI_test (lpinfo * lp, int lindex, int lvstat, ratio_res * rs) { int j = 0, k; int col; int cbnd, indx; int tctr = 0; int *perm = lp->upd.perm; int *ix = lp->upd.ix; EGlpNum_t *t = lp->upd.t; EGlpNum_t *zAj, x, y, t_j, theta, rcost, delta; EGlpNum_t *pftol = &(lp->tol->ip_tol); EGlpNum_t *pivtol = &(lp->tol->pivot_tol); EGlpNumInitVar (x); EGlpNumInitVar (y); EGlpNumInitVar (t_j); EGlpNumInitVar (theta); EGlpNumInitVar (rcost); EGlpNumInitVar (delta); EGlpNumZero (delta); EGlpNumZero (t_j); EGlpNumZero (rs->tz); /*HHH*/ rs->eindex = -1; rs->ratio_stat = RATIO_FAILED; EGlpNumZero (rs->pivotval); for (k = 0; k < lp->zA.nzcnt; k++) { zAj = &(lp->zA.coef[k]); if (EGlpNumIsEqual (*zAj, zeroLpNum, *pivtol)) continue; EGlpNumCopy (t_j, INFTY); j = lp->zA.indx[k]; col = lp->nbaz[j]; if (lp->vtype[col] == VARTIFICIAL || lp->vtype[col] == VFIXED) continue; GET_XY_DRATIOTEST; if (EGlpNumIsLess (y, zeroLpNum)) { if (lp->dfeas[j] != 0 && lp->vstat[col] != STAT_ZERO) { EGlpNumCopyFrac (t[tctr], x, y); ix[tctr] = 10 * k + BBTOLOWER; tctr++; } else if (lp->vstat[col] == STAT_ZERO) { if (lp->dfeas[j] < 0) { EGlpNumCopyFrac (t[tctr], x, y); ix[tctr] = 10 * k + BBTOLOWER; tctr++; } if (lp->dfeas[j] <= 0) { EGlpNumCopyFrac (t[tctr], x, y); ix[tctr] = 10 * k + BBTOUPPER; tctr++; } } } else { if (lp->dfeas[j] > 0) { if (lp->vstat[col] == STAT_ZERO) { EGlpNumCopyFrac (t[tctr], x, y); ix[tctr] = 10 * k + BATOUPPER; tctr++; EGlpNumCopyFrac (t[tctr], x, y); ix[tctr] = 10 * k + BATOLOWER; tctr++; } } else if (lp->dfeas[j] == 0) { EGlpNumCopyFrac (t[tctr], x, y); if (lp->vtype[col] == VBOUNDED) ix[tctr] = 10 * k + BSKIP; else ix[tctr] = 10 * k + BATOLOWER; tctr++; } } } if (tctr == 0) { rs->ratio_stat = RATIO_FAILED; ILL_CLEANUP; } for (j = 0; j < tctr; j++) perm[j] = j; ILLutil_EGlpNum_perm_quicksort (perm, t, tctr); EGlpNumZero (lp->upd.c_obj); EGlpNumCopy (rcost, lp->xbz[lindex]); if (lvstat == STAT_LOWER) EGlpNumSign (rcost); for (j = 0; j < tctr; j++) { cbnd = ix[perm[j]] % 10; if (cbnd == BSKIP) continue; EGlpNumCopy (t_j, t[perm[j]]); EGlpNumCopy (x, t_j); EGlpNumSubTo (x, delta); EGlpNumAddInnProdTo (lp->upd.c_obj, x, rcost); EGlpNumCopy (delta, t_j); k = ix[perm[j]] / 10; zAj = &(lp->zA.coef[k]); indx = lp->zA.indx[k]; if (lp->vstat[lp->nbaz[indx]] == STAT_LOWER || lp->vstat[lp->nbaz[indx]] == STAT_ZERO) EGlpNumCopyNeg (theta, *zAj); else EGlpNumCopy (theta, *zAj); if (lvstat == STAT_UPPER) EGlpNumSign (theta); switch (cbnd) { case BATOLOWER: case BATOUPPER: EGlpNumSubTo (rcost, theta); break; case BBTOLOWER: case BBTOUPPER: EGlpNumAddTo (rcost, theta); break; } if (EGlpNumIsLeq (rcost, *pftol)) { /* if (t_j < 0.0) printf ("dIhell\n"); */ rs->eindex = indx; EGlpNumCopy (rs->tz, t_j); EGlpNumCopy (rs->pivotval, *zAj); rs->ratio_stat = RATIO_BCHANGE; ILL_CLEANUP; } } CLEANUP: ILLfct_update_counts (lp, CNT_DIPIV, 0, rs->pivotval); ILL_IFTRACE2 ("%s:tctr %d\n", __func__, tctr); lp->upd.tctr = tctr; lp->upd.i = j; EGlpNumCopyAbs (lp->upd.tz, t_j); EGlpNumCopy (lp->upd.piv, rs->pivotval); if (rs->eindex != -1) lp->upd.fs = lp->dfeas[rs->eindex]; EGlpNumClearVar (x); EGlpNumClearVar (y); EGlpNumClearVar (t_j); EGlpNumClearVar (theta); EGlpNumClearVar (rcost); EGlpNumClearVar (delta); }
void ILLratio_pII_test (lpinfo * lp, int eindex, int dir, ratio_res * rs) { int i, k, indx, col, ecol; EGlpNum_t *x, *l, *u, t_max, ayi_max, yi_max, ay_ij, y_ij, t_i, t_z; EGlpNum_t *pivtol = &(lp->tol->pivot_tol); EGlpNum_t *pftol = &(lp->tol->pfeas_tol); EGlpNumInitVar (y_ij); EGlpNumInitVar (ay_ij); EGlpNumInitVar (t_i); EGlpNumInitVar (t_z); EGlpNumInitVar (t_max); EGlpNumInitVar (yi_max); EGlpNumInitVar (ayi_max); /*HHH*/ rs->boundch = 0; rs->lindex = -1; EGlpNumZero (rs->tz); rs->ratio_stat = RATIO_FAILED; rs->lvstat = -1; EGlpNumZero (rs->pivotval); EGlpNumZero (rs->lbound); ecol = lp->nbaz[eindex]; for (k = 0, EGlpNumCopy (t_max, INFTY); k < lp->yjz.nzcnt; k++) { EGlpNumCopy (y_ij, lp->yjz.coef[k]); EGlpNumCopyAbs (ay_ij, y_ij); if (EGlpNumIsEqual (y_ij, zeroLpNum, *pivtol)) continue; EGlpNumCopy (t_i, INFTY); i = lp->yjz.indx[k]; x = &(lp->xbz[i]); col = lp->baz[i]; l = &(lp->lz[col]); u = &(lp->uz[col]); if ((dir == VINCREASE && EGlpNumIsLess (zeroLpNum, y_ij)) || (dir == VDECREASE && EGlpNumIsLess (y_ij, zeroLpNum))) { if (EGlpNumIsNeqq (*l, NINFTY)) { EGlpNumCopyDiff (t_i, *x, *l); EGlpNumAddTo (t_i, *pftol); EGlpNumDivTo (t_i, ay_ij); } } else if ((dir == VINCREASE && EGlpNumIsLess (y_ij, zeroLpNum)) || (dir == VDECREASE && EGlpNumIsLess (zeroLpNum, y_ij))) { if (EGlpNumIsNeqq (*u, INFTY)) { EGlpNumCopySum (t_i, *u, *pftol); EGlpNumSubTo (t_i, *x); EGlpNumDivTo (t_i, ay_ij); } } if (EGlpNumIsEqqual (t_i, INFTY)) continue; if (EGlpNumIsLess (t_i, t_max)) { /*HHH tind = i; yval = fabs (y_ij); tval = t_i - pftol/fabs(y_ij); */ EGlpNumCopy (t_max, t_i); } } /* we use yi_max as temporal variable here */ EGlpNumCopyDiff (yi_max, lp->uz[ecol], lp->lz[ecol]); if (lp->vtype[ecol] == VBOUNDED && EGlpNumIsLeq (yi_max, t_max)) { EGlpNumCopy (t_max, yi_max); rs->ratio_stat = RATIO_NOBCHANGE; EGlpNumCopy (rs->tz, t_max); if (dir != VINCREASE) EGlpNumSign (rs->tz); ILL_CLEANUP; } if (EGlpNumIsLeq (INFTY, t_max)) { rs->ratio_stat = RATIO_UNBOUNDED; ILL_CLEANUP; } /*if (EGlpNumIsLess (t_max, zeroLpNum)) * printf ("pIIhell\n"); */ indx = -1; EGlpNumZero (t_z); EGlpNumZero (yi_max); EGlpNumZero (ayi_max); ILL_IFTRACE2 (":%d", lp->yjz.nzcnt); for (k = 0; k < lp->yjz.nzcnt; k++) { EGlpNumCopy (y_ij, lp->yjz.coef[k]); EGlpNumCopyAbs (ay_ij, y_ij); if (EGlpNumIsEqual (y_ij, zeroLpNum, *pivtol)) continue; EGlpNumCopy (t_i, INFTY); i = lp->yjz.indx[k]; x = &(lp->xbz[i]); col = lp->baz[i]; l = &(lp->lz[col]); u = &(lp->uz[col]); if ((dir == VINCREASE && EGlpNumIsLess (zeroLpNum, y_ij)) || (dir == VDECREASE && EGlpNumIsLess (y_ij, zeroLpNum))) { if (EGlpNumIsNeqq (*l, NINFTY)) EGlpNumCopyDiffRatio (t_i, *x, *l, ay_ij); } else if ((dir == VINCREASE && EGlpNumIsLess (y_ij, zeroLpNum)) || (dir == VDECREASE && EGlpNumIsLess (zeroLpNum, y_ij))) { if (EGlpNumIsNeqq (*u, INFTY)) EGlpNumCopyDiffRatio (t_i, *u, *x, ay_ij); } if (EGlpNumIsLeq (t_i, t_max)) { if (EGlpNumIsLess (ayi_max, ay_ij)) { EGlpNumCopy (yi_max, y_ij); EGlpNumCopy (ayi_max, ay_ij); indx = i; EGlpNumCopy (t_z, t_i); ILL_IFTRACE2 (":%d:%lf:%lf:%lf:%lf", indx, EGlpNumToLf (t_i), EGlpNumToLf (t_max), EGlpNumToLf (ayi_max), EGlpNumToLf (ay_ij)); } } } if (indx < 0) { rs->ratio_stat = RATIO_FAILED; } else { /* * if (tind != rs->lindex){ * HHHprintf ("tmax %e tval = %e yval = %e tind = %d\n", t_max, tval, yval, tind); * HHHprintf ("h tval = %e yval = %e tind = %d\n",rs->tz, yi_max, rs->lindex); * } */ ILL_IFTRACE2 (":%d", indx); rs->lindex = indx; EGlpNumCopy (rs->tz, t_z); EGlpNumCopy (rs->pivotval, yi_max); rs->ratio_stat = RATIO_BCHANGE; if (dir == VINCREASE) rs->lvstat = (EGlpNumIsLess (zeroLpNum, yi_max)) ? STAT_LOWER : STAT_UPPER; else rs->lvstat = (EGlpNumIsLess (zeroLpNum, yi_max)) ? STAT_UPPER : STAT_LOWER; if (EGlpNumIsLess (rs->tz, zeroLpNum)) { ILL_IFTRACE2 ("need to change bound, tz=%la\n", EGlpNumToLf (rs->tz)); EGlpNumCopyAbs (rs->tz, t_max); EGlpNumDivUiTo (rs->tz, 10); rs->boundch = 1; EGlpNumCopy (rs->lbound, lp->xbz[rs->lindex]); if (rs->lvstat == STAT_LOWER) EGlpNumSubInnProdTo (rs->lbound, rs->tz, ayi_max); else EGlpNumAddInnProdTo (rs->lbound, rs->tz, ayi_max); } if (dir == VDECREASE) EGlpNumSign (rs->tz); } CLEANUP: ILLfct_update_counts (lp, CNT_PIIPIV, 0, rs->pivotval); EGlpNumClearVar (y_ij); EGlpNumClearVar (ay_ij); EGlpNumClearVar (t_i); EGlpNumClearVar (t_z); EGlpNumClearVar (t_max); EGlpNumClearVar (yi_max); EGlpNumClearVar (ayi_max); }
void ILLratio_pI_test (lpinfo * lp, int eindex, int dir, ratio_res * rs) { int i = 0, k = 0; int col, ecol; int cbnd, indx = 0; int tctr = 0; int *perm = lp->upd.perm; int *ix = lp->upd.ix; EGlpNum_t *pivtol = &(lp->tol->pivot_tol); EGlpNum_t *dftol = &(lp->tol->id_tol); /*HHH*/ EGlpNum_t * t = lp->upd.t; EGlpNum_t t_i, delta, y_ij, rcost, nrcost, ntmp; EGlpNum_t *x, *l, *u; /*HHH*/ EGlpNumInitVar (t_i); EGlpNumInitVar (delta); EGlpNumInitVar (y_ij); EGlpNumInitVar (rcost); EGlpNumInitVar (nrcost); EGlpNumInitVar (ntmp); EGlpNumZero (t_i); EGlpNumZero (y_ij); EGlpNumZero (delta); rs->lindex = -1; EGlpNumZero (rs->tz); EGlpNumZero (rs->pivotval); rs->ratio_stat = RATIO_FAILED; rs->lvstat = -1; ecol = lp->nbaz[eindex]; ILL_IFTRACE2 ("%s:%d:%d:%d:%d", __func__, eindex, dir, ecol, (VBOUNDED == lp->vtype[ecol])); if (lp->vtype[ecol] == VBOUNDED) { EGlpNumCopyDiff (t[0], lp->uz[ecol], lp->lz[ecol]); ix[0] = BBOUND; ILL_IFTRACE2 (":%d[%d](%la,%la,%la)\n", ix[tctr], tctr, EGlpNumToLf (t[tctr]), EGlpNumToLf (lp->uz[ecol]), EGlpNumToLf (lp->lz[ecol])); tctr++; } ILL_IFTRACE2 (":%d", lp->yjz.nzcnt); for (k = 0; k < lp->yjz.nzcnt; k++) { EGlpNumCopy (y_ij, lp->yjz.coef[k]); if (EGlpNumIsEqual (y_ij, zeroLpNum, *pivtol)) continue; i = lp->yjz.indx[k]; x = &(lp->xbz[i]); col = lp->baz[i]; l = &(lp->lz[col]); u = &(lp->uz[col]); if ((dir == VINCREASE && EGlpNumIsLess (zeroLpNum, y_ij)) || (dir == VDECREASE && EGlpNumIsLess (y_ij, zeroLpNum))) { if (EGlpNumIsLess (y_ij, zeroLpNum)) EGlpNumSign (y_ij); ILL_IFTRACE2 (":%d", lp->bfeas[i]); if (lp->bfeas[i] > 0) { EGlpNumCopyDiffRatio (t[tctr], *x, *u, y_ij); ix[tctr] = 10 * k + BATOUPPER; ILL_IFTRACE2 (":%d[%d](%la)\n", ix[tctr], tctr, EGlpNumToLf (t[tctr])); tctr++; if (EGlpNumIsNeqq (*l, NINFTY)) { EGlpNumCopyDiffRatio (t[tctr], *x, *l, y_ij); ix[tctr] = 10 * k + BATOLOWER; ILL_IFTRACE2 (":%d[%d](%la)\n", ix[tctr], tctr, EGlpNumToLf (t[tctr])); tctr++; } } else if (lp->bfeas[i] == 0) { if (EGlpNumIsNeqq (*l, NINFTY)) { EGlpNumCopyDiffRatio (t[tctr], *x, *l, y_ij); ix[tctr] = 10 * k + BATOLOWER; ILL_IFTRACE2 (":%d[%d](%la)\n", ix[tctr], tctr, EGlpNumToLf (t[tctr])); tctr++; } } } else if ((dir == VINCREASE && EGlpNumIsLess (y_ij, zeroLpNum)) || (dir == VDECREASE && EGlpNumIsLess (zeroLpNum, y_ij))) { if (EGlpNumIsLess (y_ij, zeroLpNum)) EGlpNumSign (y_ij); ILL_IFTRACE2 (":%d", lp->bfeas[i]); if (lp->bfeas[i] < 0) { EGlpNumCopyDiffRatio (t[tctr], *l, *x, y_ij); ix[tctr] = 10 * k + BBTOLOWER; ILL_IFTRACE2 (":%d[%d](%la)\n", ix[tctr], tctr, EGlpNumToLf (t[tctr])); tctr++; if (EGlpNumIsNeqq (*u, INFTY)) { EGlpNumCopyDiffRatio (t[tctr], *u, *x, y_ij); ix[tctr] = 10 * k + BBTOUPPER; ILL_IFTRACE2 (":%d[%d](%la)\n", ix[tctr], tctr, EGlpNumToLf (t[tctr])); tctr++; } } else if (lp->bfeas[i] == 0) { if (EGlpNumIsNeqq (*u, INFTY)) { EGlpNumCopyDiffRatio (t[tctr], *u, *x, y_ij); ix[tctr] = 10 * k + BBTOUPPER; ILL_IFTRACE2 (":%d[%d](%la)\n", ix[tctr], tctr, EGlpNumToLf (t[tctr])); tctr++; } } } } if (tctr == 0) { rs->ratio_stat = RATIO_FAILED; ILL_CLEANUP; } for (i = 0; i < tctr; i++) perm[i] = i; ILLutil_EGlpNum_perm_quicksort (perm, t, tctr); EGlpNumZero (lp->upd.c_obj); EGlpNumCopy (rcost, lp->pIdz[eindex]); ILL_IFTRACE2 ("\n%s:%d:%lf", __func__, tctr, EGlpNumToLf (rcost)); for (i = 0; i < tctr; i++) { EGlpNumCopy (t_i, t[perm[i]]); EGlpNumCopy (ntmp, t_i); EGlpNumSubTo (ntmp, delta); EGlpNumAddInnProdTo (lp->upd.c_obj, ntmp, rcost); EGlpNumCopy (delta, t_i); ILL_IFTRACE2 (":%d:%lf", perm[i], EGlpNumToLf (delta)); /*HHH*/ cbnd = ix[perm[i]] % 10; if (cbnd != BBOUND) { k = ix[perm[i]] / 10; EGlpNumCopy (y_ij, lp->yjz.coef[k]); indx = lp->yjz.indx[k]; ILL_IFTRACE2 (":%d", indx); } switch (cbnd) { case BBOUND: rs->ratio_stat = RATIO_NOBCHANGE; EGlpNumCopy (rs->tz, t_i); if (dir != VINCREASE) EGlpNumSign (rs->tz); ILL_CLEANUP; case BATOLOWER: case BATOUPPER: EGlpNumAddTo (rcost, y_ij); break; case BBTOLOWER: case BBTOUPPER: EGlpNumSubTo (rcost, y_ij); break; } EGlpNumCopyNeg (nrcost, rcost); if ((dir == VINCREASE && EGlpNumIsLeq (nrcost, *dftol)) || (dir == VDECREASE && EGlpNumIsLeq (rcost, *dftol))) { /* change 5 to -1 if t_i > 0 is required below */ if (EGlpNumIsLess (t_i, zeroLpNum) && i > 5) { /* printf ("pIhell %.5f %d\n", t_i, i); */ EGlpNumDivUiTo (t_i, 2); rs->ratio_stat = RATIO_NEGATIVE; EGlpNumZero (rs->tz); ILL_CLEANUP; } rs->lindex = indx; rs->ratio_stat = RATIO_BCHANGE; if (cbnd == BATOLOWER || cbnd == BBTOLOWER) rs->lvstat = STAT_LOWER; else rs->lvstat = STAT_UPPER; EGlpNumCopy (rs->pivotval, y_ij); EGlpNumCopy (rs->tz, t_i); if (dir != VINCREASE) EGlpNumSign (rs->tz); ILL_CLEANUP; } } CLEANUP: ILLfct_update_counts (lp, CNT_PIPIV, 0, rs->pivotval); ILL_IFTRACE2 (":tctr %d:%d\n", tctr, rs->ratio_stat); lp->upd.tctr = tctr; lp->upd.i = i; EGlpNumCopy (lp->upd.tz, t_i); EGlpNumCopy (lp->upd.piv, rs->pivotval); if (dir == VDECREASE) EGlpNumSign (lp->upd.c_obj); if (rs->lindex != -1) lp->upd.fs = lp->bfeas[rs->lindex]; EGlpNumClearVar (t_i); EGlpNumClearVar (delta); EGlpNumClearVar (y_ij); EGlpNumClearVar (rcost); EGlpNumClearVar (nrcost); EGlpNumClearVar (ntmp); }
/** @brief Tester program for EGlpNum_t structure and functions * @return zero on success, non-zero otherwise * @par Description: * Perform various tests on EGlpNum_t and their functions * */ int main (int argc, char **argv) { /* local variables */ EGlpNum_t ntmp[4]; double dtmp[5]; char *strnum1, *strnum2, *strnum3; int rval=0; #ifdef HAVE_LIBGMP int n_char = 0; mpq_t qnum; #endif EGlpNumStart(); /* set signal and limits */ EGsigSet(rval,CLEANUP); EGsetLimits(3600.0,4294967295UL); #ifdef HAVE_LIBGMP EGlpNumSetPrecision (128); mpq_init (qnum); #endif EGlpNumInitVar (ntmp[0]); EGlpNumInitVar (ntmp[1]); EGlpNumInitVar (ntmp[2]); EGlpNumInitVar (ntmp[3]); /* the input should have at least two parameters, namelly the number where we * will work on */ if (argc < 3) { fprintf (stderr, "usage: %s num1 num2\n\tWhere num1 and num2 are numbers in" " the number format (either a/b or regular doubles)\n", argv[0]); exit (1); } /* we ask for two numbers and perform some basic operations and compare * aganist double arithmetic */ #ifdef HAVE_LIBGMP n_char = mpq_EGlpNumReadStrXc (qnum, argv[1]); #endif EGlpNumReadStr (ntmp[0], argv[1]); EGlpNumReadStr (ntmp[1], argv[2]); dtmp[0] = EGlpNumToLf (ntmp[0]); dtmp[1] = EGlpNumToLf (ntmp[1]); /* convert numbers */ strnum1 = EGlpNumGetStr (ntmp[0]); strnum2 = EGlpNumGetStr (ntmp[1]); fprintf (stderr, "You Input %s (%lg) and %s (%lg)\n", strnum1, dtmp[0], strnum2, dtmp[1]); #ifdef HAVE_LIBGMP strnum3 = mpq_EGlpNumGetStr (qnum); fprintf (stderr, "Your first number represented as exact rational is %s, " "readed with %d chars\n", strnum3, n_char); free (strnum3); mpq_EGlpNumSet (qnum, dtmp[0]); strnum3 = mpq_EGlpNumGetStr (qnum); fprintf (stderr, "Your first number represented as continuous fraction " "is %s, readed with %d chars\n", strnum3, n_char); free (strnum3); #endif /* internal constants */ strnum3 = EGlpNumGetStr (oneLpNum); fprintf (stderr, "1.0 = %s\n", strnum3); EGfree (strnum3); strnum3 = EGlpNumGetStr (zeroLpNum); fprintf (stderr, "0.0 = %s\n", strnum3); EGfree (strnum3); strnum3 = EGlpNumGetStr (epsLpNum); fprintf (stderr, "eps = %s\n", strnum3); EGfree (strnum3); strnum3 = EGlpNumGetStr (MaxLpNum); fprintf (stderr, "Max = %s\n", strnum3); EGfree (strnum3); strnum3 = EGlpNumGetStr (MinLpNum); fprintf (stderr, "Min = %s\n", strnum3); EGfree (strnum3); /* copying functions */ EGlpNumCopy (ntmp[2], ntmp[0]); strnum3 = EGlpNumGetStr (ntmp[2]); fprintf (stderr, "%s = %s (%lg)\n", strnum3, strnum1, dtmp[0]); EGfree (strnum3); EGlpNumCopyDiff (ntmp[2], ntmp[0], ntmp[1]); strnum3 = EGlpNumGetStr (ntmp[2]); fprintf (stderr, "%s = %s - %s (%lg)\n", strnum3, strnum1, strnum2, dtmp[0] - dtmp[1]); EGfree (strnum3); EGlpNumCopyDiffRatio (ntmp[2], ntmp[0], ntmp[1], ntmp[0]); strnum3 = EGlpNumGetStr (ntmp[2]); fprintf (stderr, "%s = (%s - %s)/%s (%lg)\n", strnum3, strnum1, strnum2, strnum1, (dtmp[0] - dtmp[1]) / dtmp[0]); EGfree (strnum3); EGlpNumCopySum (ntmp[2], ntmp[0], ntmp[1]); strnum3 = EGlpNumGetStr (ntmp[2]); fprintf (stderr, "%s = %s + %s (%lg)\n", strnum3, strnum1, strnum2, dtmp[0] + dtmp[1]); EGfree (strnum3); EGlpNumCopySqrOver (ntmp[2], ntmp[1], ntmp[0]); strnum3 = EGlpNumGetStr (ntmp[2]); fprintf (stderr, "%s = %s^2/%s (%lg)\n", strnum3, strnum2, strnum1, dtmp[1] * dtmp[1] / dtmp[0]); EGfree (strnum3); EGlpNumCopyAbs (ntmp[2], ntmp[0]); strnum3 = EGlpNumGetStr (ntmp[2]); fprintf (stderr, "%s = |%s| (%lg)\n", strnum3, strnum1, fabs (dtmp[0])); EGfree (strnum3); EGlpNumCopyNeg (ntmp[2], ntmp[0]); strnum3 = EGlpNumGetStr (ntmp[2]); fprintf (stderr, "%s = -1*%s (%lg)\n", strnum3, strnum1, -dtmp[0]); EGfree (strnum3); EGlpNumCopyFrac (ntmp[2], ntmp[1], ntmp[0]); strnum3 = EGlpNumGetStr (ntmp[2]); fprintf (stderr, "%s = %s/%s (%lg)\n", strnum3, strnum2, strnum1, dtmp[1] / dtmp[0]); EGfree (strnum3); /* add */ EGlpNumCopy (ntmp[2], ntmp[0]); EGlpNumAddTo (ntmp[2], ntmp[1]); strnum3 = EGlpNumGetStr (ntmp[2]); fprintf (stderr, "%s + %s = %s (%lg)\n", strnum1, strnum2, strnum3, dtmp[0] + dtmp[1]); EGfree (strnum3); EGlpNumCopy (ntmp[2], ntmp[0]); EGlpNumAddUiTo (ntmp[2], 0xffU); strnum3 = EGlpNumGetStr (ntmp[2]); fprintf (stderr, "%s + %u = %s (%lg)\n", strnum1, 0xffU, strnum3, dtmp[0] + 0xffU); EGfree (strnum3); /* substract */ EGlpNumCopy (ntmp[2], ntmp[0]); EGlpNumSubTo (ntmp[2], ntmp[1]); strnum3 = EGlpNumGetStr (ntmp[2]); fprintf (stderr, "%s - %s = %s (%lg)\n", strnum1, strnum2, strnum3, dtmp[0] - dtmp[1]); EGfree (strnum3); EGlpNumCopy (ntmp[2], ntmp[0]); EGlpNumSubUiTo (ntmp[2], 0xffU); strnum3 = EGlpNumGetStr (ntmp[2]); fprintf (stderr, "%s - %u = %s (%lg)\n", strnum1, 0xffU, strnum3, dtmp[0] - 0xffU); EGfree (strnum3); /* multiply */ EGlpNumCopy (ntmp[2], ntmp[0]); EGlpNumMultTo (ntmp[2], ntmp[1]); strnum3 = EGlpNumGetStr (ntmp[2]); fprintf (stderr, "%s * %s = %s (%lg)\n", strnum1, strnum2, strnum3, dtmp[0] * dtmp[1]); EGfree (strnum3); /* multiply unsigned */ EGlpNumCopy (ntmp[2], ntmp[0]); EGlpNumMultUiTo (ntmp[2], 13); strnum3 = EGlpNumGetStr (ntmp[2]); fprintf (stderr, "%s * 13 = %s (%lg)\n", strnum1, strnum3, dtmp[0] * 13); EGfree (strnum3); /* inverse */ EGlpNumCopy (ntmp[2], ntmp[0]); EGlpNumInv (ntmp[2]); strnum3 = EGlpNumGetStr (ntmp[2]); fprintf (stderr, "1/%s = %s (%lg)\n", strnum1, strnum3, 1.0 / dtmp[0]); EGfree (strnum3); /* floor and ceil */ EGlpNumFloor (ntmp[2], ntmp[0]); strnum3 = EGlpNumGetStr (ntmp[2]); fprintf (stderr, "floor(%s) = %s (%lg)\n", strnum1, strnum3, floor (dtmp[0])); EGfree (strnum3); EGlpNumCeil (ntmp[2], ntmp[0]); strnum3 = EGlpNumGetStr (ntmp[2]); fprintf (stderr, "ceil(%s) = %s (%lg)\n", strnum1, strnum3, ceil (dtmp[0])); EGfree (strnum3); /* negative and inner products */ EGlpNumCopy (ntmp[2], ntmp[0]); EGlpNumSign (ntmp[2]); strnum3 = EGlpNumGetStr (ntmp[2]); fprintf (stderr, "-(%s) = %s (%lg)\n", strnum1, strnum3, -dtmp[0]); EGfree (strnum3); EGlpNumOne (ntmp[2]); EGlpNumAddInnProdTo (ntmp[2], ntmp[0], ntmp[1]); strnum3 = EGlpNumGetStr (ntmp[2]); fprintf (stderr, "1.0 + %s*%s = %s (%lg)\n", strnum1, strnum2, strnum3, 1.0 + dtmp[1] * dtmp[0]); EGfree (strnum3); EGlpNumOne (ntmp[2]); EGlpNumSubInnProdTo (ntmp[2], ntmp[0], ntmp[1]); strnum3 = EGlpNumGetStr (ntmp[2]); fprintf (stderr, "1.0 - %s*%s = %s (%lg)\n", strnum1, strnum2, strnum3, 1.0 - dtmp[1] * dtmp[0]); EGfree (strnum3); /* divide */ EGlpNumCopy (ntmp[2], ntmp[0]); EGlpNumDivTo (ntmp[2], ntmp[1]); strnum3 = EGlpNumGetStr (ntmp[2]); fprintf (stderr, "%s / %s = %s (%lg)\n", strnum1, strnum2, strnum3, dtmp[0] / dtmp[1]); EGfree (strnum3); EGlpNumCopy (ntmp[2], ntmp[0]); EGlpNumDivUiTo (ntmp[2], 0xffU); strnum3 = EGlpNumGetStr (ntmp[2]); fprintf (stderr, "%s / %u = %s (%lg)\n", strnum1, 0xffU, strnum3, dtmp[0] / 0xffU); EGfree (strnum3); EGfree (strnum1); EGfree (strnum2); #ifdef HAVE_LIBGMP /* test transformation to rationals */ { mpq_t n1, n2; mpf_t f1, f2; mpq_init (n1); mpq_init (n2); mpf_init (f1); mpf_init (f2); mpf_EGlpNumSet(f1,EGlpNumToLf(ntmp[0])); mpf_EGlpNumSet(f2,EGlpNumToLf(ntmp[1])); mpq_EGlpNumSet_mpf (n1, f1); mpq_EGlpNumSet_mpf (n2, f2); strnum1 = mpq_EGlpNumGetStr (n1); strnum2 = mpq_EGlpNumGetStr (n2); fprintf (stderr, "Your input in rational was:\n\t(%10.7lf) %s\n\t(%10.7lf)" " %s\n", EGlpNumToLf (ntmp[0]), strnum1, EGlpNumToLf (ntmp[1]), strnum2); EGfree (strnum1); EGfree (strnum2); /* test natural exponentiation */ mpf_EGlpNumEpow (f1, -38.81624211135693732736499880); mpf_set_ui (f2, (unsigned long)1); mpf_div_2exp (f2, f2, (unsigned long)56); strnum1 = mpf_EGlpNumGetStr (f1); strnum2 = mpf_EGlpNumGetStr (f2); fprintf (stderr, "2^-56 = %s ~ %s\n", strnum1, strnum2); EGfree (strnum1); EGfree (strnum2); mpq_clear (n1); mpq_clear (n2); mpf_clear (f1); mpf_clear (f2); } #endif /* ending */ CLEANUP: EGlpNumClearVar (ntmp[0]); EGlpNumClearVar (ntmp[1]); EGlpNumClearVar (ntmp[2]); EGlpNumClearVar (ntmp[3]); #ifdef HAVE_LIBGMP mpq_clear (qnum); #endif EGlpNumClear(); return 0; }