float128_rawlp.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: float128_rawlp.c,v $ $Revision: 1.2 $ $Date: 2003/11/05 16:49:52 $"; */
00024 /****************************************************************************/
00025 /* DataStructure and routines to deal with raw lp information as read       */
00026 /* from mps or lp files.                                                    */
00027 /****************************************************************************/
00028 
00029 #include "qs_config.h"
00030 #include "config.h"
00031 #include "float128_sortrus.h"
00032 #include "float128_iqsutil.h"
00033 #include "float128_rawlp.h"
00034 #include "allocrus.h"
00035 #ifdef USEDMALLOC
00036 #include "dmalloc.h"
00037 #endif
00038 static int TRACE = 0;
00039 
00040 ILL_PTRWORLD_ROUTINES (float128_colptr, colptralloc, colptr_bulkalloc, colptrfree)
00041 ILL_PTRWORLD_LISTFREE_ROUTINE (float128_colptr, colptr_listfree, colptrfree)
00042 ILL_PTRWORLD_LEAKS_ROUTINE (float128_colptr, colptr_check_leaks, this_val, int)
00043      const int float128_ILL_SOS_TYPE1 = 1;
00044      const int float128_ILL_SOS_TYPE2 = 2;
00045 
00046      static void float128_ILLprt_EGlpNum (
00047   FILE * f,
00048   float128 * d)
00049 {
00050   if (float128_EGlpNumIsLeq (float128_ILL_MAXDOUBLE, *d))
00051   {
00052     fprintf (f, "MAX_DOUBLE");
00053   }
00054   else
00055   {
00056     if (float128_EGlpNumIsLeq (*d, float128_ILL_MINDOUBLE))
00057     {
00058       fprintf (f, "-MAX_DOUBLE");
00059     }
00060     else
00061     {
00062       fprintf (f, "%f", float128_EGlpNumToLf (*d));
00063     }
00064   }
00065 }
00066 
00067 static int float128_ILLraw_check_bounds (
00068   float128_rawlpdata * lp);
00069 
00070 void float128_ILLinit_rawlpdata (
00071   float128_rawlpdata * lp,
00072   float128_qserror_collector * collector)
00073 {
00074   if (lp)
00075   {
00076     lp->name = 0;
00077     lp->ncols = 0;
00078     lp->nrows = 0;
00079     lp->cols = 0;
00080     lp->rowsense = 0;
00081     lp->rhsname = 0;
00082     lp->rhs = 0;
00083     lp->rhsind = 0;
00084     lp->rangesname = 0;
00085     lp->rangesind = 0;
00086     lp->ranges = 0;
00087     lp->boundsname = 0;
00088     lp->lbind = 0;
00089     lp->ubind = 0;
00090     lp->lower = 0;
00091     lp->upper = 0;
00092     lp->intmarker = 0;
00093     lp->colsize = 0;
00094     lp->sensesize = 0;
00095     lp->intsize = 0;
00096     lp->rhssize = 0;
00097     lp->refrow = NULL;
00098     lp->is_sos_size = 0;
00099     lp->is_sos_member = NULL;
00100     lp->nsos_member = 0;
00101     lp->sos_weight_size = 0;
00102     lp->sos_weight = NULL;
00103     lp->sos_col_size = 0;
00104     lp->sos_col = NULL;
00105     lp->nsos = 0;
00106     lp->sos_setsize = 0;
00107     lp->sos_set = NULL;
00108     ILLsymboltab_init (&lp->coltab);
00109     ILLsymboltab_init (&lp->rowtab);
00110     lp->objindex = -1;
00111     lp->objsense = float128_ILL_MIN;
00112     lp->refrowind = -1;         /* undefined */
00113     ILLptrworld_init (&lp->ptrworld);
00114     lp->error_collector = collector;
00115   }
00116 }
00117 
00118 void float128_ILLraw_clear_matrix (
00119   float128_rawlpdata * lp)
00120 {
00121   int i;
00122   float128_colptr *next, *curr;
00123 
00124   if ((lp != NULL) && (lp->cols != NULL))
00125   {
00126     for (i = 0; i < lp->ncols; i++)
00127     {
00128       {
00129         curr = lp->cols[i];
00130         while (curr)
00131         {
00132           next = curr->next;
00133           float128_EGlpNumClearVar ((curr->coef));
00134           colptrfree (&(lp->ptrworld), curr);
00135           curr = next;
00136         }
00137       }
00138       //colptr_listfree (&lp->ptrworld, lp->cols[i]);
00139       lp->cols[i] = NULL;
00140     }
00141   }
00142 }
00143 
00144 void float128_ILLfree_rawlpdata (
00145   float128_rawlpdata * lp)
00146 {
00147   int total, onlist;
00148   float128_colptr *next, *curr;
00149 
00150   if (lp)
00151   {
00152     ILL_IFFREE (lp->name, char);
00153 
00154     ILLsymboltab_free (&lp->rowtab);
00155     ILLsymboltab_free (&lp->coltab);
00156     ILL_IFFREE (lp->rowsense, char);
00157 
00158     float128_ILLraw_clear_matrix (lp);
00159     ILL_IFFREE (lp->cols, float128_colptr *);
00160     {
00161       curr = lp->ranges;
00162       while (curr)
00163       {
00164         next = curr->next;
00165         float128_EGlpNumClearVar ((curr->coef));
00166         colptrfree (&(lp->ptrworld), curr);
00167         curr = next;
00168       }
00169     }
00170     //colptr_listfree (&lp->ptrworld, lp->ranges);
00171     if (colptr_check_leaks (&lp->ptrworld, &total, &onlist))
00172     {
00173       fprintf (stderr, "WARNING: %d outstanding colptrs\n", total - onlist);
00174     }
00175     ILLptrworld_delete (&lp->ptrworld);
00176     ILL_IFFREE (lp->rhsname, char);
00177 
00178     float128_EGlpNumFreeArray (lp->rhs);
00179     ILL_IFFREE (lp->rhsind, char);
00180     ILL_IFFREE (lp->rangesname, char);
00181     ILL_IFFREE (lp->rangesind, char);
00182     ILL_IFFREE (lp->boundsname, char);
00183     ILL_IFFREE (lp->lbind, char);
00184     ILL_IFFREE (lp->ubind, char);
00185 
00186     float128_EGlpNumFreeArray (lp->lower);
00187     float128_EGlpNumFreeArray (lp->upper);
00188     ILL_IFFREE (lp->intmarker, char);
00189     ILL_IFFREE (lp->refrow, char);
00190     ILL_IFFREE (lp->is_sos_member, int);
00191 
00192     float128_EGlpNumFreeArray (lp->sos_weight);
00193     ILL_IFFREE (lp->sos_col, int);
00194 
00195     ILL_IFFREE (lp->sos_set, float128_sosptr);
00196     float128_ILLinit_rawlpdata (lp, NULL);
00197   }
00198 }
00199 
00200 const char *float128_ILLraw_rowname (
00201   float128_rawlpdata * lp,
00202   int i)
00203 {
00204   const char *name = NULL;
00205 
00206   ILL_FAILfalse_no_rval ((i >= 0) && (i < lp->nrows), "index out of range");
00207   ILL_FAILfalse_no_rval (lp->nrows == lp->rowtab.tablesize,
00208                          "tab and lp must be in synch");
00209   name = ILLsymboltab_get (&lp->rowtab, i);
00210 CLEANUP:
00211   return name;
00212 }
00213 const char *float128_ILLraw_colname (
00214   float128_rawlpdata * lp,
00215   int i)
00216 {
00217   const char *name = NULL;
00218 
00219   ILL_FAILfalse_no_rval ((i >= 0) && (i < lp->ncols), "index out of range");
00220   ILL_FAILfalse_no_rval (lp->ncols == lp->coltab.tablesize,
00221                          "tab and lp must be in synch");
00222   name = ILLsymboltab_get (&lp->coltab, i);
00223 CLEANUP:
00224   return name;
00225 }
00226 
00227 int float128_ILLraw_add_col (
00228   float128_rawlpdata * lp,
00229   const char *name,
00230   int intmarker)
00231 {
00232   int rval = 0;
00233   int pindex, hit;
00234 
00235   rval = ILLsymboltab_register (&lp->coltab, name, -1, &pindex, &hit);
00236   rval = rval || hit;
00237   ILL_CLEANUP_IF (rval);
00238   if (lp->ncols >= lp->colsize)
00239   {
00240     lp->colsize *= 1.3;
00241     lp->colsize += 1000;
00242     if (lp->colsize < lp->ncols + 1)
00243       lp->colsize = lp->ncols + 1;
00244     lp->cols = EGrealloc (lp->cols, lp->colsize * sizeof (float128_colptr *));
00245     //rval = rval || ILLutil_reallocrus_scale (&lp->cols,
00246     //                                         &lp->colsize, lp->ncols + 1, 1.3,
00247     //                                         sizeof (float128_colptr *));
00248   }
00249   if (lp->ncols >= lp->intsize)
00250   {
00251     lp->intsize *= 1.3;
00252     lp->intsize += 1000;
00253     if (lp->intsize < lp->ncols + 1)
00254       lp->intsize = lp->ncols + 1;
00255     lp->intmarker = EGrealloc (lp->intmarker, lp->intsize * sizeof (char));
00256     //rval = rval || ILLutil_reallocrus_scale ((void **) &lp->intmarker,
00257     //                                         &lp->intsize, lp->ncols + 1,
00258     //                                         1.3, sizeof (char));
00259   }
00260   if (lp->ncols >= lp->is_sos_size)
00261   {
00262     lp->is_sos_size *= 1.3;
00263     lp->is_sos_size += 1000;
00264     if (lp->is_sos_size < lp->ncols + 1)
00265       lp->is_sos_size = lp->ncols + 1;
00266     lp->is_sos_member = EGrealloc (lp->is_sos_member,
00267                                    sizeof (int) * lp->is_sos_size);
00268     //rval = rval || ILLutil_reallocrus_scale ((void **) &lp->is_sos_member,
00269     //                                         &lp->is_sos_size, lp->ncols + 1,
00270     //                                         1.3, sizeof (int));
00271   }
00272   ILL_CLEANUP_IF (rval);
00273   lp->cols[lp->ncols] = 0;
00274   lp->is_sos_member[lp->ncols] = -1;
00275   lp->intmarker[lp->ncols] = intmarker;
00276   lp->ncols++;
00277 CLEANUP:
00278   ILL_RETURN (rval, "float128_ILLraw_add_col");
00279 }
00280 
00281 int float128_ILLraw_init_rhs (
00282   float128_rawlpdata * lp)
00283 {
00284   int i, rval = 0;
00285 
00286   ILL_FAILfalse (lp->rhsind == NULL, "Should be called exactly once");
00287   if (lp->nrows > 0)
00288   {
00289     ILL_SAFE_MALLOC (lp->rhsind, lp->nrows, char);
00290 
00291     for (i = 0; i < lp->nrows; i++)
00292     {
00293       lp->rhsind[i] = (char) 0;
00294     }
00295   }
00296 CLEANUP:
00297   ILL_RETURN (rval, "float128_ILLraw_init_rhs");
00298 }
00299 
00300 int float128_ILLraw_init_ranges (
00301   float128_rawlpdata * lp)
00302 {
00303   int i, rval = 0;
00304 
00305   ILL_FAILfalse (lp->rangesind == NULL, "Should be called exactly once");
00306   if (lp->nrows > 0)
00307   {
00308     ILL_SAFE_MALLOC (lp->rangesind, lp->nrows, char);
00309 
00310     for (i = 0; i < lp->nrows; i++)
00311     {
00312       lp->rangesind[i] = (char) 0;
00313     }
00314   }
00315 CLEANUP:
00316   ILL_RETURN (rval, "float128_ILLraw_init_ranges");
00317 }
00318 
00319 int float128_ILLraw_add_col_coef (
00320   float128_rawlpdata * lp,
00321   int colind,
00322   int rowind,
00323   float128 coef)
00324 {
00325   float128_colptr *cp = float128_ILLcolptralloc (&lp->ptrworld);
00326 
00327   if (!cp)
00328   {
00329     return 1;
00330   }
00331   cp->this_val = rowind;
00332   float128_EGlpNumCopy (cp->coef, coef);
00333   cp->next = lp->cols[colind];
00334   lp->cols[colind] = cp;
00335   return 0;
00336 }
00337 
00338 
00339 int float128_ILLraw_add_ranges_coef (
00340   float128_rawlpdata * lp,
00341   int rowind,
00342   float128 coef)
00343 {
00344   float128_colptr *cp = float128_ILLcolptralloc (&lp->ptrworld);
00345 
00346   if (!cp)
00347   {
00348     return 1;
00349   }
00350   cp->this_val = rowind;
00351   float128_EGlpNumCopy (cp->coef, coef);
00352   cp->next = lp->ranges;
00353   lp->ranges = cp;
00354   lp->rangesind[rowind] = (char) 1;
00355   return 0;
00356 }
00357 
00358 int float128_ILLraw_add_sos (
00359   float128_rawlpdata * lp,
00360   int tp)
00361 {
00362   int rval = 0;
00363   float128_sosptr *sos, *bef;
00364 
00365   if (lp->nsos >= lp->sos_setsize)
00366   {
00367     lp->sos_setsize *= 1.3;
00368     lp->sos_setsize += 1000;
00369     if (lp->sos_setsize < lp->nsos + 1)
00370       lp->sos_setsize = lp->nsos + 1;
00371     lp->sos_set = EGrealloc (lp->sos_set, sizeof (float128_sosptr *) * lp->sos_setsize);
00372     //if (ILLutil_reallocrus_scale ((void **) &lp->sos_set,
00373     //                              &lp->sos_setsize, lp->nsos + 1, 1.3,
00374     //                              sizeof (float128_sosptr *)))
00375     //{
00376     //  ILL_CLEANUP_IF (rval);
00377     //}
00378   }
00379   sos = lp->sos_set + lp->nsos;
00380   sos->nelem = 0;
00381   sos->type = tp;
00382   if (lp->nsos == 0)
00383   {
00384     sos->first = 0;
00385   }
00386   else
00387   {
00388     bef = &(lp->sos_set[lp->nsos - 1]);
00389     sos->first = bef->first + bef->nelem;
00390   }
00391   lp->nsos++;
00392 //CLEANUP:
00393   ILL_RETURN (rval, "float128_ILLraw_add_sos");
00394 }
00395 
00396 int float128_ILLraw_is_mem_other_sos (
00397   float128_rawlpdata * lp,
00398   int colind)
00399 {
00400   return (lp->is_sos_member[colind] >= 0) &&
00401     (lp->is_sos_member[colind] != (lp->nsos - 1));
00402 }
00403 
00404 int float128_ILLraw_add_sos_member (
00405   float128_rawlpdata * lp,
00406   int colind)
00407 {
00408   int rval = 0;
00409 
00410   ILL_FAILfalse (lp->nsos > 0, "we should have called float128_ILLraw_add_sos earlier");
00411   ILL_FAILtrue (float128_ILLraw_is_mem_other_sos (lp, colind),
00412                 "colind is member of another sos set");
00413 
00414   if (lp->is_sos_member[colind] == -1)
00415   {
00416     if (lp->nsos_member >= lp->sos_weight_size)
00417     {
00418       lp->sos_weight_size *= 1.3;
00419       lp->sos_weight_size += 1000;
00420       if (lp->sos_weight_size < lp->nsos_member + 1)
00421         lp->sos_weight_size = lp->nsos_member + 1;
00422       lp->sos_weight = EGrealloc (lp->sos_weight,
00423                                   lp->sos_weight_size * sizeof (double));
00424       //if (ILLutil_reallocrus_scale ((void **) &lp->sos_weight,
00425       //                              &lp->sos_weight_size,
00426       //                              lp->nsos_member + 1, 1.3, sizeof (double)))
00427       //{
00428       //  ILL_CLEANUP_IF (rval);
00429       //}
00430     }
00431     if (lp->nsos_member >= lp->sos_col_size)
00432     {
00433       lp->sos_col_size *= 1.3;
00434       lp->sos_col_size += 1000;
00435       if (lp->sos_col_size < lp->nsos_member + 1)
00436         lp->sos_col_size = lp->nsos_member + 1;
00437       lp->sos_col = EGrealloc (lp->sos_col, sizeof (int) * lp->sos_col_size);
00438       //if (ILLutil_reallocrus_scale ((void **) &lp->sos_col,
00439       //                              &lp->sos_col_size,
00440       //                              lp->nsos_member + 1, 1.3, sizeof (int)))
00441       //{
00442       //  ILL_CLEANUP_IF (rval);
00443       //}
00444     }
00445     lp->sos_col[lp->nsos_member] = colind;
00446     lp->sos_set[lp->nsos - 1].nelem++;
00447     lp->is_sos_member[colind] = lp->nsos - 1;
00448     lp->nsos_member++;
00449   }
00450 CLEANUP:
00451   ILL_RETURN (rval, "float128_ILLraw_add_sos_member");
00452 }
00453 
00454 
00455 int float128_ILLraw_add_row (
00456   float128_rawlpdata * lp,
00457   const char *name,
00458   int sense,
00459   const float128 rhs)
00460 {
00461   int pindex, hit, rval = 0;
00462 
00463   rval = ILLsymboltab_register (&lp->rowtab, name, -1, &pindex, &hit);
00464   rval = rval || hit;
00465   ILL_CLEANUP_IF (rval);
00466   if (lp->nrows >= lp->sensesize)
00467   {
00468     lp->sensesize *= 1.3;
00469     lp->sensesize += 1000;
00470     if (lp->sensesize < lp->nrows + 1)
00471       lp->sensesize = lp->nrows + 1;
00472     lp->rowsense = EGrealloc (lp->rowsense, sizeof (char) * lp->sensesize);
00473     //if (ILLutil_reallocrus_scale ((void **) &lp->rowsense,
00474     //                              &lp->sensesize, lp->nrows + 1,
00475     //                              1.3, sizeof (char)))
00476     //{
00477     //  ILL_CLEANUP_IF (rval);
00478     //}
00479   }
00480   if (lp->nrows >= lp->rhssize)
00481   {
00482     if (lp->rhssize + 1000 < (lp->nrows + 1) * 1.3)
00483       lp->rhssize = (lp->nrows + 1) * 1.3;
00484     else
00485       lp->rhssize += 1000;
00486     float128_EGlpNumReallocArray (&(lp->rhs), lp->rhssize);
00487   }
00488   lp->rowsense[lp->nrows] = sense;
00489   float128_EGlpNumCopy (lp->rhs[lp->nrows], rhs);
00490   lp->nrows++;
00491 
00492 CLEANUP:
00493   ILL_RETURN (rval, "float128_ILLraw_add_row");
00494 }
00495 
00496 static int float128_ILLcheck_rawlpdata (
00497   float128_rawlpdata * lp)
00498 {
00499   int i, col, rval = 0;
00500   int si, *perm = NULL;
00501   const char *c1, *c2;
00502   float128_sosptr *set;
00503 
00504   ILL_FAILfalse (lp, "lp must not be NULL");
00505 
00506   /* check    
00507    *          *) that there is at least one variable 
00508    *          *) that the weights in all SOS sets are distinct 
00509    *          *) all sos members are non integer variables     
00510    *          *) sos set members have distint weights 
00511    *          *) objindex is not -1
00512    *          *) INVARIANT: rowname[objindex] != NULL
00513    *          *) INVARIANT: upper/lower arrays are filled in 
00514    *          *) INVARIANT: if col or rownames != NULL then 
00515    *                        all their elements are not NULL
00516    */
00517   if (lp->ncols < 1)
00518   {
00519     return float128_ILLdata_error (lp->error_collector, "There are no variables.");
00520   }
00521   if (lp->objindex == -1)
00522   {
00523     return float128_ILLdata_error (lp->error_collector, "There is no objective fct.");
00524   }
00525   ILL_FAILfalse (float128_ILLraw_rowname (lp, lp->objindex) != NULL,
00526                  "must have objective name");
00527   if (lp->nsos_member > 1)
00528   {
00529     ILL_SAFE_MALLOC (perm, lp->nsos_member, int);
00530 
00531     for (si = 0; si < lp->nsos; si++)
00532     {
00533       set = lp->sos_set + si;
00534       for (i = 0; i < set->nelem; i++)
00535       {
00536         col = lp->sos_col[set->first + i];
00537         if (lp->intmarker[col])
00538         {
00539           rval = float128_ILLdata_error (lp->error_collector,
00540                                 "SOS set member \"%s\" is an %s.\n",
00541                                 float128_ILLraw_colname (lp, col),
00542                                 "integer/binary variable");
00543         }
00544       }
00545       if (set->nelem > 1)
00546       {
00547         for (i = 0; i < set->nelem; i++)
00548         {
00549           perm[i] = set->first + i;
00550         }
00551         float128_ILLutil_EGlpNum_perm_quicksort (perm, lp->sos_weight, set->nelem);
00552         for (i = 1; i < set->nelem; i++)
00553         {
00554           if (float128_EGlpNumIsEqqual
00555               (lp->sos_weight[perm[i - 1]], lp->sos_weight[perm[i]]))
00556           {
00557             c1 = float128_ILLraw_colname (lp, lp->sos_col[perm[i]]);
00558             c2 = float128_ILLraw_colname (lp, lp->sos_col[perm[i - 1]]);
00559             float128_ILLdata_error (lp->error_collector,
00560                            "\"%s\" and \"%s\" both have %s %f.\n", c1, c2,
00561                            "SOS weight", lp->sos_weight[perm[i]]);
00562             rval = 1;
00563           }
00564         }
00565       }
00566     }
00567   }
00568   for (i = 0; i < lp->ncols; i++)
00569   {
00570     ILL_CHECKnull (float128_ILLraw_colname (lp, i), "There is a NULL col name");
00571   }
00572   for (i = 0; i < lp->nrows; i++)
00573   {
00574     ILL_CHECKnull (float128_ILLraw_rowname (lp, i), "There is a NULL row name");
00575   }
00576   ILL_FAILtrue ((lp->upper == NULL) | (lp->lower == NULL),
00577                 "Upper/Lower arrays must be filled in.");
00578 
00579   rval += float128_ILLraw_check_bounds (lp);
00580 CLEANUP:
00581   ILL_IFFREE (perm, int);
00582 
00583   ILL_RESULT (rval, "float128_ILLcheck_rawlpdata");
00584 }
00585 
00586 int float128_ILLraw_init_bounds (
00587   float128_rawlpdata * lp)
00588 {
00589   int i, rval = 0;
00590 
00591   ILL_FAILfalse (lp->upper == NULL, "Should be called exactly once");
00592   ILL_FAILfalse (lp->lower == NULL, "Should be called exactly once");
00593   ILL_FAILfalse (lp->lbind == NULL, "Should be called exactly once");
00594   ILL_FAILfalse (lp->ubind == NULL, "Should be called exactly once");
00595   lp->upper = float128_EGlpNumAllocArray (lp->ncols);
00596   lp->lower = float128_EGlpNumAllocArray (lp->ncols);
00597   ILL_SAFE_MALLOC (lp->lbind, lp->ncols, char);
00598   ILL_SAFE_MALLOC (lp->ubind, lp->ncols, char);
00599 
00600   for (i = 0; i < lp->ncols; i++)
00601   {
00602     lp->lbind[i] = (char) 0;
00603     lp->ubind[i] = (char) 0;
00604     float128_EGlpNumZero (lp->lower[i]);
00605   }
00606 CLEANUP:
00607   ILL_RETURN (rval, "float128_ILLraw_init_bounds");
00608 }
00609 
00610 const char *float128_ILLraw_set_lowerBound (
00611   float128_rawlpdata * lp,
00612   int i,
00613   float128 bnd)
00614 {
00615   ILL_FAILtrue_no_rval (i >= lp->ncols, "proper colind");
00616   if (lp->lbind[i])
00617   {
00618     return "Using previous bound definition.";
00619   }
00620   float128_EGlpNumCopy (lp->lower[i], bnd);
00621   lp->lbind[i] = (char) 1;
00622 CLEANUP:
00623   return NULL;
00624 }
00625 
00626 const char *float128_ILLraw_set_upperBound (
00627   float128_rawlpdata * lp,
00628   int i,
00629   float128 bnd)
00630 {
00631   ILL_FAILtrue_no_rval (i >= lp->ncols, "proper colind");
00632   if (lp->ubind[i])
00633   {
00634     return "Using previous bound definition.";
00635   }
00636   float128_EGlpNumCopy (lp->upper[i], bnd);
00637   lp->ubind[i] = (char) 1;
00638   if (!float128_EGlpNumIsNeqqZero (lp->lower[i]) &&
00639       !float128_EGlpNumIsNeqqZero (bnd))
00640   {
00641     return "0.0 upper bound fixes variable.";
00642   }
00643 CLEANUP:
00644   return NULL;
00645 }
00646 
00647 const char *float128_ILLraw_set_fixedBound (
00648   float128_rawlpdata * lp,
00649   int i,
00650   float128 bnd)
00651 {
00652   ILL_FAILtrue_no_rval (i >= lp->ncols, "proper colind");
00653   if (lp->ubind[i] || lp->lbind[i])
00654   {
00655     return "Using previous bound definition.";
00656   }
00657   float128_EGlpNumCopy (lp->lower[i], bnd);
00658   lp->lbind[i] = (char) 1;
00659   float128_EGlpNumCopy (lp->upper[i], bnd);
00660   lp->ubind[i] = (char) 1;
00661 CLEANUP:
00662   return NULL;
00663 }
00664 
00665 const char *float128_ILLraw_set_unbound (
00666   float128_rawlpdata * lp,
00667   int i)
00668 {
00669   ILL_FAILtrue_no_rval (i >= lp->ncols, "proper colind");
00670   if (lp->lbind[i] || lp->ubind[i])
00671   {
00672     return "Using previous bound definition.";
00673   }
00674   float128_EGlpNumCopy (lp->lower[i], float128_ILL_MINDOUBLE);
00675   float128_EGlpNumCopy (lp->upper[i], float128_ILL_MAXDOUBLE);
00676   lp->lbind[i] = 1;
00677   lp->ubind[i] = 1;
00678 CLEANUP:
00679   return NULL;
00680 }
00681 
00682 const char *float128_ILLraw_set_binaryBound (
00683   float128_rawlpdata * lp,
00684   int i)
00685 {
00686   ILL_FAILtrue_no_rval (i >= lp->ncols, "proper colind");
00687   if (lp->lbind[i] || lp->ubind[i])
00688   {
00689     return "Using previous bound definition.";
00690   }
00691   float128_EGlpNumZero (lp->lower[i]);
00692   float128_EGlpNumOne (lp->upper[i]);
00693   lp->lbind[i] = 1;
00694   lp->ubind[i] = 1;
00695 CLEANUP:
00696   return NULL;
00697 }
00698 
00699 int float128_ILLraw_fill_in_bounds (
00700   float128_rawlpdata * lp)
00701 {
00702   int rval = 0, i;
00703 
00704   if (lp->lbind == NULL)
00705   {
00706     float128_ILLraw_init_bounds (lp);
00707   }
00708   ILL_FAILtrue (lp->upper == NULL, "must all be there now");
00709   ILL_FAILtrue (lp->lower == NULL, "must all be there now");
00710   ILL_FAILtrue (lp->lbind == NULL, "must all be there now");
00711   ILL_FAILtrue (lp->ubind == NULL, "must all be there now");
00712   for (i = 0; i < lp->ncols; i++)
00713   {
00714     if (!lp->lbind[i])
00715     {
00716       if (lp->ubind[i] && float128_EGlpNumIsLessZero (lp->upper[i]))
00717       {
00718         float128_EGlpNumCopy (lp->lower[i], float128_ILL_MINDOUBLE);
00719       }
00720     }
00721     if (!lp->ubind[i])
00722     {
00723       /* int vars without bounds are binary                        */
00724       /* all, also int vars                                        */
00725       /*          with explicit lower bound 0.0 are in [0.0,+inf]  */
00726       if (((lp->intmarker != NULL) && lp->intmarker[i]) && !lp->lbind[i])
00727       {
00728         float128_EGlpNumOne (lp->upper[i]);
00729       }
00730       else
00731       {
00732         float128_EGlpNumCopy (lp->upper[i], float128_ILL_MAXDOUBLE);
00733       }
00734     }
00735   }
00736 
00737 CLEANUP:
00738   if (rval)
00739   {
00740     float128_EGlpNumFreeArray (lp->lower);
00741     float128_EGlpNumFreeArray (lp->upper);
00742   }
00743   ILL_RETURN (rval, "float128_ILLraw_fill_in_bounds");
00744 }
00745 
00746 static int float128_ILLraw_check_bounds (
00747   float128_rawlpdata * lp)
00748 {
00749   int rval = 0, i;
00750 
00751   ILL_FAILtrue (lp->upper == NULL, "must all be there now");
00752   ILL_FAILtrue (lp->lower == NULL, "must all be there now");
00753   ILL_FAILtrue (lp->lbind == NULL, "must all be there now");
00754   ILL_FAILtrue (lp->ubind == NULL, "must all be there now");
00755   for (i = 0; i < lp->ncols; i++)
00756   {
00757     if (float128_EGlpNumIsLess (lp->upper[i], lp->lower[i]))
00758     {
00759       rval += float128_ILLdata_error (lp->error_collector,
00760                              "Lower bound is bigger than %s \"%s\".\n",
00761                              "upper bound for", float128_ILLraw_colname (lp, i));
00762     }
00763   }
00764   ILL_RESULT (rval, "float128_ILLraw_check_bounds");
00765 CLEANUP:
00766   ILL_RETURN (rval, "float128_ILLraw_check_bounds");
00767 }
00768 
00769 int float128_ILLraw_first_nondefault_bound (
00770   float128_ILLlpdata * lp)
00771 {
00772   int ri = lp->nstruct, i;
00773 
00774   ILL_FAILtrue_no_rval (lp->lower == NULL || lp->upper == NULL,
00775                         "Should not call float128_write_bounds when lower or upper are NULL");
00776   for (ri = 0; ri < lp->nstruct; ri++)
00777   {
00778     i = lp->structmap[ri];
00779     if (!float128_ILLraw_default_lower (lp, i) || !float128_ILLraw_default_upper (lp, i, ri))
00780       break;
00781   }
00782 CLEANUP:
00783   return ri;
00784 }
00785 
00786 int float128_ILLraw_default_lower (
00787   float128_ILLlpdata * lp,
00788   int i)
00789 {
00790   ILL_FAILtrue_no_rval (lp->lower == NULL || lp->upper == NULL,
00791                         "Should not call float128_write_bounds when lower or upper are NULL");
00792   ILL_FAILfalse_no_rval (lp->ncols > i, "i is not col index");
00793   if (!float128_EGlpNumIsNeqqZero (lp->lower[i]) &&
00794       !float128_EGlpNumIsLessZero (lp->upper[i]))
00795   {
00796     return 1;
00797   }
00798   if (float128_EGlpNumIsEqqual (lp->lower[i], float128_ILL_MINDOUBLE) &&
00799       float128_EGlpNumIsLessZero (lp->upper[i]))
00800   {
00801     return 1;
00802   }
00803 CLEANUP:
00804   return 0;
00805 }
00806 
00807 int float128_ILLraw_default_upper (
00808   float128_ILLlpdata * lp,
00809   int i, 
00810   int ri)
00811 {
00812   int isInt;
00813 
00814   ILL_FAILtrue_no_rval (lp->lower == NULL || lp->upper == NULL,
00815                         "Should not call float128_write_bounds when lower or upper are NULL");
00816   ILL_FAILfalse_no_rval (lp->ncols >= i, "i is not col index");
00817   isInt = (lp->intmarker != NULL) && lp->intmarker[ri];
00818   if (isInt)
00819   {
00820     if (!float128_EGlpNumIsNeqqZero (lp->lower[i]))
00821     {
00822       return (float128_EGlpNumIsEqqual (lp->upper[i], float128_oneLpNum));
00823     }
00824   }
00825 
00826   if (float128_EGlpNumIsEqqual (lp->upper[i], float128_ILL_MAXDOUBLE))
00827   {
00828     return 1;
00829   }
00830 CLEANUP:
00831   return 0;
00832 }
00833 
00834 int float128_ILLraw_fill_in_rownames (
00835   float128_rawlpdata * lp)
00836 {
00837   int i, rval = 0;
00838   char uname2[ILL_namebufsize];
00839   ILLsymboltab *rowtab;
00840   char first = 1;
00841 
00842   rowtab = &lp->rowtab;
00843   ILL_FAILtrue (lp->nrows != rowtab->tablesize, "must have same #entries");
00844   for (i = 0; (rval == 0) && i < lp->nrows; i++)
00845   {
00846     if (ILLsymboltab_get (rowtab, i) == NULL)
00847     {
00848       if (first)
00849       {
00850         float128_ILLdata_warn (lp->error_collector,
00851                       "Generating names for unnamed rows.");
00852         first = 0;
00853       }
00854 
00855       ILLsymboltab_unique_name (rowtab, i, "c", uname2);
00856       rval = ILLsymboltab_rename (rowtab, i, uname2);
00857       ILL_CLEANUP_IF (rval);
00858     }
00859   }
00860 CLEANUP:
00861   ILL_RESULT (rval, "float128_ILLraw_fill_in_rownames");
00862 }
00863 
00864 static int float128_whichColsAreUsed (
00865   float128_rawlpdata * raw,
00866   float128_ILLlpdata * lp,
00867   int *colindex)
00868 {
00869   int rval = 0;
00870   int i, objind = raw->objindex;
00871   float128_colptr *cp;
00872   char *colUsed = NULL;
00873 
00874   /* colUsed[i]  variable raw->colnames[i] is used in obj fct 
00875    * and/or equation(s) */
00876   ILL_SAFE_MALLOC (colUsed, raw->ncols, char);
00877 
00878   for (i = 0; i < raw->ncols; i++)
00879   {
00880     colUsed[i] = 0;
00881   }
00882   for (i = 0; i < raw->ncols; i++)
00883   {
00884     for (cp = raw->cols[i]; cp; cp = cp->next)
00885     {
00886       if ((cp->this_val == objind) || (raw->rowsense[cp->this_val] != 'N'))
00887       {
00888         colUsed[i] = 1;
00889         break;
00890       }
00891     }
00892   }
00893 
00894   /* colindex[i] = -1 for undefined, 0, 1, ... lp->ncol-1 
00895    * lp->ncols <= raw->ncols */
00896   for (i = 0; i < raw->ncols; i++)
00897   {
00898     if (colUsed[i])
00899     {
00900       colindex[i] = lp->ncols++;
00901     }
00902     else
00903     {
00904       colindex[i] = -1;
00905       float128_ILLdata_warn (raw->error_collector,
00906                     "\"%s\" is used in non objective 'N' rows only.",
00907                     float128_ILLraw_colname (raw, i));
00908     }
00909   }
00910   if (lp->ncols < 1)
00911   {
00912     rval = float128_ILLdata_error (raw->error_collector, "There are no variables.");
00913     ILL_CLEANUP_IF (rval);
00914   }
00915 CLEANUP:
00916   ILL_IFFREE (colUsed, char);
00917 
00918   ILL_RESULT (rval, "float128_whichColsAreUsed");
00919 }
00920 
00921 static int float128_whichRowsAreUsed (
00922   float128_rawlpdata * raw,
00923   float128_ILLlpdata * lp,
00924   int *rowindex)
00925 {
00926   int i, rval = 0;
00927 
00928   /* only use non 'N' rows */
00929   for (i = 0; i < raw->nrows; i++)
00930   {
00931     if (raw->rowsense[i] != 'N')
00932     {
00933       rowindex[i] = lp->nrows++;
00934     }
00935     else
00936     {
00937       rowindex[i] = -1;
00938     }
00939   }
00940   if (lp->nrows == 0)
00941   {
00942     rval = float128_ILLdata_error (raw->error_collector, "There are no constraints.");
00943   }
00944   ILL_RESULT (rval, "float128_whichRowsAreUsed");
00945 }
00946 
00947 
00948 static int float128_transferObjective (
00949   float128_rawlpdata * raw,
00950   float128_ILLlpdata * lp,
00951   int *colindex)
00952 {
00953   int rval = 0, i, ci, objind = raw->objindex;
00954   float128_colptr *cp;
00955   int *coefWarn = NULL;
00956 
00957   /* transfer objective fct */
00958   lp->obj = float128_EGlpNumAllocArray (lp->ncols);
00959   ILL_SAFE_MALLOC (coefWarn, lp->ncols, int);
00960 
00961   for (i = 0; i < lp->ncols; i++)
00962   {
00963     float128_EGlpNumZero (lp->obj[i]);
00964     coefWarn[i] = 0;
00965   }
00966   for (i = 0; i < raw->ncols; i++)
00967   {
00968     for (cp = raw->cols[i]; cp; cp = cp->next)
00969     {
00970       if (cp->this_val == objind)
00971       {
00972         ci = colindex[i];
00973         TESTG ((rval =
00974                 (ci < 0
00975                  || ci >= lp->ncols)), CLEANUP, "ci %d is out of range [0,%d[",
00976                ci, lp->ncols);
00977         ILL_FAILfalse (ci != -1,
00978                        "all vars in obj fct should be marked as useful");
00979         coefWarn[ci]++;
00980         if (float128_EGlpNumIsNeqqZero (cp->coef))
00981           float128_EGlpNumAddTo (lp->obj[ci], cp->coef);
00982         if (coefWarn[ci] == 2)
00983         {
00984           float128_ILLdata_warn (raw->error_collector,
00985                         "Multiple coefficients for \"%s\" in %s.",
00986                         float128_ILLraw_colname (raw, i), "objective function");
00987         }
00988       }
00989     }
00990   }
00991 CLEANUP:
00992   ILL_IFFREE (coefWarn, int);
00993 
00994   ILL_RETURN (rval, "float128_transferObjective");
00995 }
00996 
00997 static int float128_transferColNamesLowerUpperIntMarker (
00998   float128_rawlpdata * raw,
00999   float128_ILLlpdata * lp,
01000   int *colindex)
01001 {
01002   int i, ci, ind, pre, rval = 0;
01003   int hasIntVar;
01004   ILL_SAFE_MALLOC (lp->colnames, lp->ncols, char *);
01005 
01006   if (raw->upper)
01007     lp->upper = float128_EGlpNumAllocArray (lp->ncols);
01008   if (raw->lower)
01009     lp->lower = float128_EGlpNumAllocArray (lp->ncols);
01010   ILL_SAFE_MALLOC (lp->intmarker, lp->ncols, char);
01011 
01012   hasIntVar = 0;
01013   for (i = 0; i < raw->ncols; i++)
01014   {
01015     ci = colindex[i];
01016     if (ci != -1)
01017     {
01018       ILL_FAILfalse ((ci >= 0) && (ci < lp->ncols), "colindex problem");
01019       float128_ILL_UTIL_STR (lp->colnames[ci], float128_ILLraw_colname (raw, i));
01020       rval = ILLsymboltab_register (&lp->coltab,
01021                                     lp->colnames[ci], -1, &ind, &pre);
01022       ILL_FAILfalse ((rval == 0) && (ind == ci) && (pre == 0),
01023                      "should have new entry");
01024       if (raw->upper)
01025       {
01026         float128_EGlpNumCopy (lp->upper[ci], raw->upper[i]);
01027       }
01028       if (raw->lower)
01029       {
01030         float128_EGlpNumCopy (lp->lower[ci], raw->lower[i]);
01031       }
01032       lp->intmarker[ci] = raw->intmarker[i];
01033       hasIntVar = hasIntVar || lp->intmarker[ci];
01034       ILL_IFDOTRACE
01035       {
01036         if (lp->lower)
01037         {
01038           float128_ILLprt_EGlpNum (stdout, &(lp->lower[ci]));
01039           ILL_IFTRACE (" <= ");
01040         }
01041         ILL_IFTRACE ("%s", lp->colnames[ci]);
01042         if (lp->upper)
01043         {
01044           ILL_IFTRACE (" <= ");
01045           float128_ILLprt_EGlpNum (stdout, &(lp->upper[ci]));
01046         }
01047         if (lp->intmarker[ci])
01048         {
01049           ILL_IFTRACE (" INTEGER ");
01050         }
01051         ILL_IFTRACE ("\n");
01052       }
01053     }
01054   }
01055   if (!hasIntVar)
01056   {
01057     ILL_IFFREE (lp->intmarker, char);
01058   }
01059 CLEANUP:
01060   ILL_RETURN (rval, "float128_transferColNamesLowerUpperIntMarker");
01061 }
01062 
01063 static void float128_safeRegister (
01064   ILLsymboltab * tab,
01065   const char *name,
01066   int i)
01067 {
01068   int ind, pre, rval;
01069 
01070   rval = ILLsymboltab_register (tab, name, -1, &ind, &pre);
01071   ILL_FAILfalse ((rval == 0) && (ind == i) && (pre == 0),
01072                  "Pgming Error: should have new entry");
01073 CLEANUP:
01074   return;
01075 }
01076 
01077 static int float128_transferSenseRhsRowNames (
01078   float128_rawlpdata * raw,
01079   float128_ILLlpdata * lp,
01080   int *rowindex)
01081 {
01082   int i, ri, rval = 0;
01083   int objind = raw->objindex;
01084 
01085   /* transfer sense/rhs/rownames */
01086   if (lp->nrows > 0)
01087   {
01088     ILL_SAFE_MALLOC (lp->sense, lp->nrows, char);
01089 
01090     lp->rhs = float128_EGlpNumAllocArray (lp->nrows);
01091     ILL_SAFE_MALLOC (lp->rownames, lp->nrows, char *);
01092 
01093     ILL_FAILfalse (float128_ILLraw_rowname (raw, raw->objindex), "NULL objname");
01094     float128_safeRegister (&lp->rowtab, float128_ILLraw_rowname (raw, raw->objindex), 0);
01095 
01096     ri = 0;
01097     for (i = 0; i < raw->nrows; i++)
01098     {
01099       ri = rowindex[i];
01100       if (i == raw->refrowind)
01101       {
01102         float128_ILL_UTIL_STR (lp->refrowname, float128_ILLraw_rowname (raw, i));
01103         lp->refind = ri;
01104       }
01105       if (raw->rowsense[i] != 'N')
01106       {
01107         ILL_FAILfalse (float128_ILLraw_rowname (raw, i) != NULL,
01108                        "all rownames should be non NULL");
01109         float128_ILL_UTIL_STR (lp->rownames[ri], float128_ILLraw_rowname (raw, i));
01110         float128_safeRegister (&lp->rowtab, lp->rownames[ri], ri + 1);
01111         lp->sense[ri] = raw->rowsense[i];
01112         float128_EGlpNumCopy (lp->rhs[ri], raw->rhs[i]);
01113       }
01114       else if (i == objind)
01115       {
01116         ILL_FAILfalse (lp->objname == NULL, "objname == NULL");
01117         float128_ILL_UTIL_STR (lp->objname, float128_ILLraw_rowname (raw, i));
01118       }
01119       else
01120       {
01121         /* unused 'N' row */
01122       }
01123     }
01124     ILL_FAILfalse ((lp->nrows + 1) == lp->rowtab.tablesize,
01125                    "problem with rowtab structure");
01126   }
01127 CLEANUP:
01128   ILL_RETURN (rval, "float128_transferSenseRhsRowNames");
01129 }
01130 
01131 static int float128_buildMatrix (
01132   float128_rawlpdata * raw,
01133   float128_ILLlpdata * lp,
01134   int *rowindex,
01135   int *colindex)
01136 {
01137   int i, ri, ci, k, nempty = 0, rval = 0;
01138   int *nRowsUsed = 0;
01139   int *coefSet = 0;
01140   int *coefWarn = 0;
01141   float128_ILLmatrix *A = &lp->A;
01142   float128_colptr *cp = NULL;
01143 
01144   /* put subjective fcts into matrix */
01145   ILL_SAFE_MALLOC (A->matcnt, lp->ncols, int);
01146   ILL_SAFE_MALLOC (A->matbeg, lp->ncols, int);
01147   ILL_SAFE_MALLOC (nRowsUsed, lp->nrows, int);
01148 
01149   ILL_SAFE_MALLOC (coefWarn, lp->ncols, int);
01150 
01151   for (i = 0; i < lp->ncols; i++)
01152   {
01153     coefWarn[i] = 0;
01154   }
01155   for (i = 0; i < lp->nrows; i++)
01156   {
01157     nRowsUsed[i] = -1;
01158   }
01159   for (i = 0; i < raw->ncols; i++)
01160   {
01161     ci = colindex[i];
01162     if (ci == -1)
01163       continue;
01164     k = 0;
01165     for (cp = raw->cols[i]; cp; cp = cp->next)
01166     {
01167       ri = rowindex[cp->this_val];
01168       if (ri >= 0)
01169       {
01170         if (nRowsUsed[ri] != i)
01171         {
01172           nRowsUsed[ri] = i;
01173           k++;
01174         }
01175         else
01176         {
01177           if (!coefWarn[ci])
01178           {
01179             float128_ILLdata_warn (raw->error_collector,
01180                           "Multiple coefficients for \"%s\" %s.",
01181                           lp->colnames[i], "in a row");
01182             coefWarn[ci] = 1;
01183           }
01184         }
01185       }
01186     }
01187     A->matcnt[ci] = k;
01188     A->matbeg[ci] = lp->nzcount + nempty; /* mark empty cols */
01189     lp->nzcount += k;
01190     if (k == 0)
01191       nempty++;
01192   }
01193 
01194   A->matrows = lp->nrows;
01195   A->matcols = lp->ncols;
01196   A->matcolsize = lp->ncols;
01197   A->matsize = lp->nzcount + nempty + 1;
01198   A->matfree = 1;
01199   ILL_SAFE_MALLOC (A->matind, A->matsize, int);
01200 
01201   A->matval = float128_EGlpNumAllocArray (A->matsize);
01202   ILL_SAFE_MALLOC (coefSet, lp->nrows, int);
01203 
01204   for (k = 0; k < lp->nrows; k++)
01205   {
01206     coefSet[k] = -1;
01207   }
01208 
01209   for (i = 0; i < raw->ncols; i++)
01210   {
01211     ci = colindex[i];
01212     if (ci == -1)
01213       continue;                 /* unused variable */
01214     k = A->matbeg[ci];
01215     if (A->matcnt[ci] == 0)
01216     {
01217       A->matind[k] = 1;         /* Used in addcols and addrows */
01218     }
01219     else
01220     {
01221       for (cp = raw->cols[i]; cp; cp = cp->next)
01222       {
01223         ri = rowindex[cp->this_val];
01224         if (ri >= 0)
01225         {
01226           if (coefSet[ri] == -1)
01227           {
01228             A->matind[k] = ri;
01229             float128_EGlpNumCopy (A->matval[k], cp->coef);
01230             coefSet[ri] = k;
01231             k++;
01232           }
01233           else
01234           {
01235             float128_EGlpNumAddTo (A->matval[coefSet[ri]], cp->coef);
01236           }
01237         }
01238       }
01239       if (k != A->matbeg[ci] + A->matcnt[ci])
01240       {
01241         ILL_ERROR (rval, "problem with matrix");
01242       }
01243       for (k--; k >= A->matbeg[ci]; k--)
01244       {
01245         coefSet[A->matind[k]] = -1;
01246       }
01247     }
01248   }
01249   A->matind[lp->nzcount + nempty] = -1;
01250 CLEANUP:
01251   ILL_IFFREE (nRowsUsed, int);
01252   ILL_IFFREE (coefWarn, int);
01253   ILL_IFFREE (coefSet, int);
01254 
01255   ILL_RETURN (rval, "float128_buildMatrix");
01256 }
01257 
01258 static int float128_transferRanges (
01259   float128_rawlpdata * raw,
01260   float128_ILLlpdata * lp,
01261   int *rowindex)
01262 {
01263   int i, ri, rval = 0;
01264   float128_colptr *cp;
01265 
01266     /*****************************************************/
01267   /*                                                   */
01268   /*  Interpretation of RANGE values in MPS files      */
01269   /*                                                   */
01270   /*    G    rhs           <= row <= rhs + |range|     */
01271   /*    L    rhs - |range| <= row <= rhs               */
01272   /*    E +  rhs           <= row <= rhs + range       */
01273   /*    E -  rhs + range   <= row <= rhs               */
01274   /*                                                   */
01275   /*     - where + and - refer to the sign of range    */
01276   /*       and the letters refer to sense of the row.  */
01277   /*                                                   */
01278   /*    We will store ranged rows as                   */
01279   /*                                                   */
01280   /*       rhs  <= row  <= rhs + range                 */
01281   /*                                                   */
01282     /*****************************************************/
01283 
01284 
01285   lp->rangeval = float128_EGlpNumAllocArray (lp->nrows);
01286   for (i = 0; i < lp->nrows; i++)
01287   {
01288     float128_EGlpNumZero (lp->rangeval[i]);
01289   }
01290   for (cp = raw->ranges; cp; cp = cp->next)
01291   {
01292     i = cp->this_val;
01293     ri = rowindex[cp->this_val];
01294     switch (raw->rowsense[i])
01295     {
01296     case 'N':
01297       float128_ILLdata_error (raw->error_collector, "No range for N-row.\n");
01298       rval = 1;
01299       goto CLEANUP;
01300     case 'G':
01301       lp->sense[ri] = 'R';
01302       float128_EGlpNumCopyAbs (lp->rangeval[ri], cp->coef);
01303       break;
01304     case 'L':
01305       lp->sense[ri] = 'R';
01306       float128_EGlpNumCopyAbs (lp->rangeval[ri], cp->coef);
01307       float128_EGlpNumSubTo (lp->rhs[ri], lp->rangeval[ri]);
01308       break;
01309     case 'E':
01310       lp->sense[ri] = 'R';
01311       if (!float128_EGlpNumIsLessZero (cp->coef))
01312       {
01313         float128_EGlpNumCopy (lp->rangeval[ri], cp->coef);
01314       }
01315       else
01316       {
01317         float128_EGlpNumAddTo (lp->rhs[ri], cp->coef);
01318         float128_EGlpNumCopyNeg (lp->rangeval[ri], cp->coef);
01319       }
01320       break;
01321     }
01322   }
01323 CLEANUP:
01324   ILL_RETURN (rval, "float128_transferRanges");
01325 }
01326 
01327 static int float128_initStructmap (
01328   float128_ILLlpdata * lp)
01329 {
01330   int i, rval = 0;
01331 
01332   /* all vars are structural */
01333   ILL_SAFE_MALLOC (lp->structmap, lp->nstruct, int);
01334 
01335   for (i = 0; i < lp->nstruct; i++)
01336   {
01337     lp->structmap[i] = i;
01338   }
01339 
01340 CLEANUP:
01341   ILL_RETURN (rval, "float128_initStructmap");
01342 }
01343 
01344 static int float128_buildSosInfo (
01345   float128_rawlpdata * raw,
01346   float128_ILLlpdata * lp,
01347   int *colindex)
01348 {
01349   int i, ci, set, rval = 0;
01350   int nSosMem, nSetMem;
01351 
01352   /* build sos info */
01353   /* see comment in float128_lpdata.h about float128_ILLlpdata's sos and is_sos_mem 
01354    * fields and section of float128_ILLprint_rawlpdata that prints SOS sets */
01355 
01356   ILL_SAFE_MALLOC (lp->is_sos_mem, lp->ncols, int);
01357 
01358   nSosMem = 0;
01359   for (i = 0; i < raw->ncols; i++)
01360   {
01361     ci = colindex[i];
01362     if (ci != -1)
01363     {
01364       lp->is_sos_mem[ci] = raw->is_sos_member[i];
01365       if (raw->is_sos_member[i] != -1)
01366         nSosMem++;
01367     }
01368   }
01369   if (nSosMem > 0)
01370   {
01371     lp->sos.matsize = nSosMem;
01372     lp->sos.matcols = raw->nsos;
01373     lp->sos.matcolsize = raw->nsos;
01374     lp->sos.matrows = lp->ncols;
01375     lp->sos.matfree = 0;
01376     lp->sos.matval = float128_EGlpNumAllocArray (nSosMem);
01377     ILL_SAFE_MALLOC (lp->sos.matind, nSosMem, int);
01378     ILL_SAFE_MALLOC (lp->sos.matbeg, raw->nsos, int);
01379     ILL_SAFE_MALLOC (lp->sos.matcnt, raw->nsos, int);
01380     ILL_SAFE_MALLOC (lp->sos_type, raw->nsos, char);
01381 
01382     nSosMem = 0;
01383     for (set = 0; set < raw->nsos; set++)
01384     {
01385       lp->sos_type[set] = raw->sos_set[set].type;
01386       lp->sos.matbeg[set] = nSosMem;
01387       nSetMem = 0;
01388       for (i = raw->sos_set[set].first;
01389            i < raw->sos_set[set].first + raw->sos_set[set].nelem; i++)
01390       {
01391         ci = colindex[raw->sos_col[i]];
01392         if (ci != -1)
01393         {
01394           lp->sos.matind[nSosMem + nSetMem] = ci;
01395           float128_EGlpNumCopy (lp->sos.matval[nSosMem + nSetMem], raw->sos_weight[i]);
01396           nSetMem++;
01397         }
01398       }
01399       lp->sos.matcnt[set] = nSetMem;
01400       nSosMem += nSetMem;
01401     }
01402   }
01403 CLEANUP:
01404   ILL_RETURN (rval, "float128_buildSosInfo");
01405 }
01406 
01407 static int float128_convert_rawlpdata_to_lpdata (
01408   float128_rawlpdata * raw,
01409   float128_ILLlpdata * lp)
01410 /* 
01411  * only raw's non 'N' rows are converted to matrix entries in lp
01412  * columns that are used in non objective 'N' rows only are not 
01413  * converted. That is they don't end up in lp's matrix, row/colnames, 
01414  * upper/lower bounds or SOS information.
01415  */
01416 {
01417   int rval = 0;
01418   int *rowindex = 0;
01419   int *colindex = 0;
01420 
01421   ILL_FAILfalse ((raw && lp), "rawlpdata_to_lpdata called without input");
01422   if (raw->name == NULL)
01423   {
01424     float128_ILLdata_warn (raw->error_collector, "Setting problem name to \"unnamed\".");
01425     float128_ILL_UTIL_STR (raw->name, "unnamed");
01426   }
01427   rval = float128_ILLcheck_rawlpdata (raw);
01428   ILL_CLEANUP_IF (rval);
01429 
01430   ILL_FAILfalse (raw->objindex != -1, "float128_rawlpdata must have objective fct.");
01431   float128_ILLlpdata_init (lp);
01432 
01433   ILL_IFFREE (lp->probname, char);
01434 
01435   lp->probname = raw->name;
01436   raw->name = 0;
01437 
01438   /* MINIMIZE or MAXIMIZE ? */
01439   lp->objsense = raw->objsense;
01440   if (lp->objsense != float128_ILL_MIN && lp->objsense != float128_ILL_MAX)
01441   {
01442     float128_ILLdata_error (raw->error_collector, "Bad objsense.\n");
01443     rval = 1;
01444     goto CLEANUP;
01445   }
01446 
01447   ILL_SAFE_MALLOC (colindex, raw->ncols, int);
01448   ILL_SAFE_MALLOC (rowindex, raw->nrows, int);
01449 
01450   rval = float128_whichColsAreUsed (raw, lp, colindex) ||
01451     float128_whichRowsAreUsed (raw, lp, rowindex);
01452   ILL_CLEANUP_IF (rval);
01453   ILL_FAILtrue (lp->ncols == 0 || lp->nrows == 0, "we need rows and cols");
01454 
01455   /* array sizes */
01456   lp->rowsize = lp->nrows;
01457   lp->colsize = lp->ncols;
01458   lp->nstruct = lp->ncols;
01459   lp->structsize = lp->ncols;
01460   ILLsymboltab_create (&lp->rowtab, lp->nrows);
01461   ILLsymboltab_create (&lp->coltab, lp->ncols);
01462 
01463   rval = float128_transferObjective (raw, lp, colindex);
01464   rval = rval || float128_transferColNamesLowerUpperIntMarker (raw, lp, colindex);
01465   rval = rval || float128_buildMatrix (raw, lp, rowindex, colindex);
01466   rval = rval || float128_buildSosInfo (raw, lp, colindex);
01467   ILL_CLEANUP_IF (rval);
01468   ILL_IFDOTRACE
01469   {
01470     EGioFile_t*lout = EGioOpenFILE(stdout);
01471     float128_ILLmatrix_prt (lout, &lp->A);
01472     EGioClose(lout);
01473   }
01474 
01475   rval = float128_transferSenseRhsRowNames (raw, lp, rowindex);
01476   if ((lp->nrows > 0) && raw->ranges)
01477   {
01478     rval = rval || float128_transferRanges (raw, lp, rowindex);
01479   }
01480   ILL_CLEANUP_IF (rval);
01481 
01482   rval = float128_initStructmap (lp);
01483   ILL_CLEANUP_IF (rval);
01484 
01485 CLEANUP:
01486 
01487   ILL_IFFREE (rowindex, int);
01488   ILL_IFFREE (colindex, int);
01489 
01490   float128_ILLfree_rawlpdata (raw);
01491 
01492   ILL_RESULT (rval, "float128_convert_rawlpdata_to_lpdata");
01493 }
01494 
01495 int float128_ILLrawlpdata_to_lpdata (
01496   float128_rawlpdata * raw,
01497   float128_ILLlpdata * lp)
01498 {
01499   int rval = 0;
01500 
01501   ILL_IFDOTRACE
01502   {
01503     printf ("%s\n", __func__);
01504     float128_ILLprint_rawlpdata (raw);
01505   }
01506   rval = float128_convert_rawlpdata_to_lpdata (raw, lp);
01507   if (rval == 0)
01508   {
01509     rval = float128_ILLlp_add_logicals (lp);
01510   }
01511   ILL_RESULT (rval, "float128_ILLrawlpdata_to_lpdata");
01512 }
01513 
01514 static int float128_set_field_name (
01515   char **field,
01516   const char *name,
01517   int *skip)
01518 {
01519   int rval = 0;
01520 
01521   /* name is bounds/rhs/rangesname field from float128_rawlpdata */
01522   *skip = 0;
01523   if (!*field)
01524   {
01525     float128_ILL_UTIL_STR (*field, name);
01526   }
01527 
01528   if (strcmp (*field, name))
01529   {
01530     /* not first specified RHS/BOUNDS - skip it */
01531     *skip = 1;
01532   }
01533 CLEANUP:
01534   ILL_RETURN (rval, "float128_set_field_name");
01535 }
01536 
01537 int float128_ILLraw_set_rhs_name (
01538   float128_rawlpdata * lp,
01539   const char *name,
01540   int *skip)
01541 {
01542   return float128_set_field_name (&lp->rhsname, name, skip);
01543 }
01544 
01545 int float128_ILLraw_set_bounds_name (
01546   float128_rawlpdata * lp,
01547   const char *name,
01548   int *skip)
01549 {
01550   return float128_set_field_name (&lp->boundsname, name, skip);
01551 }
01552 
01553 int float128_ILLraw_set_ranges_name (
01554   float128_rawlpdata * lp,
01555   const char *name,
01556   int *skip)
01557 {
01558   return float128_set_field_name (&lp->rangesname, name, skip);
01559 }
01560 
01561 void float128_ILLprint_rawlpdata (
01562   float128_rawlpdata * lp)
01563 {
01564   int i, cnt, si, m;
01565   char c;
01566   float128 d;
01567   float128_colptr *cp;
01568   float128_sosptr *set;
01569 
01570   float128_EGlpNumInitVar (d);
01571 
01572   if (lp)
01573   {
01574     if (lp->name)
01575     {
01576       printf ("PROBLEM  %s\n", lp->name);
01577       fflush (stdout);
01578     }
01579     if (lp->rowsense && lp->rhs)
01580     {
01581       printf ("Subject To\n");
01582       for (i = 0; i < lp->nrows; i++)
01583       {
01584         switch (lp->rowsense[i])
01585         {
01586         case 'E':
01587           c = '=';
01588           break;
01589         case 'L':
01590           c = '<';
01591           break;
01592         case 'G':
01593           c = '>';
01594           break;
01595         default:
01596           c = '?';
01597           break;
01598         }
01599         printf ("%s: %c %f\n", float128_ILLraw_rowname (lp, i), c,
01600                 float128_EGlpNumToLf (lp->rhs[i]));
01601       }
01602       printf ("\n");
01603       fflush (stdout);
01604     }
01605     if (lp->ncols > 0)
01606     {
01607       printf ("Columns\n");
01608       for (i = 0; i < lp->ncols; i++)
01609       {
01610         for (cp = lp->cols[i]; cp; cp = cp->next)
01611         {
01612           printf ("%s: ", float128_ILLraw_rowname (lp, cp->this_val));
01613           printf ("%c ", (float128_EGlpNumIsLessZero (cp->coef)) ? '-' : '+');
01614           float128_EGlpNumCopyAbs (d, cp->coef);
01615           if (float128_EGlpNumIsNeqq (d, float128_oneLpNum))
01616           {
01617             printf (" %f ", float128_EGlpNumToLf (d));
01618           }
01619           printf ("%s\n", float128_ILLraw_colname (lp, i));
01620         }
01621         printf ("\n");
01622         fflush (stdout);
01623       }
01624     }
01625     if (lp->rangesname)
01626     {
01627       printf ("RANGES %s\n", lp->rangesname);
01628       for (cp = lp->ranges; cp; cp = cp->next)
01629       {
01630         printf ("(%s, %f) ", float128_ILLraw_rowname (lp, cp->this_val),
01631                 float128_EGlpNumToLf (cp->coef));
01632       }
01633       printf ("\n");
01634       fflush (stdout);
01635     }
01636     if (lp->boundsname)
01637     {
01638       printf ("BOUNDS %s\n", lp->boundsname);
01639       fflush (stdout);
01640     }
01641     else
01642     {
01643       printf ("BOUNDS \n");
01644       fflush (stdout);
01645     }
01646     if (lp->lower && lp->upper)
01647     {
01648       for (i = 0; i < lp->ncols; i++)
01649       {
01650         float128_ILLprt_EGlpNum (stdout, &(lp->lower[i]));
01651         printf (" <= %s <= ", float128_ILLraw_colname (lp, i));
01652         float128_ILLprt_EGlpNum (stdout, &(lp->upper[i]));
01653         printf ("\n");
01654       }
01655     }
01656     if (lp->intmarker)
01657     {
01658       printf ("Integer\n");
01659       cnt = 0;
01660       for (i = 0; i < lp->ncols; i++)
01661       {
01662         if (lp->intmarker[i])
01663         {
01664           printf ("%s", float128_ILLraw_colname (lp, i));
01665           cnt++;
01666           if (cnt == 8)
01667           {
01668             printf ("\n    ");
01669             cnt = 0;
01670           }
01671         }
01672       }
01673       printf ("\n");
01674       fflush (stdout);
01675     }
01676     printf ("SOS-SETS\n");
01677     for (si = 0; si < lp->nsos; si++)
01678     {
01679       set = lp->sos_set + si;
01680       printf ("SOS-SET %d: %s; nelem=%d; first=%d;\n",
01681               si, ((set->type == float128_ILL_SOS_TYPE1) ? "TYPE1" : "TYPE2"),
01682               set->nelem, set->first);
01683       printf ("\t");
01684       for (m = set->first; m < set->first + set->nelem; m++)
01685       {
01686         printf (" %s %f; ", float128_ILLraw_colname (lp, lp->sos_col[m]),
01687                 float128_EGlpNumToLf (lp->sos_weight[m]));
01688       }
01689       printf ("\n");
01690     }
01691     printf ("\n");
01692     fflush (stdout);
01693   }
01694   float128_EGlpNumClearVar (d);
01695 }
01696 
01697 static int float128_ILLmsg (
01698   float128_qserror_collector * collector,
01699   int isError,
01700   const char *format,
01701   va_list args)
01702 {
01703   const char *pre;
01704   int slen, errtype;
01705   float128_qsformat_error error;
01706   char error_desc[256];
01707 
01708   vsprintf (error_desc, format, args);
01709   slen = strlen (error_desc);
01710   if ((slen > 0) && error_desc[slen - 1] != '\n')
01711   {
01712     error_desc[slen] = '\n';
01713     error_desc[slen + 1] = '\0';
01714   }
01715 
01716   if (collector != NULL)
01717   {
01718     errtype = (isError) ? QS_DATA_ERROR : QS_DATA_WARN;
01719     float128_ILLformat_error_create (&error, errtype, error_desc, -1, NULL, -1);
01720     float128_ILLformat_error (collector, &error);
01721     float128_ILLformat_error_delete (&error);
01722   }
01723   else
01724   {
01725     pre = (isError) ? "Data Error" : "Data Warning";
01726     fprintf (stderr, "%s: %s", pre, error_desc);
01727   }
01728   return 1;
01729 }
01730 
01731 int float128_ILLdata_error (
01732   float128_qserror_collector * collector,
01733   const char *format,
01734   ...)
01735 {
01736   va_list args;
01737 
01738   va_start (args, format);
01739   return float128_ILLmsg (collector, float128_TRUE, format, args);
01740 }
01741 
01742 void float128_ILLdata_warn (
01743   float128_qserror_collector * collector,
01744   const char *format,
01745   ...)
01746 {
01747   va_list args;
01748 
01749   va_start (args, format);
01750   (void) float128_ILLmsg (collector, float128_FALSE, format, args);
01751 }
01752 
01753 float128_colptr *float128_ILLcolptralloc (
01754   ILLptrworld * p)
01755 {
01756   float128_colptr *sol = colptralloc (p);
01757 
01758   float128_EGlpNumInitVar ((sol->coef));
01759   return sol;
01760 }

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