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); }
/** @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; }