mpq_lib.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 /* RCS_INFO = "$RCSfile: mpq_lib.c,v $ $Revision: 1.2 $ $Date: 2003/11/05 16:49:52 $"; */
00024 //static int TRACE = 0;
00025 
00026 /****************************************************************************/
00027 /*                                                                          */
00028 /*               Interface Routines to Core LP Solver                       */
00029 /*                                                                          */
00030 /*  EXPORTED FUNCTIONS                                                      */
00031 /*                                                                          */
00032 /*    int mpq_ILLlib_optimize (mpq_lpinfo *lp, mpq_ILLlp_basis *B, mpq_price_info *pinf,    */
00033 /*            int algo, int *status, int simplex_display)                   */
00034 /*    int mpq_ILLlib_cache_solution (mpq_lpinfo *lp, mpq_ILLlp_cache *C)                */
00035 /*    int mpq_ILLlib_solution (mpq_lpinfo *lp, mpq_ILLlp_cache *C, double *val,         */
00036 /*            double *x, double *pi, double *slack, double *rc)             */
00037 /*    int mpq_ILLlib_get_x (mpq_lpinfo *lp, mpq_ILLlp_cache *C, double *x)              */
00038 /*    int mpq_ILLlib_get_slack (mpq_lpinfo *lp, mpq_ILLlp_cache *C, double *slack)      */
00039 /*    int mpq_ILLlib_objval (mpq_lpinfo *lp, mpq_ILLlp_cache *C, double *val)           */
00040 /*    int mpq_ILLlib_newrow (mpq_lpinfo *lp, mpq_ILLlp_basis *B, double rhs,            */
00041 /*            char sense, double range, const char *name)                   */
00042 /*        -range can specify a rangeval for the row (if sense is not 'R',   */
00043 /*         then range is ignored); it should be 0 if no range is needed;    */
00044 /*         if sense is 'R' but no rangeval array exists for the LP, the     */
00045 /*         array will be allocated and initialized.                         */
00046 /*    int mpq_ILLlib_newrows (mpq_lpinfo *lp, mpq_ILLlp_basis *B, int num, double *rhs, */
00047 /*            char *sense, double *range, const char **names)               */
00048 /*        -range is an array specifying the rangevals for the rows; range   */
00049 /*         should be NULL if no rangevals are needed.                       */
00050 /*    int mpq_ILLlib_addrow (mpq_lpinfo *lp, mpq_ILLlp_basis *B, int cnt, int *ind,     */
00051 /*            double *val, double rhs, char sense, double range,            */
00052 /*            const char *name)                                             */
00053 /*    int mpq_ILLlib_addrows (mpq_lpinfo *lp, mpq_ILLlp_basis *B, int num,              */
00054 /*            int *rmatcnt, int *rmatbeg, int *rmatind, double *rmatval,    */
00055 /*            double *rhs, char *sense, double *range, const char **names,  */
00056 /*            int *factorok)                                                */
00057 /*    int mpq_ILLlib_delrows (mpq_lpinfo *lp, mpq_ILLlp_basis *B,                       */
00058 /*            int num, int *dellist, int *basis_ok)                         */
00059 /*    int mpq_ILLlib_newcol (mpq_lpinfo *lp, mpq_ILLlp_basis *B,                        */
00060 /*            double obj, double lower, double upper, const char *name,     */
00061 /*            int factorok)                                                 */
00062 /*    int mpq_ILLlib_newcols (mpq_lpinfo *lp, mpq_ILLlp_basis *B,                       */
00063 /*            int num, double *obj, double *lower, double *upper,           */
00064 /*            const char **names, int factorok)                             */
00065 /*    int mpq_ILLlib_addcol (mpq_lpinfo *lp, mpq_ILLlp_basis *B,                        */
00066 /*            int cnt, int *ind, double *val, double obj, double lower,     */
00067 /*            double upper, const char *name, int factorok)                 */
00068 /*    int mpq_ILLlib_addcols (mpq_lpinfo *lp, mpq_ILLlp_basis *B,                       */
00069 /*            int num, int *cmatcnt, int *cmatbeg, int *cmatind,            */
00070 /*            double *cmatval, double *obj, double *lower, double *upper,   */
00071 /*            const char **names, int factorok)                             */
00072 /*    int mpq_ILLlib_delcols (mpq_lpinfo *lp, mpq_ILLlp_basis *B, int num, int *dellist */
00073 /*            int *basis_ok)                                                */
00074 /*    int mpq_ILLlib_chgcoef (mpq_lpinfo *lp, int rowindex, int colindex,           */
00075 /*            double coef)                                                  */
00076 /*    int mpq_ILLlib_chgsense (mpq_lpinfo *lp, int num, int *rowlist, char *sense)  */
00077 /*    int mpq_ILLlib_getrows (mpq_lpinfo *lp, int num, int *rowlist, int **rowcnt,  */
00078 /*            int **rowbeg, int **rowind, double **rowval, double **rhs,    */
00079 /*            char **sense, char ***names)                                  */
00080 /*    int mpq_ILLlib_getcols (mpq_lpinfo *lp, int num, int *collist, int **colcnt,  */
00081 /*            int **colbeg, int **colind, double **colval, double **obj,    */
00082 /*            double **lower, double **upper, char ***names)                */
00083 /*    int mpq_ILLlib_getobj (mpq_lpinfo *lp, double *obj)                           */
00084 /*    int mpq_ILLlib_chgobj (mpq_lpinfo *lp, int indx, double coef)                 */
00085 /*    int mpq_ILLlib_getrhs (mpq_lpinfo *lp, double *rhs)                           */
00086 /*    int mpq_ILLlib_chgrhs (mpq_lpinfo *lp, int indx, double coef)                 */
00087 /*    int mpq_ILLlib_getintflags (mpq_lpinfo *lp, int *intflags)                    */
00088 /*    int mpq_ILLlib_rownames (mpq_lpinfo *lp, char **rownames)                     */
00089 /*    int mpq_ILLlib_colnames (mpq_lpinfo *lp, char **colnames)                     */
00090 /*    int mpq_ILLlib_colindex (mpq_lpinfo *lp, char *name, int *colindex)           */
00091 /*    int mpq_ILLlib_rowindex (mpq_lpinfo *lp, char *name, int *rowindex)           */
00092 /*    int mpq_ILLlib_chgbnd  (mpq_lpinfo *lp, int indx, char lu, double bnd)        */
00093 /*    int mpq_ILLlib_chgbnds (mpq_lpinfo *lp, int cnt, int *indx, char *lu,         */
00094 /*            double *bnd)                                                  */
00095 /*    int mpq_ILLlib_getbnd (mpq_lpinfo *lp, int indx, char lu, double *bnd)        */
00096 /*    int mpq_ILLlib_getbnds (mpq_lpinfo *lp, double *lower, double *upper)         */
00097 /*    int mpq_ILLlib_strongbranch (mpq_lpinfo *lp, mpq_price_info *pinf,                */
00098 /*      int *candidatelist, int ncand, double *xlist, double *downpen,      */
00099 /*      double *uppen, int iterations, double objbound)                     */
00100 /*    int mpq_ILLlib_getbasis (mpq_lpinfo *lp, char *cstat, char *rstat)            */
00101 /*    int mpq_ILLlib_loadbasis (mpq_ILLlp_basis *B, int nstruct, int nrows,         */
00102 /*      char *cstat, char *rstat)                                           */
00103 /*    int mpq_ILLlib_readbasis (mpq_lpinfo *lp, mpq_ILLlp_basis *B, char *mpq_fname)        */
00104 /*    int mpq_ILLlib_writebasis (mpq_lpinfo *lp, const char *mpq_fname)                 */
00105 /*    int mpq_ILLlib_getrownorms (mpq_lpinfo *lp, mpq_price_info *pinf,                 */
00106 /*            double *rownorms)                                             */
00107 /*    int mpq_ILLlib_loadrownorms (mpq_lpinfo *lp, mpq_price_info *pinf,                */
00108 /*            double *rownorms)                                             */
00109 /*    int mpq_ILLlib_recompute_rownorms (mpq_lpinfo *lp, mpq_price_info *pinf)          */
00110 /*    int mpq_ILLlib_print_x (EGioFile_t *fd, mpq_lpinfo *lp, mpq_ILLlp_cache *C, double *x,  */
00111 /*            int nonZerosOnly)                                             */
00112 /*    int mpq_ILLlib_print_x (mpq_lpinfo *lp, mpq_ILLlp_cache *C)                       */
00113 /*    int mpq_ILLlib_iter (mpq_lpinfo *lp)                                          */
00114 /*                                                                          */
00115 /*  NOTES                                                                   */
00116 /*                                                                          */
00117 /*                                                                          */
00118 /****************************************************************************/
00119 
00120 #include "qs_config.h"
00121 #include "mpq_iqsutil.h"
00122 #include "mpq_lpdata.h"
00123 #include "mpq_lpdefs.h"
00124 #include "mpq_simplex.h"
00125 #include "mpq_price.h"
00126 #include "mpq_basis.h"
00127 #include "mpq_lib.h"
00128 #include "mpq_qstruct.h"
00129 #include "mpq_qsopt.h"
00130 #include "mpq_lp.h"
00131 #include "mpq_mps.h"
00132 #ifdef USEDMALLOC
00133 #include "dmalloc.h"
00134 #endif
00135 
00136 static void mpq_check_pinf (
00137   mpq_price_info * pinf,
00138   int *it_exists);
00139 
00140 static int mpq_matrix_addrow (
00141   mpq_ILLmatrix * A,
00142   int rowcnt,
00143   int *rowind,
00144   const mpq_t * rowval),
00145   mpq_matrix_addrow_end (
00146   mpq_ILLmatrix * A,
00147   int row,
00148   int rowcnt,
00149   int *rowind,
00150   const mpq_t * rowval),
00151   mpq_matrix_addcoef (
00152   mpq_lpinfo * lp,
00153   mpq_ILLmatrix * A,
00154   int row,
00155   int col,
00156   mpq_t val),
00157   mpq_matrix_addcol (
00158   mpq_ILLmatrix * A,
00159   int colcnt,
00160   int *colind,
00161   mpq_t * colval),
00162   mpq_delcols_work (
00163   mpq_lpinfo * lp,
00164   char *colmark),
00165   mpq_reset_colindex (
00166   mpq_lpinfo * lp),
00167   mpq_reset_rowindex (
00168   mpq_lpinfo * lp);
00169 
00170 int mpq_ILLlib_optimize (
00171   mpq_lpinfo * lp,
00172   mpq_ILLlp_basis * B,
00173   mpq_price_info * pinf,
00174   int algo,
00175   int *status,
00176   int simplex_display,
00177   itcnt_t*itcnt)
00178 {
00179   int rval = 0;
00180   int sol_status;
00181 
00182   if (status)
00183     *status = QS_LP_UNSOLVED;
00184 
00185   /* mpq_ILLprice_free_pricing_info (pinf); *//* Should be removed later */
00186 
00187   rval = mpq_ILLsimplex (lp, algo, B, pinf, &sol_status, simplex_display, itcnt);
00188   CHECKRVALG (rval, CLEANUP);
00189 
00190   if (status)
00191     *status = sol_status;
00192 
00193 CLEANUP:
00194 
00195   if (rval == E_SIMPLEX_ERROR)
00196   {
00197     EGioFile_t *eout = 0;
00198     int tval;
00199 
00200     printf ("write bad lp to error.lp\n");
00201     fflush (stdout);
00202     #ifdef HAVE_ZLIB_H
00203     eout = EGioOpen ("error.lp.gz", "w");
00204     #else
00205     #ifdef HAVE_BZLIB_H
00206     eout = EGioOpen ("error.lp.bz2", "w");
00207     #else
00208     eout = EGioOpen ("error.lp", "w");
00209     #endif
00210     #endif
00211     if (!eout)
00212     {
00213       fprintf (stderr, "could not open file to write bad lp\n");
00214     }
00215     else
00216     {
00217       tval = mpq_ILLwrite_lp (lp->O, NULL);
00218       if (tval)
00219       {
00220         fprintf (stderr, "error while writing bad lp\n");
00221       }
00222       EGioClose (eout);
00223     }
00224 
00225     printf ("write bad basis to error.bas\n");
00226     fflush (stdout);
00227     tval = mpq_ILLlib_writebasis (lp, 0, "error.bas");
00228     if (tval)
00229     {
00230       fprintf (stderr, "error while writing bad basis\n");
00231     }
00232   }
00233   if (rval == QS_LP_CHANGE_PREC)
00234   {
00235     MESSAGE (__QS_SB_VERB, "Changing mpq_precision");
00236     return rval;
00237   }
00238   MESSAGE (rval ? 0 : 1000, "Error code %d", rval);
00239   EG_RETURN (rval);
00240 }
00241 
00242 int mpq_ILLlib_cache_solution (
00243   mpq_lpinfo * lp,
00244   mpq_ILLlp_cache * C)
00245 {
00246   int rval = 0;
00247 
00248   if (C)
00249   {
00250     if (C->nstruct != lp->O->nstruct || C->nrows != lp->O->nrows)
00251     {
00252       fprintf (stderr, "lp_cache does not match size of lp\n");
00253       rval = 1;
00254       ILL_CLEANUP;
00255     }
00256     rval = mpq_ILLlib_solution (lp, 0, &(C->val), C->x, C->pi, C->slack, C->rc);
00257     CHECKRVALG (rval, CLEANUP);
00258   }
00259 
00260 CLEANUP:
00261 
00262   EG_RETURN (rval);
00263 }
00264 
00265 int mpq_ILLlib_solution (
00266   mpq_lpinfo * lp,
00267   mpq_ILLlp_cache * C,
00268   mpq_t * val,
00269   mpq_t * x,
00270   mpq_t * pi,
00271   mpq_t * slack,
00272   mpq_t * rc)
00273 {
00274   int i, rval = 0;
00275   mpq_t *tempx = 0;
00276   mpq_t *temprc = 0;
00277   int ncols = lp->O->ncols;
00278   int nrows = lp->O->nrows;
00279   int nstruct = lp->O->nstruct;
00280   mpq_ILLlpdata *qslp = lp->O;
00281 
00282   if (C)
00283   {
00284     if (C->nrows != nrows || C->nstruct != nstruct)
00285     {
00286       fprintf (stderr, "cache mismatch in mpq_ILLlib_solution\n");
00287       rval = 0;
00288       ILL_CLEANUP;
00289     }
00290     if (val)
00291     {
00292       mpq_EGlpNumCopy (*val, C->val);
00293     }
00294     if (x)
00295     {
00296       for (i = 0; i < nstruct; i++)
00297       {
00298         mpq_EGlpNumCopy (x[i], C->x[i]);
00299       }
00300     }
00301     if (pi)
00302     {
00303       for (i = 0; i < nrows; i++)
00304       {
00305         mpq_EGlpNumCopy (pi[i], C->pi[i]);
00306       }
00307     }
00308     if (slack)
00309     {
00310       for (i = 0; i < nrows; i++)
00311       {
00312         mpq_EGlpNumCopy (slack[i], C->slack[i]);
00313       }
00314     }
00315     if (rc)
00316     {
00317       for (i = 0; i < nstruct; i++)
00318       {
00319         mpq_EGlpNumCopy (rc[i], C->rc[i]);
00320       }
00321     }
00322   }
00323   else
00324   {
00325     if (x || slack)
00326       tempx = mpq_EGlpNumAllocArray (ncols);
00327 
00328     if (rc)
00329       temprc = mpq_EGlpNumAllocArray (ncols);
00330 
00331     rval = mpq_ILLsimplex_solution (lp, tempx, pi, temprc, val);
00332     CHECKRVALG (rval, CLEANUP);
00333 
00334     if (x)
00335     {
00336       for (i = 0; i < nstruct; i++)
00337       {
00338         mpq_EGlpNumCopy (x[i], tempx[qslp->structmap[i]]);
00339       }
00340     }
00341     if (slack)
00342     {
00343       for (i = 0; i < nrows; i++)
00344       {
00345         mpq_EGlpNumCopy (slack[i], tempx[qslp->rowmap[i]]);
00346       }
00347     }
00348 
00349     if (rc)
00350     {
00351       for (i = 0; i < nstruct; i++)
00352       {
00353         mpq_EGlpNumCopy (rc[i], temprc[qslp->structmap[i]]);
00354       }
00355     }
00356 
00357 
00358     if (lp->O->objsense == mpq_ILL_MAX)
00359     {                           /* Reverse signs for max prob */
00360       if (val)
00361       {
00362         mpq_EGlpNumSign (*val);
00363       }
00364       if (pi)
00365       {
00366         for (i = 0; i < nrows; i++)
00367         {
00368           mpq_EGlpNumSign (pi[i]);
00369         }
00370       }
00371       if (rc)
00372       {
00373         for (i = 0; i < nstruct; i++)
00374         {
00375           mpq_EGlpNumSign (rc[i]);
00376         }
00377       }
00378     }
00379   }
00380 
00381 CLEANUP:
00382 
00383   mpq_EGlpNumFreeArray (tempx);
00384   mpq_EGlpNumFreeArray (temprc);
00385   EG_RETURN (rval);
00386 }
00387 
00388 int mpq_ILLlib_get_x (
00389   mpq_lpinfo * lp,
00390   mpq_ILLlp_cache * C,
00391   mpq_t * x)
00392 {
00393   int rval = 0;
00394 
00395   rval = mpq_ILLlib_solution (lp, C, 0, x, 0, 0, 0);
00396   CHECKRVALG (rval, CLEANUP);
00397 
00398 CLEANUP:
00399 
00400   EG_RETURN (rval);
00401 }
00402 
00403 int mpq_ILLlib_get_slack (
00404   mpq_lpinfo * lp,
00405   mpq_ILLlp_cache * C,
00406   mpq_t * slack)
00407 {
00408   int rval = 0;
00409 
00410   rval = mpq_ILLlib_solution (lp, C, 0, 0, 0, slack, 0);
00411   CHECKRVALG (rval, CLEANUP);
00412 
00413 CLEANUP:
00414 
00415   EG_RETURN (rval);
00416 }
00417 
00418 
00419 int mpq_ILLlib_objval (
00420   mpq_lpinfo * lp,
00421   mpq_ILLlp_cache * C,
00422   mpq_t * val)
00423 {
00424   int rval = 0;
00425 
00426   if (lp->basisstat.optimal)
00427   {
00428     rval = mpq_ILLlib_solution (lp, C, val, 0, 0, 0, 0);
00429     CHECKRVALG (rval, CLEANUP);
00430   }
00431   else
00432   {
00433     mpq_EGlpNumCopy (*val, lp->dobjval);  /* Ask Sanjeeb */
00434   }
00435 
00436 CLEANUP:
00437 
00438   EG_RETURN (rval);
00439 }
00440 
00441 int mpq_ILLlib_tableau (
00442   mpq_lpinfo * lp,
00443   int row,
00444   mpq_t * binv,
00445   mpq_t * tabrow)
00446 {
00447   int rval = 0;
00448   int i;
00449   int ncols = lp->O->ncols;
00450   int nrows = lp->O->nrows;
00451   int nstruct = lp->O->nstruct;
00452   mpq_t *brow = 0;
00453   mpq_t *trow = 0;
00454   mpq_ILLlpdata *qslp = lp->O;
00455 
00456   if (row < 0 || row >= qslp->nrows)
00457   {
00458     fprintf (stderr, "mpq_ILLlib_tableau called with bad row: %d\n", row);
00459     rval = 1;
00460     ILL_CLEANUP;
00461   }
00462   brow = mpq_EGlpNumAllocArray (nrows);
00463 
00464   if (tabrow)
00465     trow = mpq_EGlpNumAllocArray (ncols);
00466 
00467   rval = mpq_ILLbasis_tableau_row (lp, row, brow, trow, 0, 0);
00468   CHECKRVALG (rval, CLEANUP);
00469 
00470   if (binv)
00471   {
00472     for (i = 0; i < nrows; i++)
00473     {
00474       mpq_EGlpNumCopy (binv[i], brow[i]);
00475     }
00476   }
00477 
00478   if (tabrow)
00479   {
00480     for (i = 0; i < nstruct; i++)
00481     {
00482       mpq_EGlpNumCopy (tabrow[i], trow[qslp->structmap[i]]);
00483     }
00484     for (i = 0; i < nrows; i++)
00485     {
00486       mpq_EGlpNumCopy (tabrow[nstruct + i], trow[qslp->rowmap[i]]);
00487     }
00488   }
00489 
00490 CLEANUP:
00491 
00492   mpq_EGlpNumFreeArray (brow);
00493   mpq_EGlpNumFreeArray (trow);
00494   EG_RETURN (rval);
00495 }
00496 
00497 int mpq_ILLlib_basis_order (
00498   mpq_lpinfo * lp,
00499   int *header)
00500 {
00501   int rval = 0;
00502   int i, j;
00503   int ncols = lp->O->ncols;
00504   int nrows = lp->O->nrows;
00505   int nstruct = lp->O->nstruct;
00506   mpq_ILLlpdata *qslp = lp->O;
00507   int *invmap = 0;
00508 
00509   ILL_SAFE_MALLOC (invmap, ncols, int);
00510 
00511   for (j = 0; j < nstruct; j++)
00512   {
00513     invmap[qslp->structmap[j]] = j;
00514   }
00515   for (i = 0; i < nrows; i++)
00516   {
00517     invmap[qslp->rowmap[i]] = nstruct + i;
00518   }
00519 
00520   for (i = 0; i < nrows; i++)
00521   {
00522     header[i] = invmap[lp->baz[i]];
00523   }
00524 
00525 CLEANUP:
00526 
00527   ILL_IFFREE (invmap, int);
00528 
00529   EG_RETURN (rval);
00530 }
00531 
00532 int mpq_ILLlib_chgbnd (
00533   mpq_lpinfo * lp,
00534   int indx,
00535   int lu,
00536   const mpq_t bnd)
00537 {
00538   int rval = 0;
00539   int col;
00540 
00541   if (!lp)
00542   {
00543     fprintf (stderr, "mpq_ILLlib_chgbnd called without an lp\n");
00544     rval = 1;
00545     ILL_CLEANUP;
00546   }
00547 
00548   if (indx < 0 || indx > lp->O->nstruct)
00549   {
00550     fprintf (stderr, "mpq_ILLlib_chgbnd called with bad indx: %d\n", indx);
00551     rval = 1;
00552     ILL_CLEANUP;
00553   }
00554 
00555   if (lp->O->sinfo)
00556   {                             /* Presolve LP is no longer valid, free the data */
00557     mpq_ILLlp_sinfo_free (lp->O->sinfo);
00558     ILL_IFFREE (lp->O->sinfo, mpq_ILLlp_sinfo);
00559   }
00560 
00561   col = lp->O->structmap[indx];
00562 
00563   switch (lu)
00564   {
00565   case 'L':
00566     mpq_EGlpNumCopy (lp->O->lower[col], bnd);
00567     break;
00568   case 'U':
00569     mpq_EGlpNumCopy (lp->O->upper[col], bnd);
00570     break;
00571   case 'B':
00572     mpq_EGlpNumCopy (lp->O->lower[col], bnd);
00573     mpq_EGlpNumCopy (lp->O->upper[col], bnd);
00574     break;
00575   default:
00576     fprintf (stderr, "mpq_ILLlib_chgbnd called with lu: %c\n", lu);
00577     rval = 1;
00578     ILL_CLEANUP;
00579   }
00580 
00581 CLEANUP:
00582 
00583   EG_RETURN (rval);
00584 }
00585 
00586 int mpq_ILLlib_chgbnds (
00587   mpq_lpinfo * lp,
00588   int cnt,
00589   int *indx,
00590   char *lu,
00591   const mpq_t * bnd)
00592 {
00593   int rval = 0;
00594   int i;
00595 
00596   for (i = 0; i < cnt; i++)
00597   {
00598     rval = mpq_ILLlib_chgbnd (lp, indx[i], lu[i], bnd[i]);
00599     if (rval)
00600       ILL_CLEANUP;
00601   }
00602 
00603 CLEANUP:
00604 
00605   EG_RETURN (rval);
00606 }
00607 
00608 int mpq_ILLlib_getbnd (
00609   mpq_lpinfo * lp,
00610   int indx,
00611   int lu,
00612   mpq_t * bnd)
00613 {
00614   int rval = 0;
00615   int col;
00616 
00617   if (!lp)
00618   {
00619     fprintf (stderr, "mpq_ILLlib_getbnd called without an lp\n");
00620     rval = 1;
00621     ILL_CLEANUP;
00622   }
00623 
00624   if (indx < 0 || indx > lp->O->nstruct)
00625   {
00626     fprintf (stderr, "mpq_ILLlib_getbnd called with bad indx: %d\n", indx);
00627     rval = 1;
00628     ILL_CLEANUP;
00629   }
00630 
00631   col = lp->O->structmap[indx];
00632 
00633   switch (lu)
00634   {
00635   case 'L':
00636     mpq_EGlpNumCopy (*bnd, lp->O->lower[col]);
00637     break;
00638   case 'U':
00639     mpq_EGlpNumCopy (*bnd, lp->O->upper[col]);
00640     break;
00641   default:
00642     fprintf (stderr, "mpq_ILLlib_getbnd called with lu: %c\n", lu);
00643     rval = 1;
00644     ILL_CLEANUP;
00645   }
00646 
00647 CLEANUP:
00648 
00649   EG_RETURN (rval);
00650 }
00651 
00652 int mpq_ILLlib_getbnds_list ( 
00653   mpq_lpinfo *lp,
00654   int num,
00655   int*collist, 
00656   mpq_t *lower,
00657   mpq_t *upper)
00658 {
00659     int rval = 0;
00660     mpq_ILLlpdata *qslp;
00661     int nstruct;
00662     int j, col;
00663 
00664     if (!lp) {
00665         fprintf (stderr, "mpq_ILLlib_getbnds_list called without an lp\n");
00666         rval = 1; ILL_CLEANUP;
00667     }
00668 
00669     qslp = lp->O;
00670     nstruct = qslp->nstruct;
00671     for (j = 0; j < num ; j++) {
00672     if(collist[j]<0|| collist[j] >= nstruct)
00673       {
00674         fprintf (stderr, "mpq_ILLlib_getbnds_list collist[%d] = %d out "
00675                   "of range\n", j, collist[j]);
00676       }
00677       col = qslp->structmap[collist[j]];
00678       if (lower)
00679         mpq_EGlpNumCopy(lower[j], qslp->lower[col]);
00680       if (upper)
00681         mpq_EGlpNumCopy(upper[j], qslp->upper[col]);
00682     }
00683 
00684 CLEANUP:
00685 
00686   EG_RETURN(rval);    
00687 }
00688 
00689 
00690 int mpq_ILLlib_getbnds (
00691   mpq_lpinfo * lp,
00692   mpq_t * lower,
00693   mpq_t * upper)
00694 {
00695   int rval = 0;
00696   mpq_ILLlpdata *qslp;
00697   int nstruct;
00698   int j, col;
00699 
00700   if (!lp)
00701   {
00702     fprintf (stderr, "mpq_ILLlib_getbnd called without an lp\n");
00703     rval = 1;
00704     ILL_CLEANUP;
00705   }
00706 
00707   qslp = lp->O;
00708   nstruct = qslp->nstruct;
00709 
00710   for (j = 0; j < nstruct; j++)
00711   {
00712     col = qslp->structmap[j];
00713     if (lower)
00714       mpq_EGlpNumCopy (lower[j], qslp->lower[col]);
00715     if (upper)
00716       mpq_EGlpNumCopy (upper[j], qslp->upper[col]);
00717   }
00718 
00719 CLEANUP:
00720 
00721   EG_RETURN (rval);
00722 }
00723 
00724 int mpq_ILLlib_strongbranch (
00725   mpq_lpinfo * lp,
00726   mpq_price_info * pinf,
00727   int *candidatelist,
00728   int ncand,
00729   mpq_t * xlist,
00730   mpq_t * downpen,
00731   mpq_t * uppen,
00732   int iterations,
00733   mpq_t objbound,
00734   itcnt_t*itcnt)
00735 {
00736   int rval = 0;
00737   int i, k, status, have_norms;
00738   int olditer = lp->maxiter;
00739   int nstruct = lp->O->nstruct;
00740   int nrows = lp->O->nrows;
00741   mpq_t *myx = 0;
00742   mpq_t xi, t, oldbnd;
00743   mpq_price_info lpinf;
00744   mpq_ILLlp_basis B, origB;
00745 
00746   mpq_EGlpNumInitVar (lpinf.htrigger);
00747   mpq_EGlpNumInitVar (xi);
00748   mpq_EGlpNumInitVar (t);
00749   mpq_EGlpNumInitVar (oldbnd);
00750   mpq_EGlpNumZero (oldbnd);
00751   mpq_ILLlp_basis_init (&B);
00752   mpq_ILLlp_basis_init (&origB);
00753   mpq_ILLprice_init_pricing_info (&lpinf);
00754   lpinf.dI_price = QS_PRICE_DSTEEP;
00755   lpinf.dII_price = QS_PRICE_DSTEEP;
00756 
00757   if (xlist == 0)
00758   {
00759     myx = mpq_EGlpNumAllocArray (nstruct);
00760     rval = mpq_ILLlib_get_x (lp, 0, myx);
00761     CHECKRVALG (rval, CLEANUP);
00762   }
00763 
00764   rval = mpq_ILLlp_basis_alloc (&origB, nstruct, nrows);
00765   CHECKRVALG (rval, CLEANUP);
00766 
00767   rval = mpq_ILLlib_getbasis (lp, origB.cstat, origB.rstat);
00768   CHECKRVALG (rval, CLEANUP);
00769 
00770   mpq_check_pinf (pinf, &have_norms);
00771   if (have_norms == 0)
00772   {
00773     origB.rownorms = mpq_EGlpNumAllocArray (nrows);
00774     rval = mpq_ILLlib_getrownorms (lp, pinf, origB.rownorms);
00775     CHECKRVALG (rval, CLEANUP);
00776   }
00777   else
00778   {
00779     lp->basisid = -1;
00780     rval = mpq_ILLlib_optimize (lp, 0, &lpinf, DUAL_SIMPLEX, &status, 0, itcnt);
00781     CHECKRVALG (rval, CLEANUP);
00782   }
00783 
00784   rval = mpq_ILLlp_basis_alloc (&B, nstruct, nrows);  /* Note: B and orgiB may */
00785   /* differ.               */
00786   CHECKRVALG (rval, CLEANUP);
00787 
00788   rval = mpq_ILLlib_getbasis (lp, B.cstat, B.rstat);
00789   CHECKRVALG (rval, CLEANUP);
00790   B.rownorms = mpq_EGlpNumAllocArray (nrows);
00791 
00792   if (have_norms == 0)
00793   {
00794     rval = mpq_ILLlib_getrownorms (lp, pinf, B.rownorms);
00795     CHECKRVALG (rval, CLEANUP);
00796   }
00797   else
00798   {
00799     rval = mpq_ILLlib_getrownorms (lp, &lpinf, B.rownorms);
00800     CHECKRVALG (rval, CLEANUP);
00801   }
00802 
00803   lp->maxiter = iterations;
00804 
00805   for (i = 0; i < ncand; i++)
00806   {
00807     k = candidatelist[i];
00808     rval = mpq_ILLlib_getbnd (lp, k, 'U', &oldbnd);
00809     CHECKRVALG (rval, CLEANUP);
00810     if (xlist)
00811       mpq_EGlpNumCopy (xi, xlist[i]);
00812     else
00813       mpq_EGlpNumCopy (xi, myx[k]);
00814     mpq_EGlpNumFloor (t, xi);
00815     if (mpq_EGlpNumIsLessDbl (t, 0.1) && mpq_EGlpNumIsGreaDbl (t, -0.1))
00816       mpq_EGlpNumZero (t);
00817 
00818     rval = mpq_ILLlib_chgbnd (lp, k, 'U', t);
00819     CHECKRVALG (rval, CLEANUP);
00820 
00821     rval = mpq_ILLlib_optimize (lp, &B, &lpinf, DUAL_SIMPLEX, &status, 0, itcnt);
00822     CHECKRVALG (rval, CLEANUP);
00823 
00824     mpq_EGlpNumCopy (downpen[i], lp->dobjval);
00825     rval = mpq_ILLlib_chgbnd (lp, k, 'U', oldbnd);
00826     CHECKRVALG (rval, CLEANUP);
00827 
00828     rval = mpq_ILLlib_getbnd (lp, k, 'L', &oldbnd);
00829     CHECKRVALG (rval, CLEANUP);
00830     mpq_EGlpNumCeil (t, xi);
00831     if (mpq_EGlpNumIsLessDbl (t, 1.1) && mpq_EGlpNumIsGreaDbl (t, 0.9))
00832       mpq_EGlpNumOne (t);
00833     rval = mpq_ILLlib_chgbnd (lp, k, 'L', t);
00834     CHECKRVALG (rval, CLEANUP);
00835 
00836     rval = mpq_ILLlib_optimize (lp, &B, &lpinf, DUAL_SIMPLEX, &status, 0, itcnt);
00837     CHECKRVALG (rval, CLEANUP);
00838 
00839     mpq_EGlpNumCopy (uppen[i], lp->dobjval);
00840     rval = mpq_ILLlib_chgbnd (lp, k, 'L', oldbnd);
00841     CHECKRVALG (rval, CLEANUP);
00842   }
00843 
00844   if (lp->O->objsense == mpq_ILL_MAX)
00845   {
00846 
00847   }
00848   else
00849   {
00850     for (i = 0; i < ncand; i++)
00851     {
00852       if (mpq_EGlpNumIsLess (objbound, downpen[i]))
00853         mpq_EGlpNumCopy (downpen[i], objbound);
00854       if (mpq_EGlpNumIsLess (objbound, uppen[i]))
00855         mpq_EGlpNumCopy (uppen[i], objbound);
00856     }
00857   }
00858 
00859   /* Restore the old optimal solution */
00860 
00861   lp->maxiter = olditer;
00862   rval = mpq_ILLlib_optimize (lp, &origB, pinf, DUAL_SIMPLEX, &status, 0, itcnt);
00863   CHECKRVALG (rval, CLEANUP);
00864 
00865 CLEANUP:
00866 
00867   mpq_EGlpNumClearVar (xi);
00868   mpq_EGlpNumClearVar (t);
00869   mpq_EGlpNumClearVar (oldbnd);
00870   lp->maxiter = olditer;
00871   mpq_ILLprice_free_pricing_info (&lpinf);
00872   mpq_ILLlp_basis_free (&B);
00873   mpq_ILLlp_basis_free (&origB);
00874   if (xlist == 0)
00875     mpq_EGlpNumFreeArray (myx);
00876   mpq_EGlpNumClearVar (lpinf.htrigger);
00877   EG_RETURN (rval);
00878 }
00879 
00880 #define mpq_EXTRA_ROWS (100)
00881 #define mpq_EXTRA_COLS (100)
00882 #define mpq_EXTRA_MAT  (1000)
00883 
00884 int mpq_ILLlib_newrow (
00885   mpq_lpinfo * lp,
00886   mpq_ILLlp_basis * B,
00887   const mpq_t rhs,
00888   int sense,
00889   const mpq_t range,
00890   const char *name)
00891 {
00892   int rval = 0;
00893 
00894   rval = mpq_ILLlib_addrow (lp, B, 0, 0, 0, rhs, sense, range, name);
00895   CHECKRVALG (rval, CLEANUP);
00896 
00897 CLEANUP:
00898 
00899   EG_RETURN (rval);
00900 }
00901 
00902 int mpq_ILLlib_newrows (
00903   mpq_lpinfo * lp,
00904   mpq_ILLlp_basis * B,
00905   int num,
00906   const mpq_t * rhs,
00907   char *sense,
00908   const mpq_t * range,
00909   const char **names)
00910 {
00911   int rval = 0;
00912   int *rmatcnt = 0;
00913   int *rmatbeg = 0;
00914   int i;
00915 
00916   if (!num)
00917     ILL_CLEANUP;
00918 
00919   ILL_SAFE_MALLOC (rmatcnt, num, int);
00920 
00921   ILL_SAFE_MALLOC (rmatbeg, num, int);
00922 
00923   for (i = 0; i < num; i++)
00924   {
00925     rmatcnt[i] = 0;
00926     rmatbeg[i] = 0;
00927   }
00928 
00929   rval = mpq_ILLlib_addrows (lp, B, num, rmatcnt, rmatbeg, 0, 0, rhs, sense,
00930                          range, names, 0);
00931   CHECKRVALG (rval, CLEANUP);
00932 
00933 CLEANUP:
00934 
00935   ILL_IFFREE (rmatcnt, int);
00936   ILL_IFFREE (rmatbeg, int);
00937 
00938   EG_RETURN (rval);
00939 }
00940 
00941 int mpq_ILLlib_addrows (
00942   mpq_lpinfo * lp,
00943   mpq_ILLlp_basis * B,
00944   int num,
00945   int *rmatcnt,
00946   int *rmatbeg,
00947   int *rmatind,
00948   const mpq_t * rmatval,
00949   const mpq_t * rhs,
00950   char *sense,
00951   const mpq_t * range,
00952   const char **names,
00953   int *factorok)
00954 {
00955   int rval = 0;
00956   int i, j, total, bsing;
00957   int *imap = 0;
00958   int *bbeg = 0;
00959   int *bcnt = 0;
00960   int *bindi = 0;
00961   int *rindi = 0;
00962   int *jstat = 0;
00963   mpq_t *bval = 0;
00964   mpq_t rng;
00965   int badfactor = 0;
00966 
00967   mpq_EGlpNumInitVar (rng);
00968 
00969   if (B == 0 || B->rownorms == 0)
00970   {
00971     if (factorok)
00972       *factorok = 0;
00973   }
00974 
00975   if (B)
00976     mpq_EGlpNumFreeArray (B->colnorms);
00977 
00978   if (B && B->rownorms && factorok && *factorok == 1)
00979   {
00980     int *structmap = lp->O->structmap;
00981 
00982     lp->matbeg = lp->O->A.matbeg;
00983     lp->matcnt = lp->O->A.matcnt;
00984     lp->matind = lp->O->A.matind;
00985     lp->matval = lp->O->A.matval;
00986 
00987     lp->nrows = lp->O->nrows;
00988     lp->ncols = lp->O->ncols;
00989     if (B->rownorms_size < lp->O->nrows + num)
00990       mpq_EGlpNumReallocArray (&(B->rownorms), lp->O->nrows + num);
00991 
00992     ILL_SAFE_MALLOC (bcnt, num, int);
00993     ILL_SAFE_MALLOC (bbeg, num, int);
00994     ILL_SAFE_MALLOC (imap, lp->O->nstruct, int);
00995 
00996     ILL_SAFE_MALLOC (jstat, lp->ncols, int);
00997 
00998     for (i = 0; i < lp->ncols; i++)
00999     {
01000       jstat[i] = -1;
01001     }
01002     for (i = 0; i < lp->O->nstruct; i++)
01003     {
01004       jstat[structmap[i]] = i;
01005     }
01006 
01007     for (i = 0; i < lp->O->nstruct; i++)
01008     {
01009       imap[i] = -1;
01010     }
01011     for (i = 0; i < lp->O->nrows; i++)
01012     {
01013       if (jstat[lp->baz[i]] != -1)
01014       {
01015         imap[jstat[lp->baz[i]]] = i;
01016       }
01017     }
01018 
01019     for (i = 0, total = 0; i < num; i++)
01020     {
01021       bcnt[i] = 0;
01022       bbeg[i] = total;
01023       for (j = 0; j < rmatcnt[i]; j++)
01024       {
01025         if (imap[rmatind[rmatbeg[i] + j]] != -1)
01026         {
01027           bcnt[i]++;
01028           total++;
01029         }
01030       }
01031     }
01032     if (total)
01033     {
01034       ILL_SAFE_MALLOC (bindi, total, int);
01035 
01036       bval = mpq_EGlpNumAllocArray (total);
01037     }
01038     for (i = 0, total = 0; i < num; i++)
01039     {
01040       for (j = 0; j < rmatcnt[i]; j++)
01041       {
01042         if (imap[rmatind[rmatbeg[i] + j]] != -1)
01043         {
01044           mpq_EGlpNumCopy (bval[total], rmatval[rmatbeg[i] + j]);
01045           bindi[total] = imap[rmatind[rmatbeg[i] + j]];
01046           total++;
01047         }
01048       }
01049     }
01050 
01051     rval = mpq_ILLprice_get_new_rownorms (lp, num, B->rownorms + lp->O->nrows,
01052                                       bcnt, bbeg, bindi, bval);
01053     CHECKRVALG (rval, CLEANUP);
01054 
01055     ILL_IFFREE (bcnt, int);
01056     ILL_IFFREE (bbeg, int);
01057     ILL_IFFREE (bindi, int);
01058 
01059     mpq_EGlpNumFreeArray (bval);
01060     ILL_IFFREE (imap, int);
01061 
01062     badfactor = 1;
01063   }
01064 
01065   for (i = 0; i < num; i++)
01066   {
01067     if (range)
01068       mpq_EGlpNumCopy (rng, range[i]);
01069     else
01070       mpq_EGlpNumZero (rng);
01071     if (names)
01072     {
01073       rval = mpq_ILLlib_addrow (lp, B, rmatcnt[i], rmatind + rmatbeg[i],
01074                             rmatval + rmatbeg[i], rhs[i], sense[i], rng,
01075                             names[i]);
01076     }
01077     else
01078     {
01079       rval = mpq_ILLlib_addrow (lp, B, rmatcnt[i], rmatind + rmatbeg[i],
01080                             rmatval + rmatbeg[i], rhs[i], sense[i], rng, 0);
01081     }
01082     CHECKRVALG (rval, CLEANUP);
01083   }
01084 
01085 
01086   if (B && B->rownorms && (factorok && *factorok == 0))
01087   {
01088     lp->matbeg = lp->O->A.matbeg;
01089     lp->matcnt = lp->O->A.matcnt;
01090     lp->matind = lp->O->A.matind;
01091     lp->matval = lp->O->A.matval;
01092     lp->nrows = lp->O->nrows;
01093     lp->ncols = lp->O->ncols;
01094     lp->bz = lp->O->rhs;
01095     lp->nnbasic = lp->ncols - lp->nrows;
01096 
01097     rval = mpq_ILLbasis_load (lp, B);
01098     CHECKRVALG (rval, CLEANUP);
01099 
01100     if (lp->f)
01101       mpq_ILLfactor_free_factor_work (lp->f);
01102 
01103     rval = mpq_ILLbasis_factor (lp, &bsing);
01104     CHECKRVALG (rval, CLEANUP);
01105     if (bsing)
01106       MESSAGE (__QS_SB_VERB, "Singular Basis found!");
01107     *factorok = 1;
01108 
01109     if (B->rownorms_size < lp->O->nrows)
01110       mpq_EGlpNumReallocArray (&(B->rownorms), lp->O->nrows);
01111 
01112     ILL_SAFE_MALLOC (rindi, lp->O->nrows /* num */ , int);
01113 
01114     for (i = 0; i < num; i++)
01115     {
01116       rindi[i] = lp->O->nrows - num + i;
01117     }
01118 
01119     rval = mpq_ILLprice_get_dsteep_norms (lp, num, rindi,
01120                                       B->rownorms + lp->O->nrows - num);
01121     CHECKRVALG (rval, CLEANUP);
01122   }
01123 
01124   if (factorok != 0 && badfactor == 1)
01125   {
01126     *factorok = 0;
01127   }
01128 
01129 
01130 CLEANUP:
01131 
01132   ILL_IFFREE (bcnt, int);
01133   ILL_IFFREE (bbeg, int);
01134   ILL_IFFREE (bindi, int);
01135 
01136   mpq_EGlpNumFreeArray (bval);
01137   ILL_IFFREE (imap, int);
01138   ILL_IFFREE (jstat, int);
01139   ILL_IFFREE (rindi, int);
01140 
01141   mpq_EGlpNumClearVar (rng);
01142   EG_RETURN (rval);
01143 }
01144 
01145 int mpq_ILLlib_addrow (
01146   mpq_lpinfo * lp,
01147   mpq_ILLlp_basis * B,
01148   int cnt,
01149   int *ind,
01150   const mpq_t * val,
01151   const mpq_t rhs,
01152   int sense,
01153   const mpq_t range,
01154   const char *name)
01155 {
01156   int rval = 0;
01157   mpq_ILLlpdata *qslp;
01158   mpq_ILLmatrix *A;
01159   int i, nrows, ncols;
01160   char buf[ILL_namebufsize];
01161   int tind[1];
01162   mpq_t tval[1];
01163   int *tempind = 0;
01164   int pind, hit;
01165 
01166   mpq_EGlpNumInitVar (tval[0]);
01167 
01168   if (!lp)
01169   {
01170     fprintf (stderr, "mpq_ILLlib_addrow called without an lp\n");
01171     rval = 1;
01172     ILL_CLEANUP;
01173   }
01174 
01175   qslp = lp->O;
01176   A = &qslp->A;
01177 
01178   if (qslp->rA)
01179   {                             /* After an addrow call, needs to be updated */
01180     mpq_ILLlp_rows_clear (qslp->rA);
01181     ILL_IFFREE (qslp->rA, mpq_ILLlp_rows);
01182   }
01183 
01184   if (qslp->sinfo)
01185   {                             /* Presolve LP is no longer valid, free the data */
01186     mpq_ILLlp_sinfo_free (qslp->sinfo);
01187     ILL_IFFREE (qslp->sinfo, mpq_ILLlp_sinfo);
01188   }
01189 
01190   nrows = qslp->nrows;
01191   ncols = qslp->ncols;
01192 
01193   /* If the row has a range, create the rangeval array if needed  */
01194 
01195   if (sense == 'R' && !(qslp->rangeval) && qslp->rowsize > 0)
01196   {
01197     qslp->rangeval = mpq_EGlpNumAllocArray (qslp->rowsize);
01198     for (i = 0; i < qslp->nrows; i++)
01199     {
01200       mpq_EGlpNumZero (qslp->rangeval[i]);
01201     }
01202   }
01203 
01204   /* Add the row to the row structures */
01205 
01206   if (qslp->rowsize < nrows + 1)
01207   {
01208     mpq_EGlpNumReallocArray (&(qslp->rhs), qslp->rowsize + mpq_EXTRA_ROWS);
01209     qslp->sense = EGrealloc (qslp->sense,
01210                              sizeof (char) * (qslp->rowsize + mpq_EXTRA_ROWS));
01211     //rval = ILLutil_reallocrus_count ((void **) &(qslp->sense),
01212     //                                 qslp->rowsize + mpq_EXTRA_ROWS, sizeof (char));
01213     //CHECKRVALG(rval,CLEANUP);
01214 
01215     qslp->rowmap = EGrealloc (qslp->rowmap,
01216                               sizeof (int) * (qslp->rowsize + mpq_EXTRA_ROWS));
01217     //rval = ILLutil_reallocrus_count ((void **) &(qslp->rowmap),
01218     //                                 qslp->rowsize + mpq_EXTRA_ROWS, sizeof (int));
01219     //CHECKRVALG(rval,CLEANUP);
01220 
01221     if (qslp->rangeval || sense == 'R')
01222       mpq_EGlpNumReallocArray (&(qslp->rangeval), qslp->rowsize + mpq_EXTRA_ROWS);
01223 
01224     qslp->rownames = EGrealloc (qslp->rownames,
01225                                 sizeof (char *) * (qslp->rowsize + mpq_EXTRA_ROWS));
01226     //rval = ILLutil_reallocrus_count ((void **) &(qslp->rownames),
01227     //                                 qslp->rowsize + mpq_EXTRA_ROWS,
01228     //                                 sizeof (char *));
01229     //CHECKRVALG(rval,CLEANUP);
01230     qslp->rowsize += mpq_EXTRA_ROWS;
01231   }
01232 
01233   mpq_EGlpNumCopy (qslp->rhs[nrows], rhs);
01234   qslp->sense[nrows] = sense;
01235   qslp->rowmap[nrows] = ncols;  /* this will be the new logical */
01236   if (qslp->rangeval)
01237   {
01238     if (sense == 'R')
01239       mpq_EGlpNumCopy (qslp->rangeval[nrows], range);
01240     else
01241       mpq_EGlpNumZero (qslp->rangeval[nrows]);
01242   }
01243   ILL_FAILtrue (qslp->rownames == NULL, "must always be non NULL");
01244   mpq_ILLlib_findName (qslp, 1 /*row */ , name, nrows, buf);
01245   mpq_ILL_UTIL_STR (qslp->rownames[nrows], buf);
01246   ILLsymboltab_register (&qslp->rowtab, buf, qslp->nrows, &pind, &hit);
01247   ILL_FAILfalse (hit == 0, "must be new");
01248 
01249 
01250   /* Add the logical variable to the column structures */
01251 
01252   if (qslp->colsize < ncols + 1)
01253   {
01254     mpq_EGlpNumReallocArray (&(qslp->lower), qslp->colsize + mpq_EXTRA_COLS);
01255     mpq_EGlpNumReallocArray (&(qslp->upper), qslp->colsize + mpq_EXTRA_COLS);
01256     mpq_EGlpNumReallocArray (&(qslp->obj), qslp->colsize + mpq_EXTRA_COLS);
01257     qslp->colsize += mpq_EXTRA_COLS;
01258   }
01259 
01260   mpq_EGlpNumZero (qslp->obj[ncols]);
01261   mpq_EGlpNumZero (qslp->lower[ncols]);
01262   if (sense == 'E')
01263   {
01264     mpq_EGlpNumZero (qslp->upper[ncols]); /* Artificial */
01265   }
01266   else if (sense == 'R')
01267   {
01268     mpq_EGlpNumCopy (qslp->upper[ncols], range);  /* Range      */
01269   }
01270   else
01271   {
01272     mpq_EGlpNumCopy (qslp->upper[ncols], mpq_ILL_MAXDOUBLE);  /* Slack      */
01273   }
01274 
01275   /* Add new row and new logical col to matrix */
01276 
01277   /* Need to map the structural indices to their proper place */
01278 
01279   if (cnt)
01280   {
01281     ILL_SAFE_MALLOC (tempind, cnt, int);
01282 
01283     for (i = 0; i < cnt; i++)
01284     {
01285       tempind[i] = qslp->structmap[ind[i]];
01286     }
01287   }
01288 
01289   rval = mpq_matrix_addrow (A, cnt, tempind, val);
01290   CHECKRVALG (rval, CLEANUP);
01291 
01292   tind[0] = nrows;
01293   mpq_EGlpNumOne (*tval);
01294   if (sense == 'G' || sense == 'R')
01295     mpq_EGlpNumSign (*tval);
01296 
01297   rval = mpq_matrix_addcol (A, 1, tind, tval);
01298   CHECKRVALG (rval, CLEANUP);
01299 
01300   if (B != 0)
01301   {
01302     B->rstat = EGrealloc (B->rstat, sizeof (char) * (nrows + 1));
01303     //rval = ILLutil_reallocrus_count ((void **) &(B->rstat), nrows + 1,
01304     //                                 sizeof (char));
01305     //CHECKRVALG(rval,CLEANUP);
01306     B->rstat[nrows] = QS_ROW_BSTAT_BASIC;
01307   }
01308 
01309 #if 0
01310   lp->basisid = -1;             /* To get optimizer to reload the basis */
01311 #endif
01312 
01313   qslp->ncols++;
01314   qslp->nrows++;
01315   qslp->nzcount += (cnt + 1);
01316 
01317   if (B != 0)
01318   {
01319     B->nrows++;
01320   }
01321 
01322 CLEANUP:
01323   ILL_IFFREE (tempind, int);
01324 
01325   mpq_EGlpNumClearVar (tval[0]);
01326   EG_RETURN (rval);
01327 }
01328 
01329 int mpq_ILLlib_delrows (
01330   mpq_lpinfo * lp,
01331   mpq_ILLlp_basis * B,
01332   mpq_ILLlp_cache * C,
01333   int num,
01334   int *dellist,
01335   int *basis_ok,
01336   int *cache_ok)
01337 {
01338   int rval = 0;
01339   int i, j, k, nrows, ncols, nstruct, spot, dk, bok = 0, cok = 0;
01340   mpq_ILLlpdata *qslp;
01341   mpq_ILLmatrix *A;
01342   char *rowmark = 0;
01343   char *colmark = 0;
01344   int *newrowindex = 0;
01345   int *newcolindex = 0;
01346   int *ind, *beg, *cnt;
01347   mpq_t *val;
01348 
01349   if (!lp)
01350   {
01351     fprintf (stderr, "mpq_ILLlib_delrows called without an lp\n");
01352     rval = 1;
01353     ILL_CLEANUP;
01354   }
01355 
01356   if (num <= 0)
01357   {
01358     if (basis_ok)
01359       *basis_ok = 1;
01360     if (cache_ok)
01361       *cache_ok = 1;
01362     ILL_CLEANUP;
01363   }
01364 
01365   if (basis_ok)
01366     *basis_ok = 0;
01367   if (cache_ok)
01368     *cache_ok = 0;
01369 
01370   qslp = lp->O;
01371   A = &qslp->A;
01372 
01373   if (qslp->rA)
01374   {                             /* After a delrow call, needs to be updated */
01375     mpq_ILLlp_rows_clear (qslp->rA);
01376     ILL_IFFREE (qslp->rA, mpq_ILLlp_rows);
01377   }
01378 
01379   nrows = A->matrows;
01380   ncols = A->matcols;
01381   ind = A->matind;
01382   beg = A->matbeg;
01383   cnt = A->matcnt;
01384   val = A->matval;
01385   nstruct = qslp->nstruct;
01386 
01387   ILL_SAFE_MALLOC (rowmark, nrows, char);
01388 
01389   for (i = 0; i < nrows; i++)
01390   {
01391     rowmark[i] = 0;
01392   }
01393   for (i = 0; i < num; i++)
01394   {
01395     rowmark[dellist[i]] = 1;
01396   }
01397 
01398 
01399   /* Try to update the basis */
01400 
01401   if (B)
01402   {
01403     bok = 1;
01404     cok = 1;
01405     for (i = 0; i < num; i++)
01406     {
01407       j = dellist[i];
01408       if (B->rstat[j] == QS_ROW_BSTAT_LOWER ||
01409           B->rstat[j] == QS_ROW_BSTAT_UPPER)
01410       {
01411         bok = 0;
01412         break;
01413       }
01414       if (C && mpq_EGlpNumIsLess (mpq_DFEAS_TOLER, C->pi[j]))
01415       {
01416 /*
01417                 printf ("XXXX: Postive pi (%f) at basic row\n", C->pi[j]);
01418                 fflush (stdout);
01419 */
01420         cok = 0;
01421       }
01422     }
01423     if (bok == 1)
01424     {
01425       mpq_EGlpNumFreeArray (B->colnorms);
01426       if (B->rownorms)
01427       {
01428         for (i = 0, k = 0; i < nstruct; i++)
01429         {
01430           if (B->cstat[i] == QS_COL_BSTAT_BASIC)
01431             k++;
01432         }
01433         for (i = 0, j = k; i < nrows; i++)
01434         {
01435           if (B->rstat[i] == QS_ROW_BSTAT_BASIC)
01436           {
01437             if (rowmark[i] == 0)
01438             {
01439               mpq_EGlpNumCopy (B->rownorms[k++], B->rownorms[j]);
01440             }
01441             j++;
01442           }
01443         }
01444         if (k != nrows - num)
01445         {
01446           fprintf (stderr, "error in  mpq_ILLlib_delrows\n");
01447           rval = 1;
01448           ILL_CLEANUP;
01449         }
01450       }
01451 
01452       for (i = 0, j = 0; i < nrows; i++)
01453       {
01454         if (rowmark[i] == 0)
01455         {
01456           B->rstat[j++] = B->rstat[i];
01457         }
01458       }
01459       B->nrows = j;
01460 
01461       if (C && cok == 1)
01462       {
01463         for (i = 0, j = 0; i < nrows; i++)
01464         {
01465           if (rowmark[i] == 0)
01466           {
01467             mpq_EGlpNumCopy (C->pi[j], C->pi[i]);
01468             mpq_EGlpNumCopy (C->slack[j++], C->slack[i]);
01469           }
01470         }
01471         C->nrows = j;
01472         if (cache_ok)
01473           *cache_ok = 1;
01474       }
01475       if (basis_ok)
01476         *basis_ok = 1;
01477     }
01478   }
01479 
01480   ILL_SAFE_MALLOC (newrowindex, nrows, int);
01481 
01482 
01483   /* Delete the marked rows */
01484 
01485   ILL_FAILtrue (qslp->rownames == NULL, "must always be non NULL");
01486   for (i = 0, j = 0; i < nrows; i++)
01487   {
01488     if (rowmark[i] == 0)
01489     {
01490       if (i != j)
01491       {
01492         mpq_EGlpNumCopy (qslp->rhs[j], qslp->rhs[i]);
01493         qslp->sense[j] = qslp->sense[i];
01494         if (qslp->rangeval)
01495           mpq_EGlpNumCopy (qslp->rangeval[j], qslp->rangeval[i]);
01496         if (qslp->rownames)
01497           qslp->rownames[j] = qslp->rownames[i];
01498       }
01499       newrowindex[i] = j++;
01500     }
01501     else
01502     {
01503       if (qslp->rownames)
01504       {
01505         rval = ILLsymboltab_delete (&qslp->rowtab, qslp->rownames[i]);
01506         CHECKRVALG (rval, CLEANUP);
01507         ILL_IFFREE (qslp->rownames[i], char);
01508       }
01509     }
01510   }
01511 
01512 
01513   /* Delete the logicals */
01514 
01515   ILL_SAFE_MALLOC (colmark, ncols, char);
01516 
01517   for (i = 0; i < ncols; i++)
01518   {
01519     colmark[i] = 0;
01520   }
01521   for (i = 0; i < num; i++)
01522   {
01523     colmark[qslp->rowmap[dellist[i]]] = 1;
01524   }
01525 
01526   rval = mpq_delcols_work (lp, colmark);
01527   CHECKRVALG (rval, CLEANUP);
01528 
01529   A->matcols -= num;
01530   qslp->ncols -= num;
01531 
01532 
01533   /* Pack the rowmap  */
01534 
01535   for (i = 0, j = 0; i < nrows; i++)
01536   {
01537     if (rowmark[i] == 0)
01538     {
01539       qslp->rowmap[j++] = qslp->rowmap[i];
01540     }
01541   }
01542 
01543   /* Remove the entries to deleted rows, and update the indices */
01544 
01545   for (i = 0; i < ncols - num; i++)
01546   {
01547     dk = 0;
01548     spot = beg[i];
01549     for (j = 0; j < cnt[i]; j++)
01550     {
01551       if (rowmark[ind[beg[i] + j]] == 1)
01552       {
01553         dk++;
01554       }
01555       else
01556       {
01557         mpq_EGlpNumCopy (val[spot], val[beg[i] + j]);
01558         ind[spot] = newrowindex[ind[beg[i] + j]];
01559         spot++;
01560       }
01561     }
01562     for (; spot < beg[i] + cnt[i]; spot++)
01563     {
01564       ind[spot] = -1;
01565     }
01566 
01567     cnt[i] -= dk;
01568     if (cnt[i] == 0)
01569     {
01570       ind[beg[i]] = 1;          /* we always mark the empty cols */
01571     }
01572   }
01573 
01574   A->matrows -= num;
01575   qslp->nrows -= num;
01576 
01577 #if 0
01578   lp->basisid = -1;             /* To get optimizer to reload the basis */
01579 #endif
01580 
01581   /* if the base is OK, we MUST load the status variables again */
01582   if(bok)
01583   {
01584     rval = mpq_ILLbasis_load( lp, B);
01585     CHECKRVALG (rval, CLEANUP);
01586   }
01587 CLEANUP:
01588 
01589   ILL_IFFREE (rowmark, char);
01590   ILL_IFFREE (colmark, char);
01591   ILL_IFFREE (newcolindex, int);
01592   ILL_IFFREE (newrowindex, int);
01593 
01594   EG_RETURN (rval);
01595 }
01596 
01597 int mpq_ILLlib_delcols (
01598   mpq_lpinfo * lp,
01599   mpq_ILLlp_basis * B,
01600   int num,
01601   int *dellist,
01602   int *basis_ok)
01603 {
01604   int rval = 0;
01605   int i, j, bok = 0, ncols;
01606   char *colmark = 0;
01607   mpq_ILLlpdata *qslp;
01608 
01609   if (!lp)
01610   {
01611     fprintf (stderr, "mpq_ILLlib_delcols called without an lp\n");
01612     rval = 1;
01613     ILL_CLEANUP;
01614   }
01615 
01616   if (basis_ok)
01617     *basis_ok = 0;
01618 
01619   if (num <= 0)
01620   {
01621     *basis_ok = 1;
01622     ILL_CLEANUP;
01623   }
01624 
01625   qslp = lp->O;
01626   ncols = qslp->A.matcols;
01627 
01628   if (qslp->rA)
01629   {                             /* After a delcol call, needs to be updated */
01630     mpq_ILLlp_rows_clear (qslp->rA);
01631     ILL_IFFREE (qslp->rA, mpq_ILLlp_rows);
01632   }
01633 
01634   ILL_SAFE_MALLOC (colmark, ncols, char);
01635 
01636   for (i = 0; i < ncols; i++)
01637   {
01638     colmark[i] = 0;
01639   }
01640   for (i = 0; i < num; i++)
01641   {
01642     colmark[qslp->structmap[dellist[i]]] = 1;
01643   }
01644 
01645   if (B)
01646   {
01647     B->nstruct -= num;
01648     bok = 1;
01649     for (i = 0; i < num; i++)
01650     {
01651       j = dellist[i];
01652       if (B->cstat[j] == QS_COL_BSTAT_BASIC)
01653       {
01654         bok = 0;
01655         //printf ("BONG\n");
01656         //fflush (stdout);
01657         break;
01658       }
01659     }
01660     if (bok == 1)
01661     {
01662       mpq_EGlpNumFreeArray (B->colnorms);
01663       for (i = 0, j = 0; i < qslp->nstruct; i++)
01664       {
01665         if (colmark[qslp->structmap[i]] == 0)
01666         {
01667           B->cstat[j++] = B->cstat[i];
01668         }
01669       }
01670       if (basis_ok)
01671         *basis_ok = 1;
01672     }
01673   }
01674 
01675   rval = mpq_delcols_work (lp, colmark);
01676   CHECKRVALG (rval, CLEANUP);
01677 
01678 
01679   qslp->A.matcols -= num;
01680   qslp->ncols -= num;
01681   qslp->nstruct -= num;
01682 
01683   /* if the base is OK, we MUST load the status variables again */
01684   if(bok)
01685   {
01686     rval = mpq_ILLbasis_load( lp, B);
01687     CHECKRVALG (rval, CLEANUP);
01688   }
01689 #if 0
01690   lp->basisid = -1;             /* To get optimizer to reload the basis */
01691 #endif
01692 
01693 CLEANUP:
01694 
01695   ILL_IFFREE (colmark, char);
01696 
01697   EG_RETURN (rval);
01698 }
01699 
01700 static int mpq_matrix_getcoef (
01701   mpq_ILLmatrix *A, 
01702   int row,
01703   int col,
01704   mpq_t*val)
01705 {
01706   int i;
01707   int rval = 0;
01708   if (row >= A->matrows || row < 0)
01709   {
01710     fprintf (stderr, "illegal row index in mpq_matrix_getcoef\n");
01711     rval= 1;
01712     ILL_CLEANUP;
01713   }
01714 
01715   if (col >= A->matcols || col < 0)
01716   {
01717     fprintf (stderr, "illegal col index in mpq_matrix_getcoef\n");
01718     rval= 1;
01719     ILL_CLEANUP;
01720   }
01721 
01722   /* by default value is zero */
01723   mpq_EGlpNumZero(*val);
01724   for (i = A->matbeg[col]; i < A->matbeg[col] + A->matcnt[col]; i++)
01725   {
01726     if (A->matind[i] == row)
01727     {
01728       mpq_EGlpNumCopy(*val, A->matval[i]);
01729       ILL_CLEANUP;
01730     }
01731   }
01732 
01733 CLEANUP:
01734 
01735   EG_RETURN(rval);
01736 }
01737 
01738 static int mpq_delcols_work (
01739   mpq_lpinfo * lp,
01740   char *colmark)
01741 {
01742   int rval = 0;
01743   int i, j, k, nrows, ncols;
01744   mpq_ILLlpdata *qslp;
01745   mpq_ILLmatrix *A;
01746   int *newcolindex = 0;
01747   int *ind, *beg, *cnt;
01748 
01749   /* Allows logicals to be deleted, to handle call from delcols. */
01750 
01751   qslp = lp->O;
01752   A = &qslp->A;
01753   nrows = A->matrows;
01754   ncols = A->matcols;
01755   ind = A->matind;
01756   beg = A->matbeg;
01757   cnt = A->matcnt;
01758 
01759   ILL_SAFE_MALLOC (newcolindex, ncols, int);
01760 
01761   /* Delete the columns */
01762 
01763   for (i = 0, j = 0; i < ncols; i++)
01764   {
01765     if (colmark[i] == 0)
01766     {
01767       if (i != j)
01768       {
01769         beg[j] = beg[i];
01770         cnt[j] = cnt[i];
01771         mpq_EGlpNumCopy (qslp->obj[j], qslp->obj[i]);
01772         mpq_EGlpNumCopy (qslp->lower[j], qslp->lower[i]);
01773         mpq_EGlpNumCopy (qslp->upper[j], qslp->upper[i]);
01774       }
01775       newcolindex[i] = j++;
01776     }
01777     else
01778     {
01779       for (k = 0; k < cnt[i]; k++)
01780       {
01781         ind[beg[i] + k] = -1;
01782       }
01783       newcolindex[i] = -1;
01784     }
01785   }
01786 
01787   /* Update the struct arrays */
01788 
01789   for (i = 0, j = 0; i < qslp->nstruct; i++)
01790   {
01791     k = qslp->structmap[i];
01792     if (colmark[k] == 0)
01793     {
01794       qslp->structmap[j] = newcolindex[k];
01795       qslp->colnames[j] = qslp->colnames[i];
01796       if (qslp->intmarker)
01797         qslp->intmarker[j] = qslp->intmarker[i];
01798       j++;
01799     }
01800     else
01801     {
01802       rval = ILLsymboltab_delete (&qslp->coltab, qslp->colnames[i]);
01803       CHECKRVALG (rval, CLEANUP);
01804       ILL_IFFREE (qslp->colnames[i], char);
01805     }
01806   }
01807 
01808   /* Update the rowmap: note if logicals deleted, map will be -1 */
01809 
01810   for (i = 0; i < nrows; i++)
01811   {
01812     qslp->rowmap[i] = newcolindex[qslp->rowmap[i]];
01813   }
01814 
01815 CLEANUP:
01816 
01817   ILL_IFFREE (newcolindex, int);
01818 
01819   EG_RETURN (rval);
01820 }
01821 
01822 int mpq_ILLlib_getcoef (
01823   mpq_lpinfo *lp,
01824   int rowindex,
01825   int colindex,
01826   mpq_t* coef)
01827 { 
01828   int rval = 0;
01829   mpq_ILLlpdata *qslp;
01830   mpq_ILLmatrix *A;
01831   int nrows, nstruct, j;
01832   if (!lp)
01833   {
01834     fprintf (stderr, "mpq_ILLlib_chgcoef called without an lp\n");
01835     rval = 1;
01836     ILL_CLEANUP;
01837   }
01838 
01839   qslp = lp->O;
01840   A = &qslp->A;
01841   nrows = qslp->nrows;
01842   nstruct = qslp->nstruct;
01843 
01844   if (rowindex < 0 || rowindex >= nrows || colindex < 0 || colindex >= nstruct)
01845   {
01846     fprintf (stderr, "mpq_ILLlib_getcoef called with out-of-range index\n");
01847     rval = 1;
01848     ILL_CLEANUP;
01849   }
01850   
01851   j = qslp->structmap[colindex];
01852   rval = mpq_matrix_getcoef (A, rowindex, j, coef);
01853   CHECKRVALG(rval, CLEANUP);
01854 
01855 CLEANUP:
01856 
01857   EG_RETURN (rval);
01858 }
01859 
01860 int mpq_ILLlib_chgcoef (
01861   mpq_lpinfo * lp,
01862   int rowindex,
01863   int colindex,
01864   mpq_t coef)
01865 {
01866   int rval = 0;
01867   mpq_ILLlpdata *qslp;
01868   mpq_ILLmatrix *A;
01869   int nrows, nstruct, j;
01870 
01871   if (!lp)
01872   {
01873     fprintf (stderr, "mpq_ILLlib_chgcoef called without an lp\n");
01874     rval = 1;
01875     ILL_CLEANUP;
01876   }
01877 
01878   qslp = lp->O;
01879   A = &qslp->A;
01880 
01881   nrows = qslp->nrows;
01882   nstruct = qslp->nstruct;
01883 
01884   if (rowindex < 0 || rowindex >= nrows || colindex < 0 || colindex >= nstruct)
01885   {
01886     fprintf (stderr, "mpq_ILLlib_chgcoef called with out-of-range index\n");
01887     rval = 1;
01888     ILL_CLEANUP;
01889   }
01890 
01891   if (qslp->rA)
01892   {                             /* After a chgcoef call, needs to be updated */
01893     mpq_ILLlp_rows_clear (qslp->rA);
01894     ILL_IFFREE (qslp->rA, mpq_ILLlp_rows);
01895   }
01896 
01897   if (qslp->sinfo)
01898   {                             /* Presolve LP is no longer valid, free the data */
01899     mpq_ILLlp_sinfo_free (qslp->sinfo);
01900     ILL_IFFREE (qslp->sinfo, mpq_ILLlp_sinfo);
01901   }
01902 
01903   j = qslp->structmap[colindex];
01904 
01905   rval = mpq_matrix_addcoef (lp, A, rowindex, j, coef);
01906   CHECKRVALG (rval, CLEANUP);
01907 
01908 CLEANUP:
01909 
01910   EG_RETURN (rval);
01911 }
01912 
01913 int mpq_ILLlib_chgsense (
01914   mpq_lpinfo * lp,
01915   int num,
01916   int *rowlist,
01917   char *sense)
01918 {
01919   int rval = 0;
01920   int i, j, k;
01921   mpq_ILLlpdata *qslp = lp->O;
01922   mpq_ILLmatrix *A = &(lp->O->A);
01923 
01924   for (i = 0; i < num; i++)
01925   {
01926     j = qslp->rowmap[rowlist[i]];
01927     if (A->matcnt[j] != 1)
01928     {
01929       fprintf (stderr, "logical variable is not a singleton\n");
01930       rval = 1;
01931       ILL_CLEANUP;
01932     }
01933     k = A->matbeg[j];
01934     switch (sense[i])
01935     {
01936     case 'R':                 /* Range constraint, we will set its upper bound
01937                                  once we call mpq_QSchange_range, by default it 
01938                                  will be zero, i.e. an equation. */
01939       qslp->sense[rowlist[i]] = 'R';
01940       mpq_EGlpNumZero(qslp->lower[j]);
01941       mpq_EGlpNumZero(qslp->upper[j]);
01942       mpq_EGlpNumOne(A->matval[k]);
01943       break;
01944     case 'E':                 /* Artificial */
01945       qslp->sense[rowlist[i]] = 'E';
01946       mpq_EGlpNumZero (qslp->lower[j]);
01947       mpq_EGlpNumZero (qslp->upper[j]);
01948       mpq_EGlpNumOne (A->matval[k]);
01949       break;
01950     case 'G':                 /* Surplus   */
01951       qslp->sense[rowlist[i]] = 'G';
01952       mpq_EGlpNumZero (qslp->lower[j]);
01953       mpq_EGlpNumCopy (qslp->upper[j], mpq_ILL_MAXDOUBLE);
01954       mpq_EGlpNumOne (A->matval[k]);
01955       mpq_EGlpNumSign (A->matval[k]);
01956       break;
01957     case 'L':                 /* Slack     */
01958       qslp->sense[rowlist[i]] = 'L';
01959       mpq_EGlpNumZero (qslp->lower[j]);
01960       mpq_EGlpNumCopy (qslp->upper[j], mpq_ILL_MAXDOUBLE);
01961       mpq_EGlpNumOne (A->matval[k]);
01962       break;
01963     default:
01964       fprintf (stderr, "illegal sense %c in mpq_ILLlib_chgsense\n", sense[i]);
01965       rval = 1;
01966       ILL_CLEANUP;
01967     }
01968   }
01969 
01970 CLEANUP:
01971 
01972   EG_RETURN (rval);
01973 }
01974 
01975 int mpq_ILLlib_getsenses (
01976   mpq_lpinfo *lp,
01977   char *senses)
01978 {
01979   mpq_ILLlpdata *qslp;
01980   int nrows, i;
01981   int rval = 0;
01982 
01983   if (!lp) {
01984     fprintf (stderr, "ILLlib_getsense called without an LP\n");
01985     rval = 1;
01986     ILL_CLEANUP;
01987   }
01988 
01989   qslp = lp->O;
01990   nrows = qslp->nrows;
01991 
01992   for (i = 0; i < nrows; i++)
01993   {
01994     senses[i] = qslp->sense[i];
01995   } 
01996 
01997 CLEANUP:
01998 
01999     EG_RETURN(rval);
02000 }
02001 
02002 int mpq_ILLlib_newcol (
02003   mpq_lpinfo * lp,
02004   mpq_ILLlp_basis * B,
02005   const mpq_t obj,
02006   const mpq_t lower,
02007   const mpq_t upper,
02008   const char *name,
02009   int factorok)
02010 {
02011   int rval = 0;
02012 
02013   rval = mpq_ILLlib_addcol (lp, B, 0, 0, 0, obj, lower, upper, name, factorok);
02014   CHECKRVALG (rval, CLEANUP);
02015 
02016 CLEANUP:
02017 
02018   EG_RETURN (rval);
02019 }
02020 
02021 int mpq_ILLlib_newcols (
02022   mpq_lpinfo * lp,
02023   mpq_ILLlp_basis * B,
02024   int num,
02025   mpq_t * obj,
02026   mpq_t * lower,
02027   mpq_t * upper,
02028   const char **names,
02029   int factorok)
02030 {
02031   int rval = 0;
02032   int *cmatcnt = 0;
02033   int *cmatbeg = 0;
02034   int i;
02035 
02036   ILL_SAFE_MALLOC (cmatcnt, num, int);
02037 
02038   ILL_SAFE_MALLOC (cmatbeg, num, int);
02039 
02040   for (i = 0; i < num; i++)
02041   {
02042     cmatcnt[i] = 0;
02043     cmatbeg[i] = 0;
02044   }
02045 
02046   rval = mpq_ILLlib_addcols (lp, B, num, cmatcnt, cmatbeg, 0,
02047                          0, obj, lower, upper, names, factorok);
02048   CHECKRVALG (rval, CLEANUP);
02049 
02050 
02051 CLEANUP:
02052 
02053   ILL_IFFREE (cmatcnt, int);
02054   ILL_IFFREE (cmatbeg, int);
02055 
02056   EG_RETURN (rval);
02057 }
02058 
02059 int mpq_ILLlib_addcols (
02060   mpq_lpinfo * lp,
02061   mpq_ILLlp_basis * B,
02062   int num,
02063   int *cmatcnt,
02064   int *cmatbeg,
02065   int *cmatind,
02066   mpq_t * cmatval,
02067   mpq_t * obj,
02068   mpq_t * lower,
02069   mpq_t * upper,
02070   const char **names,
02071   int factorok)
02072 {
02073   int rval = 0;
02074   int i;
02075 
02076   for (i = 0; i < num; i++)
02077   {
02078     if (names)
02079     {
02080       rval = mpq_ILLlib_addcol (lp, B, cmatcnt[i], cmatind + cmatbeg[i],
02081                             cmatval + cmatbeg[i], obj[i], lower[i],
02082                             upper[i], names[i], factorok);
02083     }
02084     else
02085     {
02086       rval = mpq_ILLlib_addcol (lp, B, cmatcnt[i], cmatind + cmatbeg[i],
02087                             cmatval + cmatbeg[i], obj[i], lower[i],
02088                             upper[i], 0, factorok);
02089     }
02090     CHECKRVALG (rval, CLEANUP);
02091   }
02092 
02093 CLEANUP:
02094 
02095   EG_RETURN (rval);
02096 }
02097 
02098 int mpq_ILLlib_addcol (
02099   mpq_lpinfo * lp,
02100   mpq_ILLlp_basis * B,
02101   int cnt,
02102   int *ind,
02103   mpq_t * val,
02104   const mpq_t obj,
02105   const mpq_t lower,
02106   const mpq_t upper,
02107   const char *name,
02108   int factorok)
02109 {
02110   int rval = 0;
02111   mpq_ILLlpdata *qslp;
02112   mpq_ILLmatrix *A;
02113   int ncols;
02114   char buf[ILL_namebufsize];
02115   int pind, hit;
02116   mpq_t l, u;
02117 
02118   mpq_EGlpNumInitVar (l);
02119   mpq_EGlpNumInitVar (u);
02120 
02121   if (!lp)
02122   {
02123     fprintf (stderr, "mpq_ILLlib_addcol called without an lp\n");
02124     rval = 1;
02125     ILL_CLEANUP;
02126   }
02127 
02128   qslp = lp->O;
02129   A = &qslp->A;
02130   ncols = qslp->ncols;
02131 
02132   if (qslp->rA)
02133   {                             /* After an addcol call, needs to be updated */
02134     mpq_ILLlp_rows_clear (qslp->rA);
02135     ILL_IFFREE (qslp->rA, mpq_ILLlp_rows);
02136   }
02137 
02138   if (qslp->sinfo)
02139   {                             /* Presolve LP is no longer valid, free the data */
02140     mpq_ILLlp_sinfo_free (qslp->sinfo);
02141     ILL_IFFREE (qslp->sinfo, mpq_ILLlp_sinfo);
02142   }
02143 
02144 
02145   /* Add the new variable to the column structures */
02146 
02147   if (qslp->colsize < ncols + 1)
02148   {
02149     mpq_EGlpNumReallocArray (&(qslp->lower), qslp->colsize + mpq_EXTRA_COLS);
02150     mpq_EGlpNumReallocArray (&(qslp->upper), qslp->colsize + mpq_EXTRA_COLS);
02151     mpq_EGlpNumReallocArray (&(qslp->obj), qslp->colsize + mpq_EXTRA_COLS);
02152     qslp->colsize += mpq_EXTRA_COLS;
02153   }
02154 
02155   mpq_EGlpNumCopy (qslp->obj[ncols], obj);
02156   mpq_EGlpNumCopy (qslp->lower[ncols], lower);
02157   mpq_EGlpNumCopy (qslp->upper[ncols], upper);
02158 
02159   /*  Add the variable to the structural arrays */
02160 
02161   if (qslp->structsize < qslp->nstruct + 1)
02162   {
02163     qslp->structmap = EGrealloc (qslp->structmap,
02164                                  sizeof (int) * (qslp->structsize +
02165                                                  mpq_EXTRA_COLS));
02166     //rval = ILLutil_reallocrus_count ((void **) &(qslp->structmap),
02167     //                                 qslp->structsize + mpq_EXTRA_COLS,
02168     //                                 sizeof (int));
02169     //CHECKRVALG(rval,CLEANUP);
02170 
02171     qslp->colnames = EGrealloc (qslp->colnames,
02172                                 sizeof (char *) * (qslp->structsize +
02173                                                    mpq_EXTRA_COLS));
02174     //rval = ILLutil_reallocrus_count ((void **) &(qslp->colnames),
02175     //                                 qslp->structsize + mpq_EXTRA_COLS,
02176     //                                 sizeof (char *));
02177     //CHECKRVALG(rval,CLEANUP);
02178 
02179     if (qslp->intmarker)
02180     {
02181       qslp->intmarker = EGrealloc (qslp->intmarker,
02182                                    sizeof (char) * (qslp->structsize +
02183                                                     mpq_EXTRA_COLS));
02184       //rval = ILLutil_reallocrus_count ((void **) &(qslp->intmarker),
02185       //                                 qslp->structsize + mpq_EXTRA_COLS,
02186       //                                 sizeof (char));
02187       //CHECKRVALG(rval,CLEANUP);
02188     }
02189     qslp->structsize += mpq_EXTRA_COLS;
02190   }
02191 
02192   qslp->structmap[qslp->nstruct] = ncols;
02193   if (qslp->intmarker)
02194   {
02195     /* NOTE: If we want to add integer variables, this is the place. */
02196     qslp->intmarker[qslp->nstruct] = (char) 0;
02197   }
02198 
02199   ILL_FAILtrue (qslp->colnames == NULL, "must always be non NULL");
02200   mpq_ILLlib_findName (qslp, 0 /*isRow */ , name, qslp->nstruct, buf);
02201   ILLsymboltab_register (&qslp->coltab, buf, qslp->nstruct, &pind, &hit);
02202   ILL_FAILfalse ((pind == qslp->nstruct) && (hit == 0), "must be new");
02203   mpq_ILL_UTIL_STR (qslp->colnames[qslp->nstruct], buf);
02204 
02205 
02206   /*  Add col to the matrix */
02207 
02208   rval = mpq_matrix_addcol (A, cnt, ind, val);
02209   CHECKRVALG (rval, CLEANUP);
02210 
02211 
02212   if (B)
02213   {
02214     B->cstat = EGrealloc (B->cstat, sizeof (char) * (qslp->nstruct + 1));
02215     //rval = ILLutil_reallocrus_count ((void **) &(B->cstat),
02216     //                                 qslp->nstruct + 1, sizeof (char));
02217     //CHECKRVALG(rval,CLEANUP);
02218     if (mpq_EGlpNumIsEqual (lower, mpq_ILL_MINDOUBLE, mpq_oneLpNum) &&
02219         mpq_EGlpNumIsEqual (upper, mpq_ILL_MAXDOUBLE, mpq_oneLpNum))
02220     {
02221       B->cstat[qslp->nstruct] = QS_COL_BSTAT_FREE;
02222     }
02223     else if (mpq_EGlpNumIsEqual (upper, mpq_ILL_MAXDOUBLE, mpq_oneLpNum))
02224     {
02225       B->cstat[qslp->nstruct] = QS_COL_BSTAT_LOWER;
02226     }
02227     //else if (lower == mpq_ILL_MAXDOUBLE)
02228     else if (mpq_EGlpNumIsEqual (lower, mpq_ILL_MAXDOUBLE, mpq_oneLpNum))
02229     {
02230       B->cstat[qslp->nstruct] = QS_COL_BSTAT_UPPER;
02231     }
02232     else
02233     {
02234       /*l = fabs (lower);
02235        * u = fabs (upper); */
02236       mpq_EGlpNumCopyAbs (l, lower);
02237       mpq_EGlpNumCopyAbs (u, upper);
02238       if (mpq_EGlpNumIsLess (l, u))
02239       {
02240         B->cstat[qslp->nstruct] = QS_COL_BSTAT_LOWER;
02241       }
02242       else
02243       {
02244         B->cstat[qslp->nstruct] = QS_COL_BSTAT_UPPER;
02245       }
02246     }
02247 
02248     /* UPDATE THE PINF mpq_PRIMAL NORMS */
02249     mpq_EGlpNumFreeArray (B->colnorms);
02250   }
02251 
02252   if (factorok == 0)
02253   {
02254 #if 0
02255     lp->basisid = -1;           /* To get optimizer to reload the basis */
02256 #endif
02257   }
02258   else
02259   {
02260     if (!lp->nbaz || !lp->vindex || !lp->vstat)
02261     {
02262       fprintf (stderr, "ERROR: factorok set without a current basis\n");
02263       rval = 1;
02264       ILL_CLEANUP;
02265     }
02266 
02267     lp->nbaz = EGrealloc (lp->nbaz, sizeof (int) * (qslp->nstruct + 1));
02268     //rval = ILLutil_reallocrus_count ((void **) &(lp->nbaz),
02269     //                                 qslp->nstruct + 1, sizeof (int));
02270     //CHECKRVALG(rval,CLEANUP);
02271 
02272     lp->vindex = EGrealloc (lp->vindex, sizeof (int) * (qslp->ncols + 1));
02273     //rval = ILLutil_reallocrus_count ((void **) &(lp->vindex),
02274     //                                 qslp->ncols + 1, sizeof (int));
02275     //CHECKRVALG(rval,CLEANUP);
02276 
02277     lp->vstat = EGrealloc (lp->vstat, sizeof (int) * (qslp->ncols + 1));
02278     //rval = ILLutil_reallocrus_count ((void **) &(lp->vstat),
02279     //                                 qslp->ncols + 1, sizeof (int));
02280 
02281 
02282     lp->nbaz[qslp->nstruct] = qslp->ncols;
02283     lp->vindex[qslp->ncols] = qslp->nstruct;
02284 
02285     if (mpq_EGlpNumIsEqual (lower, mpq_ILL_MINDOUBLE, mpq_oneLpNum) &&
02286         mpq_EGlpNumIsEqual (upper, mpq_ILL_MAXDOUBLE, mpq_oneLpNum))
02287     {
02288       lp->vstat[qslp->ncols] = STAT_ZERO;
02289     }
02290     else if (mpq_EGlpNumIsEqual (upper, mpq_ILL_MAXDOUBLE, mpq_oneLpNum))
02291     {
02292       lp->vstat[qslp->ncols] = STAT_LOWER;
02293     }
02294     //else if (lower == mpq_ILL_MAXDOUBLE)
02295     else if (mpq_EGlpNumIsEqual (lower, mpq_ILL_MAXDOUBLE, mpq_oneLpNum))
02296     {
02297       lp->vstat[qslp->ncols] = STAT_UPPER;
02298     }
02299     else
02300     {
02301       /*l = fabs (lower);
02302        * u = fabs (upper); */
02303       mpq_EGlpNumCopyAbs (l, lower);
02304       mpq_EGlpNumCopyAbs (u, upper);
02305       if (mpq_EGlpNumIsLess (l, u))
02306       {
02307         lp->vstat[qslp->ncols] = STAT_LOWER;
02308       }
02309       else
02310       {
02311         lp->vstat[qslp->ncols] = STAT_UPPER;
02312       }
02313     }
02314   }
02315 
02316 
02317   qslp->ncols++;
02318   qslp->nstruct++;
02319   (qslp->nzcount) += cnt;
02320 
02321   if (B)
02322   {
02323     B->nstruct++;
02324   }
02325 
02326 CLEANUP:
02327   mpq_EGlpNumClearVar (l);
02328   mpq_EGlpNumClearVar (u);
02329   EG_RETURN (rval);
02330 }
02331 
02332 static int mpq_matrix_addrow (
02333   mpq_ILLmatrix * A,
02334   int rowcnt,
02335   int *rowind,
02336   const mpq_t * rowval)
02337 {
02338   int rval = 0;
02339   int i, j, k, ind, memo, stop, delta = 0;
02340 
02341   /* matsize will be the length of the array.                   */
02342   /* matfree will keep track of the free space at end of array. */
02343 
02344   for (i = 0; i < rowcnt; i++)
02345   {
02346     if (rowind[i] >= A->matcols || rowind[i] < 0)
02347     {
02348       fprintf (stderr, "illegal col index in mpq_matrix_addrow\n");
02349       rval = 1;
02350       ILL_CLEANUP;
02351     }
02352   }
02353 
02354   for (i = 0; i < rowcnt; i++)
02355   {
02356     j = rowind[i];
02357     if (A->matcnt[j] > 0 &&
02358         (A->matbeg[j] + A->matcnt[j] + 1 > A->matsize ||
02359          A->matind[A->matbeg[j] + A->matcnt[j]] != -1))
02360     {
02361       delta += (A->matcnt[j] + 2);  /* 1 for the new coef and 1 for */
02362       /* an extra space               */
02363     }
02364   }
02365 
02366   if (delta < A->matfree)
02367   {
02368     for (i = 0; i < rowcnt; i++)
02369     {
02370       j = rowind[i];
02371       if (A->matcnt[j] == 0)
02372       {
02373         A->matind[A->matbeg[j]] = A->matrows;
02374         mpq_EGlpNumCopy (A->matval[A->matbeg[j]], rowval[i]);
02375         A->matcnt[j] = 1;
02376       }
02377       else if (A->matind[A->matbeg[j] + A->matcnt[j]] == -1)
02378       {
02379         /* Since A->matfree is positive, we know that we are not */
02380         /* sitting at the end of the array.                      */
02381         A->matind[A->matbeg[j] + A->matcnt[j]] = A->matrows;
02382         mpq_EGlpNumCopy (A->matval[A->matbeg[j] + A->matcnt[j]], rowval[i]);
02383         if ((A->matbeg[j] + A->matcnt[j]) == (A->matsize - A->matfree))
02384         {
02385           A->matfree--;         /* at end of used space */
02386         }
02387         (A->matcnt[j])++;
02388       }
02389       else
02390       {
02391         ind = A->matsize - A->matfree + 1;  /* leave space for -1 */
02392         memo = ind;
02393         stop = A->matbeg[j] + A->matcnt[j];
02394         for (k = A->matbeg[j]; k < stop; k++)
02395         {
02396           if (ind >= A->matsize)
02397           {
02398             printf ("WHAT: %d, %d\n", A->matsize, ind);
02399             fflush (stdout);
02400             exit (1);
02401           }
02402           A->matind[ind] = A->matind[k];
02403           mpq_EGlpNumCopy (A->matval[ind], A->matval[k]);
02404           A->matind[k] = -1;
02405           ind++;
02406         }
02407         A->matind[ind] = A->matrows;
02408         mpq_EGlpNumCopy (A->matval[ind], rowval[i]);
02409         A->matbeg[j] = memo;
02410         (A->matcnt[j])++;
02411         (A->matfree) -= (A->matcnt[j] + 1);
02412       }
02413     }
02414   }
02415   else
02416   {
02417     rval = mpq_matrix_addrow_end (A, A->matrows, rowcnt, rowind, rowval);
02418     CHECKRVALG (rval, CLEANUP);
02419   }
02420   A->matrows++;
02421 
02422 CLEANUP:
02423 
02424   EG_RETURN (rval);
02425 }
02426 
02427 static int mpq_matrix_addrow_end (
02428   mpq_ILLmatrix * A,
02429   int row,
02430   int rowcnt,
02431   int *rowind,
02432   const mpq_t * rowval)
02433 {
02434   int rval = 0;
02435   int i, j, k, start, stop, total;
02436   int *newbeg = 0;
02437   int *newind = 0;
02438   mpq_t *newval = 0;
02439   int ncols = A->matcols;
02440 
02441   if (A->matcolsize > 0)
02442   {
02443     ILL_SAFE_MALLOC (newbeg, A->matcolsize, int);
02444   }
02445   ILL_SAFE_MALLOC (newind, A->matsize + rowcnt + mpq_EXTRA_MAT, int);
02446 
02447   newval = mpq_EGlpNumAllocArray (A->matsize + rowcnt + mpq_EXTRA_MAT);
02448 
02449   A->matsize += (rowcnt + mpq_EXTRA_MAT);
02450 
02451   for (i = 0; i < rowcnt; i++)
02452   {
02453     A->matcnt[rowind[i]]++;
02454   }
02455   for (total = 0, j = 0; j < ncols; j++)
02456   {
02457     newbeg[j] = total;
02458     if (A->matcnt[j] > 0)
02459       total += A->matcnt[j];
02460     else
02461       total += 1;
02462   }
02463   for (i = 0; i < rowcnt; i++)
02464   {
02465     A->matcnt[rowind[i]]--;
02466   }
02467   for (j = total; j < A->matsize; j++)
02468   {
02469     newind[j] = -1;
02470   }
02471   A->matfree = A->matsize - total;
02472 
02473   for (j = 0; j < ncols; j++)
02474   {
02475     if (A->matcnt[j] > 0)
02476     {
02477       stop = A->matbeg[j] + A->matcnt[j];
02478       start = newbeg[j];
02479       for (k = A->matbeg[j]; k < stop; k++)
02480       {
02481         newind[start] = A->matind[k];
02482         mpq_EGlpNumCopy (newval[start], A->matval[k]);
02483         start++;
02484       }
02485     }
02486     else
02487     {
02488       newind[newbeg[j]] = 1;
02489     }
02490   }
02491   for (i = 0; i < rowcnt; i++)
02492   {
02493     j = rowind[i];
02494     newind[newbeg[j] + A->matcnt[j]] = row;
02495     mpq_EGlpNumCopy (newval[newbeg[j] + A->matcnt[j]], rowval[i]);
02496     (A->matcnt[j])++;
02497   }
02498 
02499   ILL_IFFREE (A->matbeg, int);
02500   ILL_IFFREE (A->matind, int);
02501 
02502   mpq_EGlpNumFreeArray (A->matval);
02503 
02504   A->matbeg = newbeg;
02505   A->matind = newind;
02506   A->matval = newval;
02507 
02508 CLEANUP:
02509 
02510   if (rval)
02511   {
02512     ILL_IFFREE (newbeg, int);
02513     ILL_IFFREE (newind, int);
02514 
02515     mpq_EGlpNumFreeArray (newval);
02516   }
02517 
02518   EG_RETURN (rval);
02519 }
02520 
02521 static int mpq_matrix_addcoef (
02522   mpq_lpinfo * lp,
02523   mpq_ILLmatrix * A,
02524   int row,
02525   int col,
02526   mpq_t val)
02527 {
02528   int i, k, delta, ind, stop, memo;
02529   int tind[1];
02530   mpq_t tval[1];
02531   int rval = 0;
02532 
02533   mpq_EGlpNumInitVar (tval[0]);
02534   mpq_EGlpNumCopy (tval[0], val);
02535 
02536   if (row >= A->matrows || row < 0)
02537   {
02538     fprintf (stderr, "illegal row index in mpq_matrix_addcoef\n");
02539     rval = 1;
02540     ILL_CLEANUP;
02541   }
02542 
02543   if (col >= A->matcols || col < 0)
02544   {
02545     fprintf (stderr, "illegal col index in mpq_matrix_addcoef\n");
02546     rval = 1;
02547     ILL_CLEANUP;
02548   }
02549 
02550   for (i = A->matbeg[col]; i < A->matbeg[col] + A->matcnt[col]; i++)
02551   {
02552     if (A->matind[i] == row)
02553     {
02554       mpq_EGlpNumCopy (A->matval[i], val);
02555       ILL_CLEANUP;
02556     }
02557   }
02558 
02559   /* The coef is new, we need to add it to A */
02560 
02561   lp->O->nzcount++;
02562   delta = A->matcnt[col] + 2;
02563 
02564   if (A->matcnt[col] == 0)
02565   {
02566     /* First entry, always a free space */
02567     A->matind[A->matbeg[col]] = row;
02568     mpq_EGlpNumCopy (A->matval[A->matbeg[col]], val);
02569     A->matcnt[col] = 1;
02570   }
02571   else if (A->matbeg[col] + A->matcnt[col] < A->matsize &&
02572            A->matind[A->matbeg[col] + A->matcnt[col]] == -1)
02573   {
02574     /* Free space in the column */
02575     A->matind[A->matbeg[col] + A->matcnt[col]] = row;
02576     mpq_EGlpNumCopy (A->matval[A->matbeg[col] + A->matcnt[col]], val);
02577     if ((A->matbeg[col] + A->matcnt[col]) == (A->matsize - A->matfree))
02578     {
02579       A->matfree--;
02580     }
02581     (A->matcnt[col])++;
02582   }
02583   else if (A->matfree > delta)
02584   {
02585     /* Enough space to move column to end of array */
02586     ind = A->matsize - A->matfree + 1;
02587     memo = ind;
02588     stop = A->matbeg[col] + A->matcnt[col];
02589     for (k = A->matbeg[col]; k < stop; k++)
02590     {
02591       A->matind[ind] = A->matind[k];
02592       mpq_EGlpNumCopy (A->matval[ind], A->matval[k]);
02593       A->matind[k] = -1;
02594       ind++;
02595     }
02596     A->matind[ind] = row;
02597     mpq_EGlpNumCopy (A->matval[ind], val);
02598 
02599     A->matbeg[col] = memo;
02600     (A->matcnt[col])++;
02601     (A->matfree) -= (A->matcnt[col] + 1);
02602   }
02603   else
02604   {
02605     /* Need to malloc space to move column to end of array */
02606 
02607     tind[0] = col;
02608 
02609     rval = mpq_matrix_addrow_end (A, row, 1, tind, tval);
02610     CHECKRVALG (rval, CLEANUP);
02611   }
02612 
02613 CLEANUP:
02614 
02615   mpq_EGlpNumClearVar (tval[0]);
02616   EG_RETURN (rval);
02617 }
02618 
02619 static int mpq_matrix_addcol (
02620   mpq_ILLmatrix * A,
02621   int colcnt,
02622   int *colind,
02623   mpq_t * colval)
02624 {
02625   int rval = 0;
02626   int i, ind;
02627 
02628   for (i = 0; i < colcnt; i++)
02629   {
02630     if (colind[i] >= A->matrows || colind[i] < 0)
02631     {
02632       fprintf (stderr, "illegal row index in mpq_matrix_addcol\n");
02633       rval = 1;
02634       ILL_CLEANUP;
02635     }
02636   }
02637 
02638   if (A->matcolsize < A->matcols + 1)
02639   {
02640     A->matbeg =
02641       EGrealloc (A->matbeg, sizeof (int) * (A->matcolsize + mpq_EXTRA_COLS));
02642     //rval = ILLutil_reallocrus_count ((void **) &(A->matbeg),
02643     //                                 A->matcolsize + mpq_EXTRA_COLS, sizeof (int));
02644     //CHECKRVALG(rval,CLEANUP);
02645 
02646     A->matcnt =
02647       EGrealloc (A->matcnt, sizeof (int) * (A->matcolsize + mpq_EXTRA_COLS));
02648     //rval = ILLutil_reallocrus_count ((void **) &(A->matcnt),
02649     //                                 A->matcolsize + mpq_EXTRA_COLS, sizeof (int));
02650     //CHECKRVALG(rval,CLEANUP);
02651 
02652     (A->matcolsize) += mpq_EXTRA_COLS;
02653   }
02654 
02655   if (A->matfree < colcnt + 1)
02656   {
02657     A->matind = EGrealloc (A->matind,
02658                            sizeof (int) * (A->matsize + colcnt + mpq_EXTRA_MAT +
02659                                            1));
02660     //rval = ILLutil_reallocrus_count ((void **) &(A->matind),
02661     //                                 A->matsize + colcnt + mpq_EXTRA_MAT + 1,
02662     //                                 sizeof (int));
02663     //CHECKRVALG(rval,CLEANUP);
02664     mpq_EGlpNumReallocArray (&(A->matval), A->matsize + colcnt + mpq_EXTRA_MAT + 1);
02665 
02666     for (i = 0; i < colcnt + mpq_EXTRA_MAT + 1; i++)
02667     {
02668       A->matind[A->matsize + i] = -1;
02669     }
02670     A->matsize += (colcnt + mpq_EXTRA_MAT + 1);
02671     A->matfree += (colcnt + mpq_EXTRA_MAT + 1);
02672   }
02673 
02674   ind = A->matsize - A->matfree;
02675   A->matbeg[A->matcols] = ind;
02676   A->matcnt[A->matcols] = colcnt;
02677   if (colcnt == 0)
02678   {
02679     A->matind[ind] = 1;         /* Dummy value to stop columns from stealing */
02680     /* this space in addrows.                    */
02681     A->matfree -= 1;
02682   }
02683   else
02684   {
02685     for (i = 0; i < colcnt; i++)
02686     {
02687       mpq_EGlpNumCopy (A->matval[ind], colval[i]);
02688       A->matind[ind] = colind[i];
02689       ind++;
02690     }
02691     A->matfree -= colcnt;
02692   }
02693   A->matcols++;
02694 
02695 CLEANUP:
02696 
02697   EG_RETURN (rval);
02698 }
02699 
02700 int mpq_ILLlib_getrows (
02701   mpq_lpinfo * lp,
02702   int num,
02703   int *rowlist,
02704   int **rowcnt,
02705   int **rowbeg,
02706   int **rowind,
02707   mpq_t ** rowval,
02708   mpq_t ** rhs,
02709   char **sense,
02710   mpq_t ** range,
02711   char ***names)
02712 {
02713   int rval = 0;
02714   int *allbeg = 0;
02715   int *allcnt = 0;
02716   int *allind = 0;
02717   mpq_t *allval = 0;
02718   int i, row, k, start, stop, len, tcnt, cnt = 0;
02719   mpq_ILLlpdata *qslp;
02720   mpq_ILLlp_rows lprows;
02721 
02722   if (rowcnt) *rowcnt = 0;
02723   if (rowbeg) *rowbeg = 0;
02724   if (rowind) *rowind = 0;
02725   if (rowval) *rowval = 0;
02726   if (rhs) *rhs = 0;
02727   if (range) *range = 0;
02728   if (sense) *sense = 0;
02729   if (names) *names = 0;
02730 
02731   if (!lp)
02732   {
02733     fprintf (stderr, "mpq_ILLlib_getrows called without an LP\n");
02734     rval = 1;
02735     ILL_CLEANUP;
02736   }
02737 
02738   if (!num)
02739     ILL_CLEANUP;
02740 
02741   qslp = lp->O;
02742 
02743   rval = mpq_ILLlp_rows_init (&lprows, qslp, 0);
02744   CHECKRVALG (rval, CLEANUP);
02745   allbeg = lprows.rowbeg;
02746   allcnt = lprows.rowcnt;
02747   allind = lprows.rowind;
02748   allval = lprows.rowval;
02749 
02750   for (i = 0; i < num; i++)
02751   {
02752     cnt += allcnt[rowlist[i]];
02753   }
02754 
02755   if (rowcnt)
02756   {
02757     ILL_SAFE_MALLOC (*rowcnt, num, int);
02758 
02759     for (i = 0; i < num; i++)
02760     {
02761       (*rowcnt)[i] = allcnt[rowlist[i]];
02762     }
02763   }
02764 
02765   if (rowbeg)
02766   {
02767     ILL_SAFE_MALLOC (*rowbeg, num, int);
02768 
02769     tcnt = 0;
02770     for (i = 0; i < num; i++)
02771     {
02772       (*rowbeg)[i] = tcnt;
02773       tcnt += allcnt[rowlist[i]];
02774     }
02775   }
02776 
02777   if (cnt && rowind)
02778   {
02779     ILL_SAFE_MALLOC (*rowind, cnt, int);
02780 
02781     tcnt = 0;
02782     for (i = 0; i < num; i++)
02783     {
02784       row = rowlist[i];
02785       start = allbeg[row];
02786       stop = start + allcnt[row];
02787       for (k = start; k < stop; k++)
02788       {
02789         (*rowind)[tcnt++] = allind[k];
02790       }
02791     }
02792   }
02793 
02794   if (cnt && rowval)
02795   {
02796     *rowval = mpq_EGlpNumAllocArray (cnt);
02797     tcnt = 0;
02798     for (i = 0; i < num; i++)
02799     {
02800       row = rowlist[i];
02801       start = allbeg[row];
02802       stop = start + allcnt[row];
02803       for (k = start; k < stop; k++)
02804       {
02805         mpq_EGlpNumCopy ((*rowval)[tcnt++], allval[k]);
02806       }
02807     }
02808   }
02809 
02810   if (rhs)
02811   {
02812     *rhs = mpq_EGlpNumAllocArray (num);
02813     for (i = 0; i < num; i++)
02814     {
02815       mpq_EGlpNumCopy ((*rhs)[i], qslp->rhs[rowlist[i]]);
02816     }
02817   }
02818 
02819   if (range)
02820   {
02821     *range = mpq_EGlpNumAllocArray(num);
02822     if(qslp->rangeval)
02823     {
02824       for(i = 0; i < num ; i++)
02825       {
02826         mpq_EGlpNumCopy((*range)[i], qslp->rangeval[rowlist[i]]);
02827       }
02828     }
02829     else
02830     {
02831       for(i = 0; i < num ; i++)
02832       {
02833         mpq_EGlpNumZero((*range)[i]);
02834       }
02835     }
02836   }
02837 
02838   if (sense)
02839   {
02840     ILL_SAFE_MALLOC (*sense, num, char);
02841 
02842     for (i = 0; i < num; i++)
02843     {
02844       (*sense)[i] = qslp->sense[rowlist[i]];
02845     }
02846   }
02847 
02848   if (names)
02849   {
02850     if (qslp->rownames == 0)
02851     {
02852       fprintf (stderr, "LP does not have row names\n");
02853       rval = 1;
02854       ILL_CLEANUP;
02855     }
02856     ILL_SAFE_MALLOC (*names, num, char *);
02857 
02858     for (i = 0; i < num; i++)
02859     {
02860       (*names)[i] = 0;
02861     }
02862     for (i = 0; i < num; i++)
02863     {
02864       len = strlen (qslp->rownames[rowlist[i]]) + 1;
02865       ILL_SAFE_MALLOC ((*names)[i], len, char);
02866 
02867       strcpy ((*names)[i], qslp->rownames[rowlist[i]]);
02868     }
02869   }
02870 
02871 CLEANUP:
02872 
02873   ILL_IFFREE (allbeg, int);
02874   ILL_IFFREE (allcnt, int);
02875   ILL_IFFREE (allind, int);
02876 
02877   mpq_EGlpNumFreeArray (allval);
02878 
02879   if (rval)
02880   {
02881     if (rowcnt)
02882       ILL_IFFREE (*rowcnt, int);
02883 
02884     if (rowbeg)
02885       ILL_IFFREE (*rowbeg, int);
02886 
02887     if (rowind)
02888       ILL_IFFREE (*rowind, int);
02889 
02890     if (rowval)
02891       mpq_EGlpNumFreeArray (*rowval);
02892     if (rhs)
02893       mpq_EGlpNumFreeArray (*rhs);
02894     if (sense)
02895       ILL_IFFREE (*sense, char);
02896 
02897     if (names && (*names))
02898     {
02899       for (i = 0; i < num; i++)
02900       {
02901         ILL_IFFREE ((*names)[i], char);
02902       }
02903       ILL_IFFREE (*names, char *);
02904     }
02905   }
02906 
02907   EG_RETURN (rval);
02908 }
02909 
02910 int mpq_ILLlib_getcols (
02911   mpq_lpinfo * lp,
02912   int num,
02913   int *collist,
02914   int **colcnt,
02915   int **colbeg,
02916   int **colind,
02917   mpq_t ** colval,
02918   mpq_t ** obj,
02919   mpq_t ** lower,
02920   mpq_t ** upper,
02921   char ***names)
02922 {
02923   int rval = 0;
02924   int i, col, k, start, stop, len, tcnt, cnt = 0;
02925   mpq_ILLlpdata *qslp;
02926   mpq_ILLmatrix *A;
02927   int *tlist = 0;
02928 
02929   if (colcnt)
02930     *colcnt = 0;
02931   if (colbeg)
02932     *colbeg = 0;
02933   if (colind)
02934     *colind = 0;
02935   if (colval)
02936     *colval = 0;
02937   if (lower)
02938     *lower = 0;
02939   if (upper)
02940     *upper = 0;
02941   if (obj)
02942     *obj = 0;
02943   if (names)
02944     *names = 0;
02945 
02946   if (!lp)
02947   {
02948     fprintf (stderr, "mpq_ILLlib_getcols called without an LP\n");
02949     rval = 1;
02950     ILL_CLEANUP;
02951   }
02952 
02953   if (!num)
02954     ILL_CLEANUP;
02955 
02956   qslp = lp->O;
02957   A = &(qslp->A);
02958 
02959   ILL_SAFE_MALLOC (tlist, num, int);
02960 
02961   for (i = 0; i < num; i++)
02962   {
02963     tlist[i] = qslp->structmap[collist[i]];
02964   }
02965 
02966   for (i = 0; i < num; i++)
02967   {
02968     cnt += A->matcnt[tlist[i]];
02969   }
02970 
02971   if (colcnt)
02972   {
02973     ILL_SAFE_MALLOC (*colcnt, num, int);
02974 
02975     for (i = 0; i < num; i++)
02976     {
02977       (*colcnt)[i] = A->matcnt[tlist[i]];
02978     }
02979   }
02980 
02981   if (colbeg)
02982   {
02983     ILL_SAFE_MALLOC (*colbeg, num, int);
02984 
02985     tcnt = 0;
02986     for (i = 0; i < num; i++)
02987     {
02988       (*colbeg)[i] = tcnt;
02989       tcnt += A->matcnt[tlist[i]];
02990     }
02991   }
02992 
02993   if (cnt && colind)
02994   {
02995     ILL_SAFE_MALLOC (*colind, cnt, int);
02996 
02997     tcnt = 0;
02998     for (i = 0; i < num; i++)
02999     {
03000       col = tlist[i];
03001       start = A->matbeg[col];
03002       stop = start + A->matcnt[col];
03003       for (k = start; k < stop; k++)
03004       {
03005         (*colind)[tcnt++] = A->matind[k];
03006       }
03007     }
03008   }
03009 
03010   if (cnt && colval)
03011   {
03012     *colval = mpq_EGlpNumAllocArray (cnt);
03013     tcnt = 0;
03014     for (i = 0; i < num; i++)
03015     {
03016       col = tlist[i];
03017       start = A->matbeg[col];
03018       stop = start + A->matcnt[col];
03019       for (k = start; k < stop; k++)
03020       {
03021         mpq_EGlpNumCopy ((*colval)[tcnt++], A->matval[k]);
03022       }
03023     }
03024   }
03025 
03026   if (obj)
03027   {
03028     *obj = mpq_EGlpNumAllocArray (num);
03029     for (i = 0; i < num; i++)
03030     {
03031       mpq_EGlpNumCopy ((*obj)[i], qslp->obj[tlist[i]]);
03032     }
03033   }
03034 
03035   if (lower)
03036   {
03037     *lower = mpq_EGlpNumAllocArray (num);
03038     for (i = 0; i < num; i++)
03039     {
03040       mpq_EGlpNumCopy ((*lower)[i], qslp->lower[tlist[i]]);
03041     }
03042   }
03043 
03044   if (upper)
03045   {
03046     *upper = mpq_EGlpNumAllocArray (num);
03047     for (i = 0; i < num; i++)
03048     {
03049       mpq_EGlpNumCopy ((*upper)[i], qslp->upper[tlist[i]]);
03050     }
03051   }
03052 
03053   if (names)
03054   {
03055     if (qslp->colnames == 0)
03056     {
03057       fprintf (stderr, "LP does not have col names\n");
03058       rval = 1;
03059       ILL_CLEANUP;
03060     }
03061     ILL_SAFE_MALLOC (*names, num, char *);
03062 
03063     for (i = 0; i < num; i++)
03064     {
03065       (*names)[i] = 0;
03066     }
03067     for (i = 0; i < num; i++)
03068     {
03069       len = strlen (qslp->colnames[collist[i]]) + 1;
03070       ILL_SAFE_MALLOC ((*names)[i], len, char);
03071 
03072       strcpy ((*names)[i], qslp->colnames[collist[i]]);
03073     }
03074   }
03075 
03076 CLEANUP:
03077 
03078   if (rval)
03079   {
03080     if (colcnt)
03081       ILL_IFFREE (*colcnt, int);
03082 
03083     if (colbeg)
03084       ILL_IFFREE (*colbeg, int);
03085 
03086     if (colind)
03087       ILL_IFFREE (*colind, int);
03088 
03089     if (colval)
03090       mpq_EGlpNumFreeArray (*colval);
03091     if (obj)
03092       mpq_EGlpNumFreeArray (*obj);
03093     if (lower)
03094       mpq_EGlpNumFreeArray (*lower);
03095     if (upper)
03096       mpq_EGlpNumFreeArray (*upper);
03097     if (names && (*names))
03098     {
03099       for (i = 0; i < num; i++)
03100       {
03101         ILL_IFFREE ((*names)[i], char);
03102       }
03103       ILL_IFFREE (*names, char *);
03104     }
03105   }
03106   ILL_IFFREE (tlist, int);
03107 
03108   EG_RETURN (rval);
03109 }
03110 
03111 int mpq_ILLlib_getobj_list (
03112   mpq_lpinfo *lp,
03113   int num,
03114   int* collist,
03115   mpq_t* obj)
03116 {
03117   const int*const structmap = lp->O->structmap;
03118   mpq_ILLlpdata *qslp;
03119   int nstruct, j, col;
03120   int rval = 0;
03121   
03122   if (!lp)
03123   {
03124     fprintf (stderr, "mpq_ILLlib_getobj_list called without an LP\n");
03125     rval = 1;
03126     ILL_CLEANUP;
03127   }
03128   
03129   qslp = lp->O;
03130   nstruct = qslp->nstruct;
03131   
03132   for (j = 0; j < num; j++)
03133   {
03134     col = collist[j];
03135     if(col<0 || col >= nstruct)
03136     {
03137       fprintf(stderr, "mpq_ILLlib_getobj_list collist[%d] = %d outside"
03138               " valid range\n", j, col);
03139       rval = 1;
03140       ILL_CLEANUP;
03141     }
03142     mpq_EGlpNumCopy(obj[j],qslp->obj[structmap[col]]);
03143   }  
03144 
03145 CLEANUP:
03146 
03147   EG_RETURN (rval);
03148 }
03149 
03150 
03151 int mpq_ILLlib_getobj (
03152   mpq_lpinfo * lp,
03153   mpq_t * obj)
03154 {
03155   const int*const structmap = lp->O->structmap;
03156   mpq_ILLlpdata *qslp;
03157   int nstruct, j;
03158   int rval = 0;
03159 
03160   if (!lp)
03161   {
03162     fprintf (stderr, "mpq_ILLlib_getobj called without an LP\n");
03163     rval = 1;
03164     ILL_CLEANUP;
03165   }
03166 
03167   qslp = lp->O;
03168   nstruct = qslp->nstruct;
03169 
03170   for (j = 0; j < nstruct; j++)
03171   {
03172     mpq_EGlpNumCopy (obj[j], qslp->obj[structmap[j]]);
03173   }
03174 
03175 CLEANUP:
03176 
03177   EG_RETURN (rval);
03178 }
03179 
03180 int mpq_ILLlib_chgobj (
03181   mpq_lpinfo * lp,
03182   int indx,
03183   mpq_t coef)
03184 {
03185   int rval = 0;
03186   int col;
03187 
03188   if (!lp)
03189   {
03190     fprintf (stderr, "mpq_ILLlib_chgobj called without an lp\n");
03191     rval = 1;
03192     ILL_CLEANUP;
03193   }
03194 
03195   if (indx < 0 || indx >= lp->O->nstruct)
03196   {
03197     fprintf (stderr, "mpq_ILLlib_chgrhs called with bad indx: %d\n", indx);
03198     rval = 1;
03199     ILL_CLEANUP;
03200   }
03201 
03202   if (lp->O->sinfo)
03203   {                             /* Presolve LP is no longer valid, free the data */
03204     mpq_ILLlp_sinfo_free (lp->O->sinfo);
03205     ILL_IFFREE (lp->O->sinfo, mpq_ILLlp_sinfo);
03206   }
03207 
03208   col = lp->O->structmap[indx];
03209   mpq_EGlpNumCopy (lp->O->obj[col], coef);
03210 
03211 CLEANUP:
03212 
03213   EG_RETURN (rval);
03214 }
03215 
03216 int mpq_ILLlib_getrhs (
03217   mpq_lpinfo * lp,
03218   mpq_t * rhs)
03219 {
03220   mpq_ILLlpdata *qslp;
03221   int nrows, i;
03222   int rval = 0;
03223 
03224   if (!lp)
03225   {
03226     fprintf (stderr, "mpq_ILLlib_getrhs called without an LP\n");
03227     rval = 1;
03228     ILL_CLEANUP;
03229   }
03230 
03231   qslp = lp->O;
03232   nrows = qslp->nrows;
03233 
03234   for (i = 0; i < nrows; i++)
03235   {
03236     mpq_EGlpNumCopy (rhs[i], qslp->rhs[i]);
03237   }
03238 
03239 CLEANUP:
03240 
03241   EG_RETURN (rval);
03242 }
03243 
03244 int mpq_ILLlib_chgrange (
03245   mpq_lpinfo *lp,
03246   int indx,
03247   mpq_t coef)
03248 {
03249   register int i;
03250   int rval = 0;
03251   mpq_ILLlpdata *qslp;
03252   
03253   if (!lp)
03254   {
03255     fprintf (stderr, "mpq_ILLlib_chgrhs called without an lp\n");
03256     rval = 1;
03257     ILL_CLEANUP;
03258   }
03259   
03260   if (indx < 0 || indx >= lp->O->nrows)
03261   {
03262     fprintf (stderr, "mpq_ILLlib_chgrhs called with bad indx: %d\n", indx);
03263     rval = 1;
03264     ILL_CLEANUP;
03265   }
03266   
03267   if (lp->O->sinfo)
03268   {/* Presolve LP is no longer valid, free the data */
03269     mpq_ILLlp_sinfo_free (lp->O->sinfo);
03270     ILL_IFFREE (lp->O->sinfo, mpq_ILLlp_sinfo);
03271   }
03272   
03273   qslp = lp->O;
03274   if(qslp->rangeval == 0)
03275   {
03276     qslp->rangeval = mpq_EGlpNumAllocArray(qslp->rowsize);
03277     for( i = qslp->nrows ; i-- ; )
03278     {
03279       mpq_EGlpNumZero(qslp->rangeval[i]);
03280     }
03281   }
03282   
03283   if(qslp->sense[indx] != 'R')
03284   {
03285     fprintf(stderr,"setting range for non-range constraint\n");
03286     rval = 1;
03287     ILL_CLEANUP;
03288   }
03289   
03290   mpq_EGlpNumCopy(qslp->rangeval[indx], coef);
03291 
03292 CLEANUP:
03293 
03294   EG_RETURN (rval);
03295 }
03296 
03297 
03298 int mpq_ILLlib_chgrhs (
03299   mpq_lpinfo * lp,
03300   int indx,
03301   mpq_t coef)
03302 {
03303   int rval = 0;
03304 
03305   if (!lp)
03306   {
03307     fprintf (stderr, "mpq_ILLlib_chgrhs called without an lp\n");
03308     rval = 1;
03309     ILL_CLEANUP;
03310   }
03311 
03312   if (indx < 0 || indx >= lp->O->nrows)
03313   {
03314     fprintf (stderr, "mpq_ILLlib_chgrhs called with bad indx: %d\n", indx);
03315     rval = 1;
03316     ILL_CLEANUP;
03317   }
03318 
03319   if (lp->O->sinfo)
03320   {                             /* Presolve LP is no longer valid, free the data */
03321     mpq_ILLlp_sinfo_free (lp->O->sinfo);
03322     ILL_IFFREE (lp->O->sinfo, mpq_ILLlp_sinfo);
03323   }
03324 
03325   mpq_EGlpNumCopy (lp->O->rhs[indx], coef);
03326 
03327 CLEANUP:
03328 
03329   EG_RETURN (rval);
03330 }
03331 
03332 int mpq_ILLlib_rownames (
03333   mpq_lpinfo * lp,
03334   char **rownames)
03335 {
03336   mpq_ILLlpdata *qslp;
03337   int nrows, len, i, rcount = 0;
03338   int rval = 0;
03339 
03340   if (!lp)
03341   {
03342     fprintf (stderr, "mpq_ILLlib_rownames called without an LP\n");
03343     rval = 1;
03344     ILL_CLEANUP;
03345   }
03346   if (!rownames)
03347   {
03348     fprintf (stderr, "mpq_ILLlib_rownames called with NULL rownames\n");
03349     rval = 1;
03350     ILL_CLEANUP;
03351   }
03352 
03353   qslp = lp->O;
03354   nrows = qslp->nrows;
03355 
03356   if (qslp->rownames == 0)
03357   {
03358     fprintf (stderr, "LP does not have rownames assigned\n");
03359     rval = 1;
03360     ILL_CLEANUP;
03361   }
03362 
03363   for (i = 0; i < nrows; i++)
03364   {
03365     len = strlen (qslp->rownames[i]) + 1;
03366     ILL_SAFE_MALLOC (rownames[i], len, char);
03367 
03368     strcpy (rownames[i], qslp->rownames[i]);
03369     rcount++;
03370   }
03371 
03372 CLEANUP:
03373 
03374   if (rval)
03375   {
03376     for (i = 0; i < rcount; i++)
03377     {
03378       ILL_IFFREE (rownames[i], char);
03379     }
03380   }
03381   EG_RETURN (rval);
03382 }
03383 
03384 int mpq_ILLlib_getintflags (
03385   mpq_lpinfo * lp,
03386   int *intflags)
03387 {
03388   int j, nstruct, rval = 0;
03389   mpq_ILLlpdata *qslp;
03390 
03391   if (!lp)
03392   {
03393     fprintf (stderr, "mpq_ILLlib_getintflags called without an LP\n");
03394     rval = 1;
03395     ILL_CLEANUP;
03396   }
03397 
03398   qslp = lp->O;
03399   nstruct = qslp->nstruct;
03400 
03401   if (qslp->intmarker == 0)
03402   {
03403     for (j = 0; j < nstruct; j++)
03404     {
03405       intflags[j] = 0;
03406     }
03407   }
03408   else
03409   {
03410     for (j = 0; j < nstruct; j++)
03411     {
03412       if (qslp->intmarker[j])
03413       {
03414         intflags[j] = 1;
03415       }
03416       else
03417       {
03418         intflags[j] = 0;
03419       }
03420     }
03421   }
03422 
03423 CLEANUP:
03424 
03425   EG_RETURN (rval);
03426 }
03427 
03428 int mpq_ILLlib_colnames (
03429   mpq_lpinfo * lp,
03430   char **colnames)
03431 {
03432   mpq_ILLlpdata *qslp;
03433   int nstruct, len, i, ccount = 0;
03434   int rval = 0;
03435 
03436   if (!lp)
03437   {
03438     fprintf (stderr, "mpq_ILLlib_colnames called without an LP\n");
03439     rval = 1;
03440     ILL_CLEANUP;
03441   }
03442   if (!colnames)
03443   {
03444     fprintf (stderr, "mpq_ILLlib_colnames called with NULL colnames\n");
03445     rval = 1;
03446     ILL_CLEANUP;
03447   }
03448 
03449   qslp = lp->O;
03450   nstruct = qslp->nstruct;
03451 
03452   if (qslp->colnames == 0)
03453   {
03454     fprintf (stderr, "LP does not have colnames assigned\n");
03455     rval = 1;
03456     ILL_CLEANUP;
03457   }
03458 
03459   for (i = 0; i < nstruct; i++)
03460   {
03461     len = strlen (qslp->colnames[i]) + 1;
03462     ILL_SAFE_MALLOC (colnames[i], len, char);
03463 
03464     strcpy (colnames[i], qslp->colnames[i]);
03465     ccount++;
03466   }
03467 
03468 
03469 CLEANUP:
03470 
03471   if (rval)
03472   {
03473     for (i = 0; i < ccount; i++)
03474     {
03475       ILL_IFFREE (colnames[i], char);
03476     }
03477   }
03478 
03479   EG_RETURN (rval);
03480 }
03481 
03482 static int mpq_reset_colindex (
03483   mpq_lpinfo * lp)
03484 {
03485   int rval = 0;
03486   int test;
03487   mpq_ILLlpdata *qslp = lp->O;
03488 
03489   test = ILLsymboltab_index_ok (&qslp->coltab);
03490   if (!test)
03491   {
03492     rval = ILLsymboltab_index_reset (&qslp->coltab, qslp->nstruct,
03493                                      qslp->colnames);
03494     CHECKRVALG (rval, CLEANUP);
03495   }
03496 
03497 CLEANUP:
03498 
03499   EG_RETURN (rval);
03500 }
03501 
03502 static int mpq_reset_rowindex (
03503   mpq_lpinfo * lp)
03504 {
03505   int rval = 0;
03506   int test;
03507   mpq_ILLlpdata *qslp = lp->O;
03508 
03509   test = ILLsymboltab_index_ok (&qslp->rowtab);
03510   if (!test)
03511   {
03512     rval = ILLsymboltab_index_reset (&qslp->rowtab, qslp->nrows,
03513                                      qslp->rownames);
03514     CHECKRVALG (rval, CLEANUP);
03515   }
03516 
03517 CLEANUP:
03518 
03519   EG_RETURN (rval);
03520 }
03521 
03522 int mpq_ILLlib_colindex (
03523   mpq_lpinfo * lp,
03524   const char *name,
03525   int *colindex)
03526 {
03527   int rval = 0;
03528   mpq_ILLlpdata *qslp;
03529 
03530   *colindex = -1;
03531 
03532   if (!lp)
03533   {
03534     fprintf (stderr, "mpq_ILLlib_colindex called without an LP\n");
03535     rval = 1;
03536     ILL_CLEANUP;
03537   }
03538 
03539   qslp = lp->O;
03540 
03541   rval = mpq_reset_colindex (lp);
03542   CHECKRVALG (rval, CLEANUP);
03543 
03544   rval = ILLsymboltab_getindex (&qslp->coltab, name, colindex);
03545   CHECKRVALG (rval, CLEANUP);
03546 
03547 CLEANUP:
03548 
03549   EG_RETURN (rval);
03550 }
03551 
03552 int mpq_ILLlib_rowindex (
03553   mpq_lpinfo * lp,
03554   const char *name,
03555   int *rowindex)
03556 {
03557   int rval = 0;
03558   mpq_ILLlpdata *qslp;
03559 
03560   *rowindex = -1;
03561 
03562   if (!lp)
03563   {
03564     fprintf (stderr, "mpq_ILLlib_rowindex called without an LP\n");
03565     rval = 1;
03566     ILL_CLEANUP;
03567   }
03568 
03569   qslp = lp->O;
03570 
03571   rval = mpq_reset_rowindex (lp);
03572   CHECKRVALG (rval, CLEANUP);
03573 
03574   rval = ILLsymboltab_getindex (&qslp->rowtab, name, rowindex);
03575   CHECKRVALG (rval, CLEANUP);
03576 
03577 CLEANUP:
03578 
03579   EG_RETURN (rval);
03580 }
03581 
03582 int mpq_ILLlib_getbasis (
03583   mpq_lpinfo * lp,
03584   char *cstat,
03585   char *rstat)
03586 {
03587   int rval = 0;
03588   int i, j, nrows;
03589   mpq_ILLlpdata *qslp;
03590 
03591   if (!lp)
03592   {
03593     fprintf (stderr, "mpq_ILLlib_getbasis called without an LP\n");
03594     rval = 1;
03595     ILL_CLEANUP;
03596   }
03597 
03598   if (lp->basisid == -1)
03599   {
03600     fprintf (stderr, "mpq_ILLlib_getbasis called with modifed LP\n");
03601     rval = 1;
03602     ILL_CLEANUP;
03603   }
03604 
03605   nrows = lp->O->nrows;
03606   qslp = lp->O;
03607 
03608   for (i = 0; i < qslp->nstruct; i++)
03609   {
03610     j = qslp->structmap[i];
03611     switch (lp->vstat[j])
03612     {
03613     case STAT_BASIC:
03614       cstat[i] = QS_COL_BSTAT_BASIC;
03615       break;
03616     case STAT_LOWER:
03617       cstat[i] = QS_COL_BSTAT_LOWER;
03618       break;
03619     case STAT_UPPER:
03620       cstat[i] = QS_COL_BSTAT_UPPER;
03621       break;
03622     case STAT_ZERO:
03623       cstat[i] = QS_COL_BSTAT_FREE;
03624       break;
03625     default:
03626       fprintf (stderr, "unknown vstat in mpq_ILLlib_getbasis: %d\n", lp->vstat[j]);
03627       rval = 1;
03628       ILL_CLEANUP;
03629     }
03630   }
03631 
03632   for (i = 0; i < nrows; i++)
03633   {
03634     j = qslp->rowmap[i];
03635     if (qslp->rangeval && mpq_EGlpNumIsNeqqZero (qslp->rangeval[i]))
03636     {
03637       switch (lp->vstat[j])
03638       {
03639       case STAT_BASIC:
03640         rstat[i] = QS_ROW_BSTAT_BASIC;
03641         break;
03642       case STAT_LOWER:
03643         rstat[i] = QS_ROW_BSTAT_LOWER;
03644         break;
03645       case STAT_UPPER:
03646         rstat[i] = QS_ROW_BSTAT_UPPER;
03647         break;
03648       default:
03649         fprintf (stderr, "unknown vstat in mpq_ILLlib_getbasis 2\n");
03650         rval = 1;
03651         ILL_CLEANUP;
03652       }
03653     }
03654     else
03655     {
03656       switch (lp->vstat[j])
03657       {
03658       case STAT_BASIC:
03659         rstat[i] = QS_ROW_BSTAT_BASIC;
03660         break;
03661       case STAT_UPPER:
03662       case STAT_LOWER:
03663         rstat[i] = QS_ROW_BSTAT_LOWER;
03664         break;
03665       default:
03666         fprintf (stderr, "unknown vstat in mpq_ILLlib_getbasis 3: %d, %d\n",
03667                  i, lp->vstat[j]);
03668         rval = 1;
03669         ILL_CLEANUP;
03670       }
03671     }
03672   }
03673 
03674 CLEANUP:
03675 
03676   EG_RETURN (rval);
03677 }
03678 
03679 int mpq_ILLlib_loadbasis (
03680   mpq_ILLlp_basis * B,
03681   int nstruct,
03682   int nrows,
03683   char *cstat,
03684   char *rstat)
03685 {
03686   int i;
03687   int rval = 0;
03688 
03689   mpq_ILLlp_basis_init (B);
03690 
03691   if (!cstat || !rstat)
03692   {
03693     rval = 1;
03694     CHECKRVALG (rval, CLEANUP);
03695   }
03696 
03697   rval = mpq_ILLlp_basis_alloc (B, nstruct, nrows);
03698   CHECKRVALG (rval, CLEANUP);
03699 
03700   for (i = 0; i < nstruct; i++)
03701   {
03702     B->cstat[i] = cstat[i];
03703   }
03704   for (i = 0; i < nrows; i++)
03705   {
03706     B->rstat[i] = rstat[i];
03707   }
03708 
03709 CLEANUP:
03710 
03711   EG_RETURN (rval);
03712 }
03713 
03714 #define mpq_READ_BASIS_XL 0
03715 #define mpq_READ_BASIS_XU 1
03716 #define mpq_READ_BASIS_LL 2
03717 #define mpq_READ_BASIS_UL 3
03718 
03719 int mpq_ILLlib_readbasis (
03720   mpq_lpinfo * lp,
03721   mpq_ILLlp_basis * B,
03722   const char *mpq_fname)
03723 {
03724   int rval = 0;
03725   mpq_ILLlpdata *qslp = lp->O;
03726   int nstruct = qslp->nstruct;
03727   int nrows = qslp->nrows;
03728   int i, j, end = 0, sec, havename = 0;
03729   int rowtype, row, col;
03730   char *bname = 0;
03731   EGioFile_t *file_in = 0;
03732   mpq_ILLread_mps_state state;
03733   mpq_qsline_reader *in = NULL;
03734 
03735   mpq_ILLlp_basis_init (B);
03736 
03737   ILL_SAFE_MALLOC (B->cstat, qslp->nstruct, char);
03738   ILL_SAFE_MALLOC (B->rstat, qslp->nrows, char);
03739 
03740   B->nstruct = nstruct;
03741   B->nrows = nrows;
03742 
03743   for (j = 0; j < nstruct; j++)
03744   {
03745     B->cstat[j] = QS_COL_BSTAT_LOWER;
03746   }
03747   for (i = 0; i < nrows; i++)
03748   {
03749     B->rstat[i] = QS_ROW_BSTAT_BASIC;
03750   }
03751 
03752   file_in = EGioOpen (mpq_fname, "r");
03753   if (file_in == 0)
03754   {
03755     fprintf (stderr, "unable to open %s for reading\n", mpq_fname);
03756     rval = 1;
03757     ILL_CLEANUP;
03758   }
03759 
03760   in = mpq_ILLline_reader_new ((mpq_qsread_line_fct) EGioGets, file_in);
03761   rval = mpq_ILLmps_state_init (&state, in, mpq_fname);
03762   CHECKRVALG (rval, CLEANUP);
03763 
03764   while (mpq_ILLmps_next_line (&state) == 0)
03765   {
03766     if (mpq_ILLmps_empty_key (&state))
03767     {
03768 
03769       /* Get the XL XU LL UL line */
03770 
03771       if (!havename)
03772       {
03773         rval = mpq_ILLmps_error (&state, "BASIS data before NAME\n");
03774         ILL_CLEANUP;
03775       }
03776 
03777       if (!strcmp (state.field, "XL"))
03778       {
03779         rowtype = mpq_READ_BASIS_XL;
03780       }
03781       else if (!strcmp (state.field, "XU"))
03782       {
03783         rowtype = mpq_READ_BASIS_XU;
03784       }
03785       else if (!strcmp (state.field, "LL"))
03786       {
03787         rowtype = mpq_READ_BASIS_LL;
03788       }
03789       else if (!strcmp (state.field, "UL"))
03790       {
03791         rowtype = mpq_READ_BASIS_UL;
03792       }
03793       else
03794       {
03795         rval = mpq_ILLmps_error (&state, "BASIS \"%s\" is invalid\n", state.field);
03796         ILL_CLEANUP;
03797       }
03798 
03799       if (mpq_ILLmps_next_field (&state) == 0)
03800       {
03801 
03802         rval = mpq_ILLlib_colindex (lp, (const char *) state.field, &col);
03803         CHECKRVALG (rval, CLEANUP);
03804         if (col == -1)
03805         {
03806           rval = mpq_ILLmps_error (&state, "BASIS col not in LP\n");
03807           ILL_CLEANUP;
03808         }
03809 
03810         if (rowtype == mpq_READ_BASIS_XL || rowtype == mpq_READ_BASIS_XU)
03811         {
03812           if (mpq_ILLmps_next_field (&state) == 0)
03813           {
03814             rval = mpq_ILLlib_rowindex (lp, (const char *) state.field, &row);
03815             CHECKRVALG (rval, CLEANUP);
03816             if (row == -1)
03817             {
03818               rval = mpq_ILLmps_error (&state, "BASIS row not in LP\n");
03819               ILL_CLEANUP;
03820             }
03821             if (rowtype == mpq_READ_BASIS_XL)
03822             {
03823               B->cstat[col] = QS_COL_BSTAT_BASIC;
03824               B->rstat[row] = QS_ROW_BSTAT_LOWER;
03825 
03826             }
03827             else
03828             {
03829               B->cstat[col] = QS_COL_BSTAT_BASIC;
03830               B->rstat[row] = QS_ROW_BSTAT_UPPER;
03831             }
03832           }
03833           else
03834           {
03835             rval = mpq_ILLmps_error (&state, "BASIS line needs row and column\n");
03836             ILL_CLEANUP;
03837           }
03838         }
03839         else
03840         {
03841           if (rowtype == mpq_READ_BASIS_LL)
03842           {
03843             B->cstat[col] = QS_COL_BSTAT_LOWER;
03844           }
03845           else
03846           {
03847             B->cstat[col] = QS_COL_BSTAT_UPPER;
03848           }
03849         }
03850       }
03851       else
03852       {
03853         rval = mpq_ILLmps_error (&state, "BASIS line has no row/column\n");
03854         ILL_CLEANUP;
03855       }
03856     }
03857     else
03858     {
03859       /* found a section indicator in col 1 */
03860       if (!strcmp (state.key, mpq_ILLmps_section_name[ILL_MPS_ENDATA]))
03861       {
03862         end = 1;
03863         break;                  /* done reading */
03864       }
03865 
03866       sec = mpq_ILLutil_index (mpq_ILLmps_section_name, state.key);
03867       if (sec < 0 || sec != ILL_MPS_NAME)
03868       {
03869         rval = mpq_ILLmps_error (&state, "BASIS \"%s\" is not a key\n", state.key);
03870         ILL_CLEANUP;
03871       }
03872 
03873       if (havename)
03874       {
03875         rval = mpq_ILLmps_error (&state, "BASIS two name sections\n");
03876         ILL_CLEANUP;
03877       }
03878 
03879       havename = 1;
03880 
03881       if (mpq_ILLmps_empty_field (&state))
03882       {
03883         mpq_ILLmps_warn (&state, "BASIS blank NAME.");
03884       }
03885       else
03886       {
03887         mpq_ILL_UTIL_STR (bname, state.field);
03888         printf ("Basis Name: %s\n", bname);
03889         fflush (stdout);
03890         if (strcmp (bname, qslp->probname))
03891         {
03892           mpq_ILLmps_warn (&state, "BASIS name does not match LP.");
03893         }
03894       }
03895     }
03896   }
03897 
03898   if (!end)
03899   {
03900     mpq_ILLmps_warn (&state, "Missing ENDATA in basis file.");
03901   }
03902   if (!mpq_ILLmps_next_line (&state))
03903   {
03904     mpq_ILLmps_warn (&state, "Ignoring text after ENDATA.");
03905   }
03906 
03907   if (!havename)
03908   {
03909     rval = mpq_ILLmps_error (&state, "BASIS no name section\n");
03910     ILL_CLEANUP;
03911   }
03912 
03913   /* Correct the free variables */
03914 
03915   for (j = 0; j < nstruct; j++)
03916   {
03917     col = lp->O->structmap[j];
03918     if (mpq_EGlpNumIsEqqual (qslp->lower[col], mpq_ILL_MINDOUBLE) &&
03919         mpq_EGlpNumIsEqqual (qslp->upper[col], mpq_ILL_MAXDOUBLE) &&
03920         B->cstat[j] == QS_COL_BSTAT_LOWER)
03921     {
03922       B->cstat[j] = QS_COL_BSTAT_FREE;
03923     }
03924   }
03925 
03926 CLEANUP:
03927 
03928   if (file_in)
03929     EGioClose (file_in);
03930   mpq_ILLline_reader_free (in);
03931 
03932   if (rval)
03933   {
03934     mpq_ILLlp_basis_free (B);
03935   }
03936   ILL_IFFREE (bname, char);
03937 
03938   EG_RETURN (rval);
03939 }
03940 
03941 int mpq_ILLlib_writebasis (
03942   mpq_lpinfo * lp,
03943   mpq_ILLlp_basis * B,
03944   const char *mpq_fname)
03945 {
03946   int rval = 0;
03947   EGioFile_t *out = 0;
03948   char *cstat = 0;
03949   char *rstat = 0;
03950   mpq_ILLlpdata *qslp;
03951   int i, j, nstruct, nrows;
03952 
03953   /* NOTE: non-basic free variables are encoded as non-basic at lower */
03954 
03955   if (!lp)
03956   {
03957     fprintf (stderr, "mpq_ILLlib_writebasis called without an LP\n");
03958     rval = 1;
03959     ILL_CLEANUP;
03960   }
03961   if (!B && lp->basisid == -1)
03962   {
03963     fprintf (stderr, "mpq_ILLlib_writebasis called with unsolved LP\n");
03964     rval = 1;
03965     ILL_CLEANUP;
03966   }
03967 
03968   qslp = lp->O;
03969   nstruct = qslp->nstruct;
03970   nrows = qslp->nrows;
03971 
03972   out = EGioOpen (mpq_fname, "w");
03973   if (out == 0)
03974   {
03975     fprintf (stderr, "unable to open %s for writing\n", mpq_fname);
03976     rval = 1;
03977     ILL_CLEANUP;
03978   }
03979 
03980   if (B)
03981   {
03982     cstat = B->cstat;
03983     rstat = B->rstat;
03984   }
03985   else
03986   {
03987     ILL_SAFE_MALLOC (cstat, nstruct, char);
03988     ILL_SAFE_MALLOC (rstat, nrows, char);
03989 
03990     rval = mpq_ILLlib_getbasis (lp, cstat, rstat);
03991     CHECKRVALG (rval, CLEANUP);
03992   }
03993 
03994   EGioPrintf (out, "NAME    %s\n", qslp->probname);
03995 
03996   /* Pick out the non-basic rows and find a matching basic column */
03997 
03998   i = 0;
03999   j = 0;
04000   do
04001   {
04002     while (i < nrows && rstat[i] == QS_ROW_BSTAT_BASIC)
04003     {
04004       i++;
04005     }
04006     if (i < nrows)
04007     {
04008       while (j < nstruct && cstat[j] != QS_COL_BSTAT_BASIC)
04009       {
04010         j++;
04011       }
04012       if (j == nstruct)
04013       {
04014         /* No basic column to match the non-basic row */
04015         fprintf (stderr, "No basic column to match non-basic row %d\n", i);
04016         rval = 1;
04017         goto CLEANUP;
04018       }
04019 
04020       if (rstat[i] == QS_ROW_BSTAT_LOWER)
04021       {
04022         EGioPrintf (out, " XL %s %s\n", qslp->colnames[j], qslp->rownames[i]);
04023       }
04024       else
04025       {
04026         EGioPrintf (out, " XU %s %s\n", qslp->colnames[j], qslp->rownames[i]);
04027       }
04028       i++;
04029       j++;
04030     }
04031   } while (i < nrows);
04032 
04033   /* Now go through and output the non-basic cols at upper bound */
04034 
04035   for (j = 0; j < nstruct; j++)
04036   {
04037     if (cstat[j] == QS_COL_BSTAT_UPPER)
04038     {
04039       EGioPrintf (out, " UL %s\n", qslp->colnames[j]);
04040     }
04041   }
04042 
04043   EGioPrintf (out, "ENDATA\n");
04044 
04045 CLEANUP:
04046 
04047   if (out)
04048     EGioClose (out);
04049   if (!B)
04050   {
04051     ILL_IFFREE (cstat, char);
04052     ILL_IFFREE (rstat, char);
04053   }
04054   EG_RETURN (rval);
04055 }
04056 
04057 int mpq_ILLlib_getrownorms (
04058   mpq_lpinfo * lp,
04059   mpq_price_info * pinf,
04060   mpq_t * rownorms)
04061 {
04062   int rval = 0;
04063   int i, j, basic = 0;
04064   mpq_ILLlpdata *qslp = lp->O;
04065   int nstruct = lp->O->nstruct;
04066   int nrows = lp->O->nrows;
04067 
04068   mpq_check_pinf (pinf, &rval);
04069   if (rval)
04070   {
04071 /*
04072         fprintf (stderr, "dual steepest mpq_edge norms not available\n");
04073 */
04074     ILL_CLEANUP;
04075   }
04076 
04077   for (i = 0; i < nstruct; i++)
04078   {
04079     j = qslp->structmap[i];
04080     if (lp->vstat[j] == STAT_BASIC)
04081     {
04082       mpq_EGlpNumCopy (rownorms[basic++], pinf->dsinfo.norms[lp->vindex[j]]);
04083     }
04084   }
04085   for (i = 0; i < nrows; i++)
04086   {
04087     j = qslp->rowmap[i];
04088     if (lp->vstat[j] == STAT_BASIC)
04089     {
04090       mpq_EGlpNumCopy (rownorms[basic++], pinf->dsinfo.norms[lp->vindex[j]]);
04091     }
04092   }
04093 
04094   if (basic != nrows)
04095   {
04096     fprintf (stderr, "error in mpq_ILLlib_getrownorms\n");
04097     rval = 1;
04098     ILL_CLEANUP;
04099   }
04100 
04101 CLEANUP:
04102 
04103 /*
04104     EG_RETURN(rval);
04105 */
04106   return rval;                  /* Don't want error message */
04107 }
04108 
04109 int mpq_ILLlib_loadrownorms (
04110   mpq_lpinfo * lp,
04111   mpq_price_info * pinf,
04112   mpq_t * rownorms)
04113 {
04114   int rval = 0;
04115 
04116   rval = mpq_ILLprice_load_rownorms (lp, rownorms, pinf);
04117   CHECKRVALG (rval, CLEANUP);
04118 
04119 CLEANUP:
04120 
04121   EG_RETURN (rval);
04122 }
04123 
04124 int mpq_ILLlib_recompute_rownorms (
04125   mpq_lpinfo * lp,
04126   mpq_price_info * pinf)
04127 {
04128   int rval = 0;
04129 
04130   rval = mpq_ILLprice_build_pricing_info (lp, pinf, DUAL_PHASEII);
04131   CHECKRVALG (rval, CLEANUP);
04132 
04133 CLEANUP:
04134 
04135   EG_RETURN (rval);
04136 }
04137 
04138 int mpq_ILLlib_iter (
04139   mpq_lpinfo * lp)
04140 {
04141   int iter = 0;
04142 
04143   if (lp && lp->cnts)
04144   {
04145     iter = lp->cnts->pI_iter + lp->cnts->pII_iter +
04146       lp->cnts->dI_iter + lp->cnts->dII_iter;
04147   }
04148 
04149   return iter;
04150 }
04151 
04152 //#define mpq_PRINT_TOL 0.000001
04153 #define mpq_PRINT_TOL mpq_PFEAS_TOLER
04154 
04155 int mpq_ILLlib_print_x (
04156   EGioFile_t * fd,
04157   mpq_lpinfo * lp,
04158   mpq_ILLlp_cache * C,
04159   mpq_t * x,
04160   int nonZerosOnly)
04161 {
04162   int rval = 0;
04163   int j;
04164   mpq_ILLlpdata *qslp = lp->O;
04165   mpq_t *dx, *myx = 0;
04166   char *strtmp;
04167 
04168   /* If x is not specified, grab the LP solution */
04169 
04170   if (!x)
04171   {
04172     myx = mpq_EGlpNumAllocArray (lp->ncols);
04173     rval = mpq_ILLlib_get_x (lp, C, myx);
04174     CHECKRVALG (rval, CLEANUP);
04175     dx = myx;
04176   }
04177   else
04178   {
04179     dx = x;
04180   }
04181 
04182   EGioPrintf (fd, "Solution Values\n");
04183   for (j = 0; j < qslp->nstruct; j++)
04184   {
04185     /*if (!nonZerosOnly || dx[j] > mpq_PRINT_TOL || dx[j] < -mpq_PRINT_TOL) */
04186     if (!nonZerosOnly || mpq_EGlpNumIsNeqZero (dx[j], mpq_PRINT_TOL))
04187     {
04188       strtmp = mpq_EGlpNumGetStr (dx[j]);
04189       ILL_FAILfalse (qslp->colnames[j] != NULL, "no NULL names PLEASE!");
04190       EGioPrintf (fd, "%s = %s\n", qslp->colnames[j], strtmp);
04191       EGioFlush (fd);
04192       EGfree (strtmp);
04193     }
04194   }
04195 
04196 CLEANUP:
04197   mpq_EGlpNumFreeArray (myx);
04198   EG_RETURN (rval);
04199 }
04200 
04201 int mpq_ILLlib_findName (
04202   mpq_ILLlpdata * qslp,
04203   int forRow,
04204   const char *name,
04205   int id,
04206   char buf[ILL_namebufsize])
04207 {
04208   ILLsymboltab *tab;
04209   const char *mode;
04210   const char *p1, *p2;
04211   int sind, rval = 0;
04212 
04213   id++;
04214   tab = (forRow) ? &qslp->rowtab : &qslp->coltab;
04215   if (tab->tablesize == 0)
04216     ILLsymboltab_create (tab, 100);
04217   p1 = (forRow) ? "c" : "x";
04218   p2 = (forRow) ? "c_" : "x_";
04219   mode = (forRow) ? "row" : "column";
04220   if (name == 0)
04221   {
04222     ILLsymboltab_unique_name (tab, id, p1, buf);
04223     /*
04224      * fprintf(stderr, "Generating %s name \"%s\".\n", mode, buf); 
04225      */
04226   }
04227   else
04228   {
04229     strcpy (buf, name);
04230   }
04231   if (!ILLsymboltab_lookup (tab, buf, &sind))
04232   {
04233     rval = ILLsymboltab_uname (&qslp->rowtab, buf, p1, p2);
04234     if (name != NULL)
04235     {
04236       fprintf (stderr, "Changing %s name \"%s\" to \"%s\".\n", mode, name, buf);
04237     }
04238     CHECKRVALG (rval, CLEANUP);
04239   }
04240 CLEANUP:
04241   EG_RETURN (rval);
04242 }
04243 
04244 int mpq_ILLwrite_lp_file (
04245   mpq_ILLlpdata * lp,
04246   EGioFile_t * out,
04247   mpq_qserror_collector * c)
04248 {
04249   int rval = 0;
04250   qsstring_reporter rep;
04251 
04252   ILLstring_reporter_copy (&rep, &lp->reporter);
04253   ILLstring_reporter_init (&lp->reporter, (qsreport_string_fct) EGioWrite, out);
04254   rval = mpq_ILLwrite_lp (lp, c);
04255   ILLstring_reporter_copy (&lp->reporter, &rep);
04256   return rval;
04257 }
04258 
04259 static void mpq_check_pinf (
04260   mpq_price_info * pinf,
04261   int *it_exists)
04262 {
04263   if (!pinf || pinf->dI_price != QS_PRICE_DSTEEP ||
04264       pinf->dII_price != QS_PRICE_DSTEEP || pinf->dsinfo.norms == 0)
04265   {
04266     *it_exists = 1;
04267   }
04268   else
04269   {
04270     *it_exists = 0;
04271   }
04272 }
04273 
04274 #if 0
04275 static int test_matrix (
04276   mpq_ILLmatrix * A)
04277 {
04278   int rval = 0;
04279   int i, j, k;
04280   int ncols = A->matcols;
04281   int nrows = A->matrows;
04282   int matsize = A->matsize;
04283   int *mbeg = A->matbeg;
04284   int *mcnt = A->matcnt;
04285   int *mind = A->matind;
04286   int *tempi = 0;
04287 
04288 
04289   if (matsize == 0)
04290     ILL_CLEANUP;
04291 
04292   ILL_SAFE_MALLOC (tempi, matsize, int);
04293 
04294   for (i = 0; i < matsize; i++)
04295     tempi[i] = 0;
04296 
04297   for (i = 0; i < ncols; i++)
04298   {
04299     for (j = 0; j < mcnt[i]; j++)
04300     {
04301       k = mind[mbeg[i] + j];
04302       if (k < 0 || k >= nrows)
04303       {
04304         printf ("ERROR IN MATRIX: %d\n", k);
04305         printf ("ncols = %d, bad col = %d\n", ncols, i);
04306         printf ("bad cnt = %d, bad index = %d\n", mcnt[i], mbeg[i] + j);
04307         printf ("matcolsize = %d, matsize = %d\n", A->matcolsize, A->matsize);
04308         rval = 1;
04309         ILL_CLEANUP;
04310       }
04311       if (tempi[mbeg[i] + j] != 0)
04312       {
04313         printf ("ERROR: over written matrix\n");
04314         printf ("ncols = %d, bad col = %d\n", ncols, i);
04315         printf ("nrows = %d\n", nrows);
04316         printf ("bad cnt = %d, bad index = %d\n", mcnt[i], mbeg[i] + j);
04317         rval = 1;
04318         ILL_CLEANUP;
04319       }
04320       else
04321       {
04322         tempi[mbeg[i] + j] = 1;
04323       }
04324     }
04325   }
04326 
04327   for (i = A->matsize - A->matfree; i < A->matsize; i++)
04328   {
04329     if (tempi[i] != 0)
04330     {
04331       printf ("ERROR: free space is being used\n");
04332       rval = 1;
04333       ILL_CLEANUP;
04334     }
04335   }
04336 
04337 CLEANUP:
04338 
04339   ILL_IFFREE (tempi, int);
04340 
04341   EG_RETURN (rval);
04342 }
04343 #endif

Generated on Thu Mar 29 09:32:32 2012 for QSopt_ex by  doxygen 1.4.7