dbl_ratio.c

Go to the documentation of this file.
00001 /****************************************************************************/
00002 /*                                                                          */
00003 /*  This file is part of QSopt_ex.                                          */
00004 /*                                                                          */
00005 /*  (c) Copyright 2006 by David Applegate, William Cook, Sanjeeb Dash,      */
00006 /*  and Daniel Espinoza                                                     */
00007 /*                                                                          */
00008 /*  Sanjeeb Dash ownership of copyright in QSopt_ex is derived from his     */
00009 /*  copyright in QSopt.                                                     */
00010 /*                                                                          */
00011 /*  This code may be used under the terms of the GNU General Public License */
00012 /*  (Version 2.1 or later) as published by the Free Software Foundation.    */
00013 /*                                                                          */
00014 /*  Alternatively, use is granted for research purposes only.               */
00015 /*                                                                          */
00016 /*  It is your choice of which of these two licenses you are operating      */
00017 /*  under.                                                                  */
00018 /*                                                                          */
00019 /*  We make no guarantees about the correctness or usefulness of this code. */
00020 /*                                                                          */
00021 /****************************************************************************/
00022 
00023 /* "$RCSfile: dbl_ratio.c,v $ $Revision: 1.2 $ $Date: 2003/11/05 16:49:52 $"; */
00024 static int TRACE = 0;
00025 
00026 #include "config.h"
00027 #include "dbl_sortrus.h"
00028 #include "stddefs.h"
00029 #include "dbl_iqsutil.h"
00030 #include "dbl_lpdefs.h"
00031 #include "dbl_ratio.h"
00032 #include "dbl_fct.h"
00033 #ifdef USEDMALLOC
00034 #include "dmalloc.h"
00035 #endif
00036 
00037 void dbl_ILLratio_pI_test (
00038   dbl_lpinfo * lp,
00039   int eindex,
00040   int dir,
00041   dbl_ratio_res * rs)
00042 {
00043   int i = 0, k = 0;
00044   int col, ecol;
00045   int cbnd, indx = 0;
00046   int tctr = 0;
00047   int *perm = lp->upd.perm;
00048   int *ix = lp->upd.ix;
00049   double *pivtol = &(lp->tol->pivot_tol);
00050   double *dftol = &(lp->tol->id_tol);
00051 
00052    /*HHH*/ double * t = lp->upd.t;
00053   double t_i, delta, y_ij, rcost, nrcost, ntmp;
00054   double *x, *l, *u;
00055 
00056    /*HHH*/ dbl_EGlpNumInitVar (t_i);
00057   dbl_EGlpNumInitVar (delta);
00058   dbl_EGlpNumInitVar (y_ij);
00059   dbl_EGlpNumInitVar (rcost);
00060   dbl_EGlpNumInitVar (nrcost);
00061   dbl_EGlpNumInitVar (ntmp);
00062   dbl_EGlpNumZero (t_i);
00063   dbl_EGlpNumZero (y_ij);
00064   dbl_EGlpNumZero (delta);
00065   rs->lindex = -1;
00066   dbl_EGlpNumZero (rs->tz);
00067   dbl_EGlpNumZero (rs->pivotval);
00068   rs->ratio_stat = RATIO_FAILED;
00069   rs->lvstat = -1;
00070   ecol = lp->nbaz[eindex];
00071   ILL_IFTRACE2 ("%s:%d:%d:%d:%d", __func__, eindex, dir, ecol,
00072                 (VBOUNDED == lp->vtype[ecol]));
00073   if (lp->vtype[ecol] == VBOUNDED)
00074   {
00075     dbl_EGlpNumCopyDiff (t[0], lp->uz[ecol], lp->lz[ecol]);
00076     ix[0] = BBOUND;
00077     ILL_IFTRACE2 (":%d[%d](%la,%la,%la)\n", ix[tctr], tctr,
00078                   dbl_EGlpNumToLf (t[tctr]), dbl_EGlpNumToLf (lp->uz[ecol]),
00079                   dbl_EGlpNumToLf (lp->lz[ecol]));
00080     tctr++;
00081   }
00082   ILL_IFTRACE2 (":%d", lp->yjz.nzcnt);
00083   for (k = 0; k < lp->yjz.nzcnt; k++)
00084   {
00085     dbl_EGlpNumCopy (y_ij, lp->yjz.coef[k]);
00086     if (!dbl_EGlpNumIsNeqZero (y_ij, *pivtol))
00087       continue;
00088 
00089     i = lp->yjz.indx[k];
00090     x = &(lp->xbz[i]);
00091     col = lp->baz[i];
00092     l = &(lp->lz[col]);
00093     u = &(lp->uz[col]);
00094 
00095     if ((dir == VINCREASE && dbl_EGlpNumIsGreatZero (y_ij)) ||
00096         (dir == VDECREASE && dbl_EGlpNumIsLessZero (y_ij)))
00097     {
00098       if (dbl_EGlpNumIsLessZero (y_ij))
00099         dbl_EGlpNumSign (y_ij);
00100       ILL_IFTRACE2 (":%d", lp->bfeas[i]);
00101       if (lp->bfeas[i] > 0)
00102       {
00103         dbl_EGlpNumCopyDiffRatio (t[tctr], *x, *u, y_ij);
00104         ix[tctr] = 10 * k + BATOUPPER;
00105         ILL_IFTRACE2 (":%d[%d](%la)\n", ix[tctr], tctr, dbl_EGlpNumToLf (t[tctr]));
00106         tctr++;
00107         if (dbl_EGlpNumIsNeqq (*l, dbl_NINFTY))
00108         {
00109           dbl_EGlpNumCopyDiffRatio (t[tctr], *x, *l, y_ij);
00110           ix[tctr] = 10 * k + BATOLOWER;
00111           ILL_IFTRACE2 (":%d[%d](%la)\n", ix[tctr], tctr,
00112                         dbl_EGlpNumToLf (t[tctr]));
00113           tctr++;
00114         }
00115       }
00116       else if (lp->bfeas[i] == 0)
00117       {
00118         if (dbl_EGlpNumIsNeqq (*l, dbl_NINFTY))
00119         {
00120           dbl_EGlpNumCopyDiffRatio (t[tctr], *x, *l, y_ij);
00121           ix[tctr] = 10 * k + BATOLOWER;
00122           ILL_IFTRACE2 (":%d[%d](%la)\n", ix[tctr], tctr,
00123                         dbl_EGlpNumToLf (t[tctr]));
00124           tctr++;
00125         }
00126       }
00127     }
00128     else if ((dir == VINCREASE && dbl_EGlpNumIsLessZero (y_ij)) ||
00129              (dir == VDECREASE && dbl_EGlpNumIsGreatZero (y_ij)))
00130     {
00131       if (dbl_EGlpNumIsLessZero (y_ij))
00132         dbl_EGlpNumSign (y_ij);
00133       ILL_IFTRACE2 (":%d", lp->bfeas[i]);
00134       if (lp->bfeas[i] < 0)
00135       {
00136         dbl_EGlpNumCopyDiffRatio (t[tctr], *l, *x, y_ij);
00137         ix[tctr] = 10 * k + BBTOLOWER;
00138         ILL_IFTRACE2 (":%d[%d](%la)\n", ix[tctr], tctr, dbl_EGlpNumToLf (t[tctr]));
00139         tctr++;
00140         if (dbl_EGlpNumIsNeqq (*u, dbl_INFTY))
00141         {
00142           dbl_EGlpNumCopyDiffRatio (t[tctr], *u, *x, y_ij);
00143           ix[tctr] = 10 * k + BBTOUPPER;
00144           ILL_IFTRACE2 (":%d[%d](%la)\n", ix[tctr], tctr,
00145                         dbl_EGlpNumToLf (t[tctr]));
00146           tctr++;
00147         }
00148       }
00149       else if (lp->bfeas[i] == 0)
00150       {
00151         if (dbl_EGlpNumIsNeqq (*u, dbl_INFTY))
00152         {
00153           dbl_EGlpNumCopyDiffRatio (t[tctr], *u, *x, y_ij);
00154           ix[tctr] = 10 * k + BBTOUPPER;
00155           ILL_IFTRACE2 (":%d[%d](%la)\n", ix[tctr], tctr,
00156                         dbl_EGlpNumToLf (t[tctr]));
00157           tctr++;
00158         }
00159       }
00160     }
00161   }
00162   if (tctr == 0)
00163   {
00164     rs->ratio_stat = RATIO_FAILED;
00165     ILL_CLEANUP;
00166   }
00167 
00168   for (i = 0; i < tctr; i++)
00169     perm[i] = i;
00170   dbl_ILLutil_EGlpNum_perm_quicksort (perm, t, tctr);
00171 
00172   dbl_EGlpNumZero (lp->upd.c_obj);
00173   dbl_EGlpNumCopy (rcost, lp->pIdz[eindex]);
00174   ILL_IFTRACE2 ("\n%s:%d:%lf", __func__, tctr, dbl_EGlpNumToLf (rcost));
00175   for (i = 0; i < tctr; i++)
00176   {
00177     dbl_EGlpNumCopy (t_i, t[perm[i]]);
00178     dbl_EGlpNumCopy (ntmp, t_i);
00179     dbl_EGlpNumSubTo (ntmp, delta);
00180     dbl_EGlpNumAddInnProdTo (lp->upd.c_obj, ntmp, rcost);
00181     dbl_EGlpNumCopy (delta, t_i);
00182     ILL_IFTRACE2 (":%d:%lf", perm[i], dbl_EGlpNumToLf (delta));
00183      /*HHH*/ cbnd = ix[perm[i]] % 10;
00184     if (cbnd != BBOUND)
00185     {
00186       k = ix[perm[i]] / 10;
00187       dbl_EGlpNumCopy (y_ij, lp->yjz.coef[k]);
00188       indx = lp->yjz.indx[k];
00189       ILL_IFTRACE2 (":%d", indx);
00190     }
00191 
00192     switch (cbnd)
00193     {
00194     case BBOUND:
00195       rs->ratio_stat = RATIO_NOBCHANGE;
00196       dbl_EGlpNumCopy (rs->tz, t_i);
00197       if (dir != VINCREASE)
00198         dbl_EGlpNumSign (rs->tz);
00199       ILL_CLEANUP;
00200 
00201     case BATOLOWER:
00202     case BATOUPPER:
00203       dbl_EGlpNumAddTo (rcost, y_ij);
00204       break;
00205     case BBTOLOWER:
00206     case BBTOUPPER:
00207       dbl_EGlpNumSubTo (rcost, y_ij);
00208       break;
00209     }
00210     dbl_EGlpNumCopyNeg (nrcost, rcost);
00211     if ((dir == VINCREASE && dbl_EGlpNumIsLeq (nrcost, *dftol)) ||
00212         (dir == VDECREASE && dbl_EGlpNumIsLeq (rcost, *dftol)))
00213     {
00214       /* change 5 to -1 if t_i > 0 is required below */
00215       if (dbl_EGlpNumIsLessZero (t_i) && i > 5)
00216       {
00217         /* printf ("pIhell %.5f %d\n", t_i, i); */
00218         dbl_EGlpNumDivUiTo (t_i, 2);
00219         rs->ratio_stat = RATIO_NEGATIVE;
00220         dbl_EGlpNumZero (rs->tz);
00221         ILL_CLEANUP;
00222       }
00223       rs->lindex = indx;
00224       rs->ratio_stat = RATIO_BCHANGE;
00225       if (cbnd == BATOLOWER || cbnd == BBTOLOWER)
00226         rs->lvstat = STAT_LOWER;
00227       else
00228         rs->lvstat = STAT_UPPER;
00229 
00230       dbl_EGlpNumCopy (rs->pivotval, y_ij);
00231       dbl_EGlpNumCopy (rs->tz, t_i);
00232       if (dir != VINCREASE)
00233         dbl_EGlpNumSign (rs->tz);
00234       ILL_CLEANUP;
00235     }
00236   }
00237 
00238 CLEANUP:
00239   dbl_ILLfct_update_counts (lp, CNT_PIPIV, 0, rs->pivotval);
00240   ILL_IFTRACE2 (":tctr %d:%d\n", tctr, rs->ratio_stat);
00241   lp->upd.tctr = tctr;
00242   lp->upd.i = i;
00243   dbl_EGlpNumCopy (lp->upd.tz, t_i);
00244   dbl_EGlpNumCopy (lp->upd.piv, rs->pivotval);
00245   if (dir == VDECREASE)
00246     dbl_EGlpNumSign (lp->upd.c_obj);
00247   if (rs->lindex != -1)
00248     lp->upd.fs = lp->bfeas[rs->lindex];
00249   dbl_EGlpNumClearVar (t_i);
00250   dbl_EGlpNumClearVar (delta);
00251   dbl_EGlpNumClearVar (y_ij);
00252   dbl_EGlpNumClearVar (rcost);
00253   dbl_EGlpNumClearVar (nrcost);
00254   dbl_EGlpNumClearVar (ntmp);
00255 }
00256 
00257 void dbl_ILLratio_pII_test (
00258   dbl_lpinfo * lp,
00259   int eindex,
00260   int dir,
00261   dbl_ratio_res * rs)
00262 {
00263   int i, k, indx, col, ecol;
00264   double *x, *l, *u, t_max, ayi_max, yi_max, ay_ij, y_ij, t_i, t_z;
00265   double *pivtol = &(lp->tol->pivot_tol);
00266   double *pftol = &(lp->tol->pfeas_tol);
00267 
00268   dbl_EGlpNumInitVar (y_ij);
00269   dbl_EGlpNumInitVar (ay_ij);
00270   dbl_EGlpNumInitVar (t_i);
00271   dbl_EGlpNumInitVar (t_z);
00272   dbl_EGlpNumInitVar (t_max);
00273   dbl_EGlpNumInitVar (yi_max);
00274   dbl_EGlpNumInitVar (ayi_max);
00275    /*HHH*/ rs->boundch = 0;
00276   rs->lindex = -1;
00277   dbl_EGlpNumZero (rs->tz);
00278   rs->ratio_stat = RATIO_FAILED;
00279   rs->lvstat = -1;
00280   dbl_EGlpNumZero (rs->pivotval);
00281   dbl_EGlpNumZero (rs->lbound);
00282   ecol = lp->nbaz[eindex];
00283 
00284   for (k = 0, dbl_EGlpNumCopy (t_max, dbl_INFTY); k < lp->yjz.nzcnt; k++)
00285   {
00286     dbl_EGlpNumCopy (y_ij, lp->yjz.coef[k]);
00287     dbl_EGlpNumCopyAbs (ay_ij, y_ij);
00288     if (!dbl_EGlpNumIsNeqZero (y_ij, *pivtol))
00289       continue;
00290 
00291     dbl_EGlpNumCopy (t_i, dbl_INFTY);
00292     i = lp->yjz.indx[k];
00293     x = &(lp->xbz[i]);
00294     col = lp->baz[i];
00295     l = &(lp->lz[col]);
00296     u = &(lp->uz[col]);
00297 
00298     if ((dir == VINCREASE && dbl_EGlpNumIsGreatZero (y_ij)) ||
00299         (dir == VDECREASE && dbl_EGlpNumIsLessZero (y_ij)))
00300     {
00301       if (dbl_EGlpNumIsNeqq (*l, dbl_NINFTY))
00302       {
00303         dbl_EGlpNumCopyDiff (t_i, *x, *l);
00304         dbl_EGlpNumAddTo (t_i, *pftol);
00305         dbl_EGlpNumDivTo (t_i, ay_ij);
00306       }
00307     }
00308     else if ((dir == VINCREASE && dbl_EGlpNumIsLessZero (y_ij)) ||
00309              (dir == VDECREASE && dbl_EGlpNumIsGreatZero (y_ij)))
00310     {
00311       if (dbl_EGlpNumIsNeqq (*u, dbl_INFTY))
00312       {
00313         dbl_EGlpNumCopySum (t_i, *u, *pftol);
00314         dbl_EGlpNumSubTo (t_i, *x);
00315         dbl_EGlpNumDivTo (t_i, ay_ij);
00316       }
00317     }
00318     if (dbl_EGlpNumIsEqqual (t_i, dbl_INFTY))
00319       continue;
00320 
00321     if (dbl_EGlpNumIsLess (t_i, t_max))
00322     {
00323       /*HHH tind = i; yval = fabs (y_ij); tval = t_i - pftol/fabs(y_ij); */
00324       dbl_EGlpNumCopy (t_max, t_i);
00325     }
00326   }
00327   /* we use yi_max as temporal variable here */
00328   dbl_EGlpNumCopyDiff (yi_max, lp->uz[ecol], lp->lz[ecol]);
00329   if (lp->vtype[ecol] == VBOUNDED && dbl_EGlpNumIsLeq (yi_max, t_max))
00330   {
00331 
00332     dbl_EGlpNumCopy (t_max, yi_max);
00333     rs->ratio_stat = RATIO_NOBCHANGE;
00334     dbl_EGlpNumCopy (rs->tz, t_max);
00335     if (dir != VINCREASE)
00336       dbl_EGlpNumSign (rs->tz);
00337     ILL_CLEANUP;
00338   }
00339 
00340   if (dbl_EGlpNumIsLeq (dbl_INFTY, t_max))
00341   {
00342     rs->ratio_stat = RATIO_UNBOUNDED;
00343     ILL_CLEANUP;
00344   }
00345   /*if (dbl_EGlpNumIsLess (t_max, dbl_zeroLpNum))
00346    * printf ("pIIhell\n");
00347    */
00348   indx = -1;
00349   dbl_EGlpNumZero (t_z);
00350   dbl_EGlpNumZero (yi_max);
00351   dbl_EGlpNumZero (ayi_max);
00352   ILL_IFTRACE2 (":%d", lp->yjz.nzcnt);
00353   for (k = 0; k < lp->yjz.nzcnt; k++)
00354   {
00355     dbl_EGlpNumCopy (y_ij, lp->yjz.coef[k]);
00356     dbl_EGlpNumCopyAbs (ay_ij, y_ij);
00357     if (!dbl_EGlpNumIsNeqZero (y_ij, *pivtol))
00358       continue;
00359 
00360     dbl_EGlpNumCopy (t_i, dbl_INFTY);
00361     i = lp->yjz.indx[k];
00362     x = &(lp->xbz[i]);
00363     col = lp->baz[i];
00364     l = &(lp->lz[col]);
00365     u = &(lp->uz[col]);
00366 
00367     if ((dir == VINCREASE && dbl_EGlpNumIsGreatZero (y_ij)) ||
00368         (dir == VDECREASE && dbl_EGlpNumIsLessZero (y_ij)))
00369     {
00370       if (dbl_EGlpNumIsNeqq (*l, dbl_NINFTY))
00371         dbl_EGlpNumCopyDiffRatio (t_i, *x, *l, ay_ij);
00372     }
00373     else if ((dir == VINCREASE && dbl_EGlpNumIsLessZero (y_ij)) ||
00374              (dir == VDECREASE && dbl_EGlpNumIsGreatZero (y_ij)))
00375     {
00376       if (dbl_EGlpNumIsNeqq (*u, dbl_INFTY))
00377         dbl_EGlpNumCopyDiffRatio (t_i, *u, *x, ay_ij);
00378     }
00379 
00380     if (dbl_EGlpNumIsLeq (t_i, t_max))
00381     {
00382       if (dbl_EGlpNumIsLess (ayi_max, ay_ij))
00383       {
00384         dbl_EGlpNumCopy (yi_max, y_ij);
00385         dbl_EGlpNumCopy (ayi_max, ay_ij);
00386         indx = i;
00387         dbl_EGlpNumCopy (t_z, t_i);
00388         ILL_IFTRACE2 (":%d:%lf:%lf:%lf:%lf", indx, dbl_EGlpNumToLf (t_i),
00389                       dbl_EGlpNumToLf (t_max), dbl_EGlpNumToLf (ayi_max),
00390                       dbl_EGlpNumToLf (ay_ij));
00391       }
00392     }
00393   }
00394 
00395   if (indx < 0)
00396   {
00397     rs->ratio_stat = RATIO_FAILED;
00398   }
00399   else
00400   {
00401     /*
00402      * if (tind != rs->lindex){
00403      * HHHprintf ("tmax %e tval = %e yval = %e tind = %d\n", t_max, tval, yval, tind);
00404      * HHHprintf ("h tval = %e yval = %e tind = %d\n",rs->tz, yi_max, rs->lindex);
00405      * }
00406      */
00407     ILL_IFTRACE2 (":%d", indx);
00408     rs->lindex = indx;
00409     dbl_EGlpNumCopy (rs->tz, t_z);
00410     dbl_EGlpNumCopy (rs->pivotval, yi_max);
00411     rs->ratio_stat = RATIO_BCHANGE;
00412 
00413     if (dir == VINCREASE)
00414       rs->lvstat =
00415         (dbl_EGlpNumIsGreatZero (yi_max)) ? STAT_LOWER : STAT_UPPER;
00416     else
00417       rs->lvstat =
00418         (dbl_EGlpNumIsGreatZero (yi_max)) ? STAT_UPPER : STAT_LOWER;
00419 
00420     if (dbl_EGlpNumIsLessZero (rs->tz))
00421     {
00422       ILL_IFTRACE2 ("need to change bound, tz=%la\n", dbl_EGlpNumToLf (rs->tz));
00423       dbl_EGlpNumCopyAbs (rs->tz, t_max);
00424       dbl_EGlpNumDivUiTo (rs->tz, 10);
00425       rs->boundch = 1;
00426       dbl_EGlpNumCopy (rs->lbound, lp->xbz[rs->lindex]);
00427       if (rs->lvstat == STAT_LOWER)
00428         dbl_EGlpNumSubInnProdTo (rs->lbound, rs->tz, ayi_max);
00429       else
00430         dbl_EGlpNumAddInnProdTo (rs->lbound, rs->tz, ayi_max);
00431     }
00432     if (dir == VDECREASE)
00433       dbl_EGlpNumSign (rs->tz);
00434   }
00435 CLEANUP:
00436   dbl_ILLfct_update_counts (lp, CNT_PIIPIV, 0, rs->pivotval);
00437   dbl_EGlpNumClearVar (y_ij);
00438   dbl_EGlpNumClearVar (ay_ij);
00439   dbl_EGlpNumClearVar (t_i);
00440   dbl_EGlpNumClearVar (t_z);
00441   dbl_EGlpNumClearVar (t_max);
00442   dbl_EGlpNumClearVar (yi_max);
00443   dbl_EGlpNumClearVar (ayi_max);
00444 }
00445 
00446 #define dbl_GET_XY_DRATIOTEST \
00447       if (lp->vstat[col] == STAT_UPPER){ \
00448         dbl_EGlpNumCopyNeg(x,lp->dz[j]);\
00449         dbl_EGlpNumCopy(y, *zAj);\
00450       } \
00451       else{ \
00452          dbl_EGlpNumCopy(x, lp->dz[j]); \
00453          dbl_EGlpNumCopyNeg(y, *zAj);\
00454       } \
00455       if (lvstat == STAT_UPPER) \
00456          dbl_EGlpNumSign(y);
00457 
00458 
00459 void dbl_ILLratio_dI_test (
00460   dbl_lpinfo * lp,
00461   int lindex,
00462   int lvstat,
00463   dbl_ratio_res * rs)
00464 {
00465   int j = 0, k;
00466   int col;
00467   int cbnd, indx;
00468   int tctr = 0;
00469   int *perm = lp->upd.perm;
00470   int *ix = lp->upd.ix;
00471   double *t = lp->upd.t;
00472   double *zAj, x, y, t_j, theta, rcost, delta;
00473   double *pftol = &(lp->tol->ip_tol);
00474   double *pivtol = &(lp->tol->pivot_tol);
00475 
00476   dbl_EGlpNumInitVar (x);
00477   dbl_EGlpNumInitVar (y);
00478   dbl_EGlpNumInitVar (t_j);
00479   dbl_EGlpNumInitVar (theta);
00480   dbl_EGlpNumInitVar (rcost);
00481   dbl_EGlpNumInitVar (delta);
00482   dbl_EGlpNumZero (delta);
00483   dbl_EGlpNumZero (t_j);
00484   dbl_EGlpNumZero (rs->tz);
00485    /*HHH*/ rs->eindex = -1;
00486   rs->ratio_stat = RATIO_FAILED;
00487   dbl_EGlpNumZero (rs->pivotval);
00488 
00489   for (k = 0; k < lp->zA.nzcnt; k++)
00490   {
00491     zAj = &(lp->zA.coef[k]);
00492     if (!dbl_EGlpNumIsNeqZero (*zAj, *pivtol))
00493       continue;
00494 
00495     dbl_EGlpNumCopy (t_j, dbl_INFTY);
00496     j = lp->zA.indx[k];
00497     col = lp->nbaz[j];
00498 
00499     if (lp->vtype[col] == VARTIFICIAL || lp->vtype[col] == VFIXED)
00500       continue;
00501 
00502     dbl_GET_XY_DRATIOTEST;
00503 
00504     if (dbl_EGlpNumIsLessZero (y))
00505     {
00506       if (lp->dfeas[j] != 0 && lp->vstat[col] != STAT_ZERO)
00507       {
00508         dbl_EGlpNumCopyFrac (t[tctr], x, y);
00509         ix[tctr] = 10 * k + BBTOLOWER;
00510         tctr++;
00511       }
00512       else if (lp->vstat[col] == STAT_ZERO)
00513       {
00514         if (lp->dfeas[j] < 0)
00515         {
00516           dbl_EGlpNumCopyFrac (t[tctr], x, y);
00517           ix[tctr] = 10 * k + BBTOLOWER;
00518           tctr++;
00519         }
00520         if (lp->dfeas[j] <= 0)
00521         {
00522           dbl_EGlpNumCopyFrac (t[tctr], x, y);
00523           ix[tctr] = 10 * k + BBTOUPPER;
00524           tctr++;
00525         }
00526       }
00527     }
00528     else
00529     {
00530       if (lp->dfeas[j] > 0)
00531       {
00532         if (lp->vstat[col] == STAT_ZERO)
00533         {
00534           dbl_EGlpNumCopyFrac (t[tctr], x, y);
00535           ix[tctr] = 10 * k + BATOUPPER;
00536           tctr++;
00537           dbl_EGlpNumCopyFrac (t[tctr], x, y);
00538           ix[tctr] = 10 * k + BATOLOWER;
00539           tctr++;
00540         }
00541       }
00542       else if (lp->dfeas[j] == 0)
00543       {
00544         dbl_EGlpNumCopyFrac (t[tctr], x, y);
00545         if (lp->vtype[col] == VBOUNDED)
00546           ix[tctr] = 10 * k + BSKIP;
00547         else
00548           ix[tctr] = 10 * k + BATOLOWER;
00549         tctr++;
00550       }
00551     }
00552   }
00553 
00554   if (tctr == 0)
00555   {
00556     rs->ratio_stat = RATIO_FAILED;
00557     ILL_CLEANUP;
00558   }
00559 
00560   for (j = 0; j < tctr; j++)
00561     perm[j] = j;
00562   dbl_ILLutil_EGlpNum_perm_quicksort (perm, t, tctr);
00563 
00564   dbl_EGlpNumZero (lp->upd.c_obj);
00565   dbl_EGlpNumCopy (rcost, lp->xbz[lindex]);
00566   if (lvstat == STAT_LOWER)
00567     dbl_EGlpNumSign (rcost);
00568   for (j = 0; j < tctr; j++)
00569   {
00570     cbnd = ix[perm[j]] % 10;
00571     if (cbnd == BSKIP)
00572       continue;
00573 
00574     dbl_EGlpNumCopy (t_j, t[perm[j]]);
00575     dbl_EGlpNumCopy (x, t_j);
00576     dbl_EGlpNumSubTo (x, delta);
00577     dbl_EGlpNumAddInnProdTo (lp->upd.c_obj, x, rcost);
00578     dbl_EGlpNumCopy (delta, t_j);
00579     k = ix[perm[j]] / 10;
00580     zAj = &(lp->zA.coef[k]);
00581     indx = lp->zA.indx[k];
00582 
00583     if (lp->vstat[lp->nbaz[indx]] == STAT_LOWER
00584         || lp->vstat[lp->nbaz[indx]] == STAT_ZERO)
00585       dbl_EGlpNumCopyNeg (theta, *zAj);
00586     else
00587       dbl_EGlpNumCopy (theta, *zAj);
00588 
00589     if (lvstat == STAT_UPPER)
00590       dbl_EGlpNumSign (theta);
00591 
00592     switch (cbnd)
00593     {
00594     case BATOLOWER:
00595     case BATOUPPER:
00596       dbl_EGlpNumSubTo (rcost, theta);
00597       break;
00598     case BBTOLOWER:
00599     case BBTOUPPER:
00600       dbl_EGlpNumAddTo (rcost, theta);
00601       break;
00602     }
00603     if (dbl_EGlpNumIsLeq (rcost, *pftol))
00604     {
00605       /* if (t_j < 0.0) printf ("dIhell\n"); */
00606       rs->eindex = indx;
00607       dbl_EGlpNumCopy (rs->tz, t_j);
00608       dbl_EGlpNumCopy (rs->pivotval, *zAj);
00609       rs->ratio_stat = RATIO_BCHANGE;
00610       ILL_CLEANUP;
00611     }
00612   }
00613 
00614 CLEANUP:
00615   dbl_ILLfct_update_counts (lp, CNT_DIPIV, 0, rs->pivotval);
00616   ILL_IFTRACE2 ("%s:tctr %d\n", __func__, tctr);
00617   lp->upd.tctr = tctr;
00618   lp->upd.i = j;
00619   dbl_EGlpNumCopyAbs (lp->upd.tz, t_j);
00620   dbl_EGlpNumCopy (lp->upd.piv, rs->pivotval);
00621   if (rs->eindex != -1)
00622     lp->upd.fs = lp->dfeas[rs->eindex];
00623   dbl_EGlpNumClearVar (x);
00624   dbl_EGlpNumClearVar (y);
00625   dbl_EGlpNumClearVar (t_j);
00626   dbl_EGlpNumClearVar (theta);
00627   dbl_EGlpNumClearVar (rcost);
00628   dbl_EGlpNumClearVar (delta);
00629 }
00630 
00631 void dbl_ILLratio_dII_test (
00632   dbl_lpinfo * lp,
00633   int lindex,
00634   int lvstat,
00635   dbl_ratio_res * rs)
00636 {
00637   int j, k, indx;
00638   int col, ecol;
00639   double *zAj, azAj, az_max, x, y, t_j, z_max, t_max, t_z;
00640   double *dftol = &(lp->tol->dfeas_tol);
00641   double *pivtol = &(lp->tol->pivot_tol);
00642 
00643   dbl_EGlpNumInitVar (x);
00644   dbl_EGlpNumInitVar (y);
00645   dbl_EGlpNumInitVar (t_j);
00646   dbl_EGlpNumInitVar (z_max);
00647   dbl_EGlpNumInitVar (t_max);
00648   dbl_EGlpNumInitVar (az_max);
00649   dbl_EGlpNumInitVar (azAj);
00650   dbl_EGlpNumInitVar (t_z);
00651   dbl_EGlpNumZero (t_j);
00652   rs->coeffch = 0;
00653   dbl_EGlpNumZero (rs->ecoeff);
00654   rs->eindex = -1;
00655   rs->ratio_stat = RATIO_FAILED;
00656   ILL_IFTRACE2 ("%s:tctr %d\n", __func__, 0);
00657   lp->upd.tctr = 0;
00658   dbl_EGlpNumZero (lp->upd.dty);
00659   for (k = 0, dbl_EGlpNumCopy (t_max, dbl_INFTY); k < lp->zA.nzcnt; k++)
00660   {
00661     zAj = &(lp->zA.coef[k]);
00662     if (!dbl_EGlpNumIsNeqZero (*zAj, *pivtol))
00663       continue;
00664 
00665     dbl_EGlpNumCopy (t_j, dbl_INFTY);
00666     j = lp->zA.indx[k];
00667     col = lp->nbaz[j];
00668 
00669     if (lp->vtype[col] == VARTIFICIAL || lp->vtype[col] == VFIXED)
00670       continue;
00671 
00672     dbl_GET_XY_DRATIOTEST;
00673 
00674 //#warning adding/substracting tolerances to used value, is it rigght?
00675     if (dbl_EGlpNumIsGreatZero (y))
00676     {
00677       //t_j = (x + dftol) / y;
00678       dbl_EGlpNumCopySum (t_j, x, *dftol);
00679       dbl_EGlpNumDivTo (t_j, y);
00680     }
00681     else
00682     {
00683 //#warning adding/substracting tolerances to used value, is it rigght?
00684       if (lp->vstat[col] == STAT_ZERO)
00685         dbl_EGlpNumCopyDiffRatio (t_j, x, *dftol, y);
00686     }
00687     //if (t_j == dbl_INFTY)
00688     if (dbl_EGlpNumIsEqqual (t_j, dbl_INFTY))
00689       continue;
00690 
00691     if (dbl_EGlpNumIsLess (t_j, t_max))
00692       dbl_EGlpNumCopy (t_max, t_j);
00693   }
00694 
00695   if (dbl_EGlpNumIsLeq (dbl_INFTY, t_max))
00696   {
00697     rs->ratio_stat = RATIO_UNBOUNDED;
00698     ILL_CLEANUP;
00699   }
00700   /* if (t_max < 0.0) printf ("dIIhell\n"); */
00701 
00702   indx = -1;
00703   dbl_EGlpNumZero (t_z);
00704   dbl_EGlpNumZero (z_max);
00705   dbl_EGlpNumZero (az_max);
00706 
00707   for (k = 0; k < lp->zA.nzcnt; k++)
00708   {
00709     zAj = &(lp->zA.coef[k]);
00710     dbl_EGlpNumCopyAbs (azAj, *zAj);
00711     if (!dbl_EGlpNumIsNeqZero (*zAj, *pivtol))
00712       continue;
00713 
00714     dbl_EGlpNumCopy (t_j, dbl_INFTY);
00715     j = lp->zA.indx[k];
00716     col = lp->nbaz[j];
00717 
00718     if (lp->vtype[col] == VARTIFICIAL || lp->vtype[col] == VFIXED)
00719       continue;
00720 
00721     dbl_GET_XY_DRATIOTEST;
00722 
00723     if (dbl_EGlpNumIsGreatZero (y) || lp->vstat[col] == STAT_ZERO)
00724       dbl_EGlpNumCopyFrac (t_j, x, y);
00725 
00726     if (dbl_EGlpNumIsLeq (t_j, t_max) && (dbl_EGlpNumIsLess (az_max, azAj)))
00727     {
00728       dbl_EGlpNumCopy (z_max, *zAj);
00729       dbl_EGlpNumCopy (az_max, azAj);
00730       indx = j;
00731       dbl_EGlpNumCopy (t_z, t_j);
00732     }
00733   }
00734 
00735 
00736   if (indx < 0)
00737   {
00738     rs->ratio_stat = RATIO_FAILED;
00739   }
00740   else
00741   {
00742     rs->eindex = indx;
00743     dbl_EGlpNumCopy (rs->tz, t_z);
00744     dbl_EGlpNumCopy (rs->pivotval, z_max);
00745     rs->ratio_stat = RATIO_BCHANGE;
00746 
00747     if (dbl_EGlpNumIsLessZero (rs->tz))
00748     {
00749       dbl_EGlpNumCopyAbs (rs->tz, t_max);
00750       dbl_EGlpNumDivUiTo (rs->tz, 20);
00751       rs->coeffch = 1;
00752       ecol = lp->nbaz[indx];
00753       dbl_EGlpNumCopyDiff (rs->ecoeff, lp->cz[ecol], lp->dz[indx]);
00754       switch (lp->vstat[ecol])
00755       {
00756       case STAT_LOWER:
00757         dbl_EGlpNumAddInnProdTo (rs->ecoeff, rs->tz, az_max);
00758         break;
00759       case STAT_UPPER:
00760         dbl_EGlpNumSubInnProdTo (rs->ecoeff, rs->tz, az_max);
00761         break;
00762       default:
00763         dbl_EGlpNumZero (rs->tz);
00764         break;
00765       }
00766     }
00767   }
00768 
00769 CLEANUP:
00770   dbl_ILLfct_update_counts (lp, CNT_DIIPIV, 0, rs->pivotval);
00771   dbl_EGlpNumCopy (lp->upd.piv, rs->pivotval);
00772   dbl_EGlpNumClearVar (x);
00773   dbl_EGlpNumClearVar (y);
00774   dbl_EGlpNumClearVar (t_j);
00775   dbl_EGlpNumClearVar (z_max);
00776   dbl_EGlpNumClearVar (t_max);
00777   dbl_EGlpNumClearVar (t_z);
00778   dbl_EGlpNumClearVar (az_max);
00779   dbl_EGlpNumClearVar (azAj);
00780 }
00781 
00782 void dbl_ILLratio_longdII_test (
00783   dbl_lpinfo * lp,
00784   int lindex,
00785   int lvstat,
00786   dbl_ratio_res * rs)
00787 {
00788   int j, k, indx = 0, tctr = 0;
00789   int col, ecol;
00790   int vs, bnd_exist = 0;
00791   int *perm = lp->upd.perm;
00792   int *ix = lp->upd.ix;
00793   int b_indx = -1;
00794   double *t = lp->upd.t;
00795   double *l,
00796     *u,
00797     *xb,
00798     *zAj = 0,
00799     x,
00800     y,
00801     t_j,
00802     z_max,
00803     t_max, t_z, theta, rcost, delta, zb_val, tb_val, az_max, azb_val, azAj;
00804   double *pftol = &(lp->tol->pfeas_tol);
00805   double *dftol = &(lp->tol->dfeas_tol);
00806   double *pivtol = &(lp->tol->pivot_tol);
00807 
00808   dbl_EGlpNumInitVar (x);
00809   dbl_EGlpNumInitVar (azAj);
00810   dbl_EGlpNumInitVar (y);
00811   dbl_EGlpNumInitVar (t_j);
00812   dbl_EGlpNumInitVar (z_max);
00813   dbl_EGlpNumInitVar (az_max);
00814   dbl_EGlpNumInitVar (t_max);
00815   dbl_EGlpNumInitVar (t_z);
00816   dbl_EGlpNumInitVar (theta);
00817   dbl_EGlpNumInitVar (rcost);
00818   dbl_EGlpNumInitVar (delta);
00819   dbl_EGlpNumInitVar (zb_val);
00820   dbl_EGlpNumInitVar (azb_val);
00821   dbl_EGlpNumInitVar (tb_val);
00822   dbl_EGlpNumZero (t_j);
00823   dbl_EGlpNumZero (delta);
00824   dbl_EGlpNumZero (zb_val);
00825   dbl_EGlpNumZero (azb_val);
00826   dbl_EGlpNumCopy (tb_val, dbl_NINFTY);
00827 //#warning not sure about THIS line
00828   dbl_EGlpNumZero (rs->pivotval);
00829 
00830   rs->coeffch = 0;
00831   rs->eindex = -1;
00832   rs->ratio_stat = RATIO_FAILED;
00833 
00834   ILL_IFTRACE2 ("%s:tctr %d\n", __func__, 0);
00835   lp->upd.tctr = 0;
00836   lp->upd.i = 0;
00837   dbl_EGlpNumZero (lp->upd.tz);
00838   dbl_EGlpNumZero (lp->upd.piv);
00839   dbl_EGlpNumZero (lp->upd.c_obj);
00840   dbl_EGlpNumZero (lp->upd.dty);
00841 
00842   xb = &(lp->xbz[lindex]);
00843   col = lp->baz[lindex];
00844   l = &(lp->lz[col]);
00845   u = &(lp->uz[col]);
00846   //rcost = (lvstat == STAT_LOWER) ? l - xb : xb - u;
00847   if (lvstat == STAT_LOWER)
00848     dbl_EGlpNumCopyDiff (rcost, *l, *xb);
00849   else
00850     dbl_EGlpNumCopyDiff (rcost, *xb, *u);
00851 
00852   for (k = 0, dbl_EGlpNumCopy (t_max, dbl_INFTY); k < lp->zA.nzcnt; k++)
00853   {
00854     zAj = &(lp->zA.coef[k]);
00855     if (!dbl_EGlpNumIsNeqZero (*zAj, *pivtol))
00856       continue;
00857 
00858     dbl_EGlpNumCopy (t_j, dbl_INFTY);
00859     j = lp->zA.indx[k];
00860     col = lp->nbaz[j];
00861 
00862     if (lp->vtype[col] == VARTIFICIAL || lp->vtype[col] == VFIXED)
00863       continue;
00864     if (lp->vtype[col] == VBOUNDED)
00865     {
00866       bnd_exist++;
00867       continue;
00868     }
00869 
00870     dbl_GET_XY_DRATIOTEST;
00871 
00872     if (dbl_EGlpNumIsGreatZero (y))
00873     {
00874       //t_j = (x + dftol) / y;
00875 //#warning Using tolerances to add to result, is it right?
00876       dbl_EGlpNumCopySum (t_j, x, *dftol);
00877       dbl_EGlpNumDivTo (t_j, y);
00878     }
00879     else
00880     {
00881       if (lp->vstat[col] == STAT_ZERO)
00882         dbl_EGlpNumCopyDiffRatio (t_j, x, *dftol, y);
00883     }
00884     if (dbl_EGlpNumIsEqqual (t_j, dbl_INFTY))
00885       continue;
00886 
00887     if (dbl_EGlpNumIsLess (t_j, t_max))
00888       dbl_EGlpNumCopy (t_max, t_j);
00889   }
00890   if (dbl_EGlpNumIsLessZero (t_max))
00891   {
00892     /*printf ("dIIhell, %.4f\n", t_max); */
00893     rs->ratio_stat = RATIO_NEGATIVE;
00894     ILL_CLEANUP;
00895   }
00896 
00897   if (bnd_exist == 0 && dbl_EGlpNumIsLeq (dbl_INFTY, t_max))
00898   {
00899     rs->ratio_stat = RATIO_UNBOUNDED;
00900     /*
00901      * printf ("x = %.8f, b = %.2f \n", lp->xbz[lindex], (lvstat == STAT_LOWER ) ? lp->lz[lp->baz[lindex]] : lp->uz[lp->baz[lindex]]);
00902      */
00903     ILL_CLEANUP;
00904   }
00905 
00906   if (bnd_exist != 0)
00907   {
00908     for (k = 0; k < lp->zA.nzcnt; k++)
00909     {
00910       zAj = &(lp->zA.coef[k]);
00911       if (!dbl_EGlpNumIsNeqZero (*zAj, *pivtol))
00912         continue;
00913 
00914       dbl_EGlpNumCopy (t_j, dbl_INFTY);
00915       j = lp->zA.indx[k];
00916       col = lp->nbaz[j];
00917 
00918       if (lp->vtype[col] != VBOUNDED)
00919         continue;
00920 
00921       dbl_GET_XY_DRATIOTEST;
00922 
00923       if (dbl_EGlpNumIsGreatZero (y))
00924       {
00925         dbl_EGlpNumCopyFrac (t_j, x, y);
00926         if (dbl_EGlpNumIsLeq (t_j, t_max))
00927         {
00928           dbl_EGlpNumCopy (t[tctr], t_j);
00929           ix[tctr] = k;
00930           tctr++;
00931         }
00932       }
00933     }
00934   }
00935 
00936   if (tctr != 0)
00937   {
00938     for (j = 0; j < tctr; j++)
00939       perm[j] = j;
00940     dbl_ILLutil_EGlpNum_perm_quicksort (perm, t, tctr);
00941 
00942     for (j = 0; j < tctr; j++)
00943     {
00944 
00945       dbl_EGlpNumCopy (t_j, t[perm[j]]);
00946       /* we use x as temporal storage */
00947       //lp->upd.c_obj += (t_j - delta) * rcost;
00948       dbl_EGlpNumCopy (x, t_j);
00949       dbl_EGlpNumSubTo (x, delta);
00950       dbl_EGlpNumAddInnProdTo (lp->upd.c_obj, x, rcost);
00951       dbl_EGlpNumCopy (delta, t_j);
00952        /*HHH*/ k = ix[perm[j]];
00953       zAj = &(lp->zA.coef[k]);
00954       indx = lp->zA.indx[k];
00955       col = lp->nbaz[indx];
00956       l = &(lp->lz[col]);
00957       u = &(lp->uz[col]);
00958       vs = lp->vstat[col];
00959       //theta = (vs == STAT_UPPER) ? (l - u) * zAj : (u - l) * zAj;
00960       dbl_EGlpNumCopyDiff (theta, *l, *u);
00961       dbl_EGlpNumMultTo (theta, *zAj);
00962       if (vs != STAT_UPPER)
00963         dbl_EGlpNumSign (theta);
00964       if (lvstat == STAT_LOWER)
00965         dbl_EGlpNumAddTo (rcost, theta);
00966       else
00967         dbl_EGlpNumSubTo (rcost, theta);
00968 
00969       if (dbl_EGlpNumIsLeq (rcost, *pftol))
00970       {
00971         rs->eindex = indx;
00972         dbl_EGlpNumCopy (rs->tz, t_j);
00973         dbl_EGlpNumCopy (rs->pivotval, *zAj);
00974         rs->ratio_stat = RATIO_BCHANGE;
00975 
00976         if (dbl_EGlpNumIsLessZero (rs->tz))
00977         {
00978           dbl_EGlpNumZero (rs->tz);
00979           rs->coeffch = 1;
00980           //rs->ecoeff = lp->cz[col] - lp->dz[indx];
00981           dbl_EGlpNumCopyDiff (rs->ecoeff, lp->cz[col], lp->dz[indx]);
00982           //lp->upd.c_obj += (rs->tz - delta) * rcost; note ts->tz == 0;
00983           dbl_EGlpNumSubInnProdTo (lp->upd.c_obj, delta, rcost);
00984         }
00985         ILL_IFTRACE2 ("%s:tctr %d\n", __func__, tctr);
00986         lp->upd.tctr = tctr;
00987         lp->upd.i = j;
00988         dbl_EGlpNumCopy (lp->upd.tz, rs->tz);
00989         ILL_CLEANUP;
00990       }
00991     }
00992     ILL_IFTRACE2 ("%s:tctr %d\n", __func__, tctr);
00993     lp->upd.tctr = tctr;
00994     lp->upd.i = tctr;
00995     dbl_EGlpNumCopy (lp->upd.tz, t_j);
00996     dbl_EGlpNumCopy (zb_val, *zAj);
00997     dbl_EGlpNumCopyAbs (azb_val, zb_val);
00998     dbl_EGlpNumCopy (tb_val, t_j);
00999     b_indx = indx;
01000   }
01001 
01002   if (bnd_exist != 0 && dbl_EGlpNumIsLeq (dbl_INFTY, t_max))
01003   {
01004     rs->ratio_stat = RATIO_UNBOUNDED;
01005     /* printf ("rcost: %.8f\n", rcost); */
01006     ILL_CLEANUP;
01007   }
01008 
01009   dbl_EGlpNumZero (z_max);
01010   dbl_EGlpNumZero (az_max);
01011   indx = -1;
01012   dbl_EGlpNumZero (t_z);
01013   for (k = 0; k < lp->zA.nzcnt; k++)
01014   {
01015     zAj = &(lp->zA.coef[k]);
01016     dbl_EGlpNumCopyAbs (azAj, *zAj);
01017     if (!dbl_EGlpNumIsNeqZero (*zAj, *pivtol))
01018       continue;
01019 
01020     dbl_EGlpNumCopy (t_j, dbl_INFTY);
01021     j = lp->zA.indx[k];
01022     col = lp->nbaz[j];
01023 
01024     if (lp->vtype[col] == VARTIFICIAL || lp->vtype[col] == VFIXED ||
01025         lp->vtype[col] == VBOUNDED)
01026       continue;
01027 
01028     dbl_GET_XY_DRATIOTEST;
01029 
01030     if (dbl_EGlpNumIsGreatZero (y) || lp->vstat[col] == STAT_ZERO)
01031       dbl_EGlpNumCopyFrac (t_j, x, y);
01032 
01033     if (dbl_EGlpNumIsLeq (t_j, t_max))
01034     {
01035       if (dbl_EGlpNumIsLess (az_max, azAj))
01036       {
01037         dbl_EGlpNumCopy (z_max, *zAj);
01038         dbl_EGlpNumCopy (az_max, azAj);
01039         indx = j;
01040         dbl_EGlpNumCopy (t_z, t_j);
01041       }
01042     }
01043   }
01044 
01045   if (indx < 0)
01046   {
01047     rs->ratio_stat = RATIO_FAILED;
01048     ILL_CLEANUP;
01049   }
01050   if ((tctr == 0) || (dbl_EGlpNumIsLessZero (tb_val)) ||
01051       (tctr != 0 && dbl_EGlpNumIsLeq (tb_val, t_z) &&
01052        dbl_EGlpNumIsLeq (azb_val, az_max)))
01053   {
01054     /* we use x as temporal vvariable */
01055     /* lp->upd.c_obj += (t_z - delta) * rcost; */
01056     dbl_EGlpNumCopyDiff (x, t_z, delta);
01057     dbl_EGlpNumAddInnProdTo (lp->upd.c_obj, x, rcost);
01058     dbl_EGlpNumCopy (delta, t_z);
01059     rs->eindex = indx;
01060     dbl_EGlpNumCopy (rs->tz, t_z);
01061     dbl_EGlpNumCopy (rs->pivotval, z_max);
01062     rs->ratio_stat = RATIO_BCHANGE;
01063   }
01064   /* For now */
01065   else if (tctr != 0)
01066   {
01067     rs->eindex = b_indx;
01068     dbl_EGlpNumCopy (rs->tz, tb_val);
01069     dbl_EGlpNumCopy (rs->pivotval, zb_val);
01070     rs->ratio_stat = RATIO_BCHANGE;
01071     lp->upd.i -= 1;
01072   }
01073 
01074   if (dbl_EGlpNumIsLessZero (rs->tz))
01075   {
01076     /* if (tctr != 0) printf ("despite long step\n"); */
01077     /* rs->tz = fabs (t_max / 20.0); */
01078     dbl_EGlpNumCopyAbs (rs->tz, t_max);
01079     dbl_EGlpNumDivUiTo (rs->tz, 20);
01080     rs->coeffch = 1;
01081 
01082     ecol = lp->nbaz[indx];
01083     if (lp->vstat[ecol] == STAT_LOWER)
01084     {
01085       /*rs->ecoeff = lp->cz[ecol] - lp->dz[indx] + rs->tz * fabs (z_max); */
01086       dbl_EGlpNumCopy (rs->ecoeff, az_max);
01087       dbl_EGlpNumMultTo (rs->ecoeff, rs->tz);
01088       dbl_EGlpNumAddTo (rs->ecoeff, lp->cz[ecol]);
01089       dbl_EGlpNumSubTo (rs->ecoeff, lp->dz[indx]);
01090     }
01091     else if (lp->vstat[ecol] == STAT_UPPER)
01092     {
01093       /*rs->ecoeff = lp->cz[ecol] - lp->dz[indx] - rs->tz * fabs (z_max); */
01094       dbl_EGlpNumCopy (rs->ecoeff, az_max);
01095       dbl_EGlpNumMultTo (rs->ecoeff, rs->tz);
01096       dbl_EGlpNumSign (rs->ecoeff);
01097       dbl_EGlpNumAddTo (rs->ecoeff, lp->cz[ecol]);
01098       dbl_EGlpNumSubTo (rs->ecoeff, lp->dz[indx]);
01099     }
01100     else
01101     {
01102       /*rs->ecoeff = lp->cz[ecol] - lp->dz[indx]; */
01103       dbl_EGlpNumCopyDiff (rs->ecoeff, lp->cz[ecol], lp->dz[indx]);
01104       dbl_EGlpNumZero (rs->tz);
01105     }
01106     /* we use x as temporal storage */
01107     /*lp->upd.c_obj += (rs->tz - delta) * rcost; */
01108     dbl_EGlpNumCopy (x, rs->tz);
01109     dbl_EGlpNumSubTo (x, delta);
01110     dbl_EGlpNumAddInnProdTo (lp->upd.c_obj, x, rcost);
01111   }
01112 
01113 CLEANUP:
01114   dbl_ILLfct_update_counts (lp, CNT_DIIPIV, 0, rs->pivotval);
01115   dbl_EGlpNumCopy (lp->upd.piv, rs->pivotval);
01116   dbl_EGlpNumClearVar (x);
01117   dbl_EGlpNumClearVar (y);
01118   dbl_EGlpNumClearVar (t_j);
01119   dbl_EGlpNumClearVar (z_max);
01120   dbl_EGlpNumClearVar (az_max);
01121   dbl_EGlpNumClearVar (t_max);
01122   dbl_EGlpNumClearVar (t_z);
01123   dbl_EGlpNumClearVar (theta);
01124   dbl_EGlpNumClearVar (rcost);
01125   dbl_EGlpNumClearVar (delta);
01126   dbl_EGlpNumClearVar (zb_val);
01127   dbl_EGlpNumClearVar (azb_val);
01128   dbl_EGlpNumClearVar (tb_val);
01129   dbl_EGlpNumClearVar (azAj);
01130 }
01131 
01132 void dbl_ILLratio_pivotin_test (
01133   dbl_lpinfo * lp,
01134   int *rlist,
01135   int rcnt,
01136   dbl_ratio_res * rs)
01137 {
01138   int i, k, col;
01139   double *x, *l, *u;
01140   double ay_ij,
01141     at_i, at_l, at_u, ayi_max, y_ij, t_i, t_l, t_u, t_max, yi_max;
01142   double *pivtol = &(lp->tol->pivot_tol);
01143 
01144   if (rcnt <= 0 || rs == NULL)
01145     return;
01146   dbl_EGlpNumInitVar (ay_ij);
01147   dbl_EGlpNumInitVar (at_i);
01148   dbl_EGlpNumInitVar (at_l);
01149   dbl_EGlpNumInitVar (at_u);
01150   dbl_EGlpNumInitVar (ayi_max);
01151   dbl_EGlpNumInitVar (t_max);
01152   dbl_EGlpNumInitVar (y_ij);
01153   dbl_EGlpNumInitVar (t_i);
01154   dbl_EGlpNumInitVar (t_l);
01155   dbl_EGlpNumInitVar (t_u);
01156   dbl_EGlpNumInitVar (yi_max);
01157   rs->boundch = 0;
01158   rs->lindex = -1;
01159   dbl_EGlpNumZero (rs->tz);
01160   rs->ratio_stat = RATIO_FAILED;
01161   rs->lvstat = -1;
01162   dbl_EGlpNumZero (rs->pivotval);
01163   dbl_EGlpNumZero (rs->lbound);
01164 
01165   for (i = 0; i < rcnt; i++)
01166     lp->iwork[rlist[i]] = 1;
01167 
01168   for (k = 0, dbl_EGlpNumCopy (t_max, dbl_INFTY); k < lp->yjz.nzcnt; k++)
01169   {
01170     dbl_EGlpNumCopy (y_ij, lp->yjz.coef[k]);
01171     if (!dbl_EGlpNumIsNeqZero (y_ij, *pivtol))
01172       continue;
01173 
01174     i = lp->yjz.indx[k];
01175     if (lp->iwork[lp->baz[i]] == 1)
01176       continue;
01177     x = &(lp->xbz[i]);
01178     col = lp->baz[i];
01179     l = &(lp->lz[col]);
01180     u = &(lp->uz[col]);
01181     dbl_EGlpNumCopy (t_u, dbl_INFTY);
01182     dbl_EGlpNumCopy (at_u, dbl_INFTY);
01183     dbl_EGlpNumCopy (t_l, dbl_NINFTY);
01184     dbl_EGlpNumCopy (at_l, dbl_INFTY);
01185 
01186     if (dbl_EGlpNumIsNeqq (*l, dbl_NINFTY))
01187     {
01188       dbl_EGlpNumCopyDiffRatio (t_l, *x, *l, y_ij);
01189       dbl_EGlpNumCopyAbs (at_l, t_l);
01190       if (dbl_EGlpNumIsLess (at_l, t_max))
01191         dbl_EGlpNumCopy (t_max, at_l);
01192     }
01193     if (dbl_EGlpNumIsNeqq (*u, dbl_INFTY))
01194     {
01195       dbl_EGlpNumCopyDiffRatio (t_u, *x, *u, y_ij);
01196       dbl_EGlpNumCopyAbs (at_u, t_u);
01197       if (dbl_EGlpNumIsLess (at_u, t_max))
01198         dbl_EGlpNumCopy (t_max, at_u);
01199     }
01200   }
01201 
01202   if (dbl_EGlpNumIsLeq (dbl_INFTY, t_max))
01203   {
01204     rs->ratio_stat = RATIO_UNBOUNDED;
01205     ILL_CLEANUP;
01206   }
01207 
01208   dbl_EGlpNumZero (yi_max);
01209   dbl_EGlpNumZero (ayi_max);
01210   dbl_EGlpNumMultUiTo (t_max, 101);
01211   dbl_EGlpNumDivUiTo (t_max, 100);
01212   for (k = 0; k < lp->yjz.nzcnt; k++)
01213   {
01214     dbl_EGlpNumCopy (y_ij, lp->yjz.coef[k]);
01215     dbl_EGlpNumCopyAbs (ay_ij, y_ij);
01216     if (!dbl_EGlpNumIsNeqZero (y_ij, *pivtol))
01217       continue;
01218 
01219     i = lp->yjz.indx[k];
01220     if (lp->iwork[lp->baz[i]] == 1)
01221       continue;
01222     x = &(lp->xbz[i]);
01223     col = lp->baz[i];
01224     l = &(lp->lz[col]);
01225     u = &(lp->uz[col]);
01226 
01227     dbl_EGlpNumCopy (t_u, dbl_INFTY);
01228     dbl_EGlpNumCopy (at_u, t_u);
01229     dbl_EGlpNumCopy (t_l, dbl_NINFTY);
01230     dbl_EGlpNumCopy (at_l, t_u);
01231     if (dbl_EGlpNumIsNeqq (*l, dbl_NINFTY))
01232     {
01233       dbl_EGlpNumCopyDiffRatio (t_l, *x, *l, y_ij);
01234       dbl_EGlpNumCopyAbs (at_l, t_l);
01235     }
01236     if (dbl_EGlpNumIsNeqq (*u, dbl_INFTY))
01237     {
01238       dbl_EGlpNumCopyDiffRatio (t_u, *x, *u, y_ij);
01239       dbl_EGlpNumCopyAbs (at_u, t_u);
01240     }
01241     //t_i = (fabs (t_l) < fabs (t_u)) ? t_l : t_u;
01242     if (dbl_EGlpNumIsLess (at_l, at_u))
01243     {
01244       dbl_EGlpNumCopy (t_i, t_l);
01245       dbl_EGlpNumCopy (at_i, at_l);
01246     }
01247     else
01248     {
01249       dbl_EGlpNumCopy (t_i, t_u);
01250       dbl_EGlpNumCopy (at_i, at_u);
01251     }
01252     /*if (fabs (t_i) <= t_max + t_max * (1.0e-2)) */
01253     if (dbl_EGlpNumIsLeq (at_i, t_max))
01254     {
01255       if (dbl_EGlpNumIsLess (ayi_max, ay_ij))
01256       {
01257         dbl_EGlpNumCopy (yi_max, y_ij);
01258         dbl_EGlpNumCopy (ayi_max, ay_ij);
01259         rs->lindex = i;
01260         dbl_EGlpNumCopy (rs->tz, t_i);
01261         rs->lvstat = (dbl_EGlpNumIsLess (at_l, at_u)) ? STAT_LOWER : STAT_UPPER;
01262       }
01263     }
01264   }
01265 
01266   if (rs->lindex < 0)
01267   {
01268     rs->ratio_stat = RATIO_FAILED;
01269   }
01270   else
01271   {
01272     rs->ratio_stat = RATIO_BCHANGE;
01273     dbl_EGlpNumCopy (rs->pivotval, yi_max);
01274   }
01275 CLEANUP:
01276   for (i = 0; i < rcnt; i++)
01277     lp->iwork[rlist[i]] = 0;
01278   dbl_EGlpNumClearVar (t_max);
01279   dbl_EGlpNumClearVar (ay_ij);
01280   dbl_EGlpNumClearVar (at_i);
01281   dbl_EGlpNumClearVar (at_l);
01282   dbl_EGlpNumClearVar (at_u);
01283   dbl_EGlpNumClearVar (ayi_max);
01284   dbl_EGlpNumClearVar (y_ij);
01285   dbl_EGlpNumClearVar (t_i);
01286   dbl_EGlpNumClearVar (t_l);
01287   dbl_EGlpNumClearVar (t_u);
01288   dbl_EGlpNumClearVar (yi_max);
01289   return;
01290 }

Generated on Wed Apr 22 09:16:10 2009 for QSopt_ex by  doxygen 1.5.2