mpq_editor.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_editor.c,v $ $Revision: 1.2 $ $Date: 2003/11/05 16:49:52 $"; */
00024 
00025 #include "qs_config.h"
00026 #include "mpq_qsopt.h"
00027 #include "mpq_lpdata.h"
00028 #include "mpq_qstruct.h"
00029 #include "mpq_qsopt.h"
00030 #include "mpq_editor.h"
00031 #include "mpq_readline.h"
00032 #include "mpq_rawlp.h"
00033 #include "stddefs.h"            /* for MAX */
00034 #include "mpq_read_lp.h"
00035 #include "mpq_lp.h"
00036 #include "mpq_lib.h"
00037 #ifdef USEDMALLOC
00038 #include "dmalloc.h"
00039 #endif
00040 
00041 static int TRACE = 0;
00042 
00043 #define mpq_ILL_BREAK_BODY_IF(rval) if (rval != 0) goto CLEANUP
00044 #define mpq_ILL_BREAK_BODY goto CLEANUP
00045 
00046 static int mpq_transpose ( mpq_rawlpdata * lp);
00047 static int mpq_pull_info_from_p ( mpq_QSdata * p, mpq_rawlpdata * lp);
00048 static void mpq_add_row ( mpq_QSdata * p, mpq_rawlpdata * lp, mpq_ILLread_lp_state * state);
00049 
00050 /* static int new_row(mpq_QSdata *p, mpq_rawlpdata *lp, mpq_ILLread_lp_state *state); */
00051 static void mpq_del_row ( mpq_QSdata * p, mpq_rawlpdata * lp, mpq_ILLread_lp_state * state);
00052 
00053 static void mpq_add_col ( mpq_QSdata * p, mpq_rawlpdata * lp, mpq_ILLread_lp_state * state);
00054 static void mpq_del_col ( mpq_QSdata * p, mpq_rawlpdata * lp, mpq_ILLread_lp_state * state);
00055 
00056 #define mpq_NONE -1
00057 #define mpq_QS_EXIT 0
00058 #define mpq_ROW 1
00059 #define mpq_COL 2
00060 #define mpq_PLP 3
00061 #define mpq_PRTX 4
00062 #define mpq_SOLVE 5
00063 #define mpq_PMPS 6
00064 #define mpq_HELP 7
00065 #define mpq_DEL 8
00066 #define mpq_NEW 9
00067 #define mpq_ADD 10
00068 #define mpq_PRIMAL 11
00069 #define mpq_DUAL 12
00070 #define mpq_NCOMMAND 13
00071 static const char *mpq_commands[mpq_NCOMMAND + 1];
00072 static char mpq_hasSubCmd[mpq_NCOMMAND + 1];
00073 
00074 void mpq_ILLeditor_init (
00075   void)
00076 {
00077   mpq_commands[mpq_QS_EXIT] = "mpq_QS_EXIT";
00078   mpq_commands[mpq_ROW] = "mpq_ROW";
00079   mpq_commands[mpq_COL] = "mpq_COL";
00080   mpq_commands[mpq_PLP] = "LP";
00081   mpq_commands[mpq_PMPS] = "MPS";
00082   mpq_commands[mpq_SOLVE] = "mpq_SOLVE";
00083   mpq_commands[mpq_PRTX] = "PRT";
00084   mpq_commands[mpq_HELP] = "mpq_HELP";
00085   mpq_commands[mpq_ADD] = "mpq_ADD";
00086   mpq_commands[mpq_DEL] = "mpq_DEL";
00087   mpq_commands[mpq_NEW] = "mpq_NEW";
00088   mpq_commands[mpq_PRIMAL] = "mpq_PRIMAL";
00089   mpq_commands[mpq_DUAL] = "mpq_DUAL";
00090   mpq_commands[mpq_NCOMMAND] = NULL;
00091 
00092   mpq_hasSubCmd[mpq_QS_EXIT] = 0;
00093   mpq_hasSubCmd[mpq_ROW] = 1;
00094   mpq_hasSubCmd[mpq_COL] = 1;
00095   mpq_hasSubCmd[mpq_PLP] = 0;
00096   mpq_hasSubCmd[mpq_PMPS] = 0;
00097   mpq_hasSubCmd[mpq_SOLVE] = 1;
00098   mpq_hasSubCmd[mpq_PRTX] = 0;
00099   mpq_hasSubCmd[mpq_HELP] = 0;
00100   mpq_hasSubCmd[mpq_ADD] = 1;
00101   mpq_hasSubCmd[mpq_DEL] = 1;
00102   mpq_hasSubCmd[mpq_NEW] = 1;
00103   mpq_hasSubCmd[mpq_PRIMAL] = 1;
00104   mpq_hasSubCmd[mpq_DUAL] = 1;
00105   mpq_hasSubCmd[mpq_NCOMMAND] = 0;
00106 }
00107 
00108 static void mpq_ILLeditor_help_cmd (
00109   int cmd,
00110   int subcmd);
00111 
00112 static void mpq_ILLeditor_help (
00113   void)
00114 {
00115   mpq_ILLeditor_help_cmd (mpq_ROW, mpq_ADD);
00116   /* mpq_ILLeditor_help_cmd(mpq_ROW, mpq_NEW);  */
00117   mpq_ILLeditor_help_cmd (mpq_ROW, mpq_DEL);
00118   mpq_ILLeditor_help_cmd (mpq_COL, mpq_ADD);
00119   mpq_ILLeditor_help_cmd (mpq_COL, mpq_DEL);
00120   mpq_ILLeditor_help_cmd (mpq_SOLVE, mpq_NONE);
00121   mpq_ILLeditor_help_cmd (mpq_PRTX, mpq_NONE);
00122   mpq_ILLeditor_help_cmd (mpq_PLP, mpq_NONE);
00123   mpq_ILLeditor_help_cmd (mpq_PMPS, mpq_NONE);
00124   mpq_ILLeditor_help_cmd (mpq_QS_EXIT, mpq_NONE);
00125   mpq_ILLeditor_help_cmd (mpq_HELP, mpq_NONE);
00126 }
00127 
00128 static void mpq_ILLeditor_help_cmd (
00129   int cmd,
00130   int subcmd)
00131 {
00132   if (cmd == mpq_ROW && subcmd == mpq_ADD)
00133     fprintf (stdout, "%s mpq_ADD:\t%s.\n",
00134              mpq_commands[mpq_ROW], "add a row; enter in LP format");
00135   if (cmd == mpq_COL && subcmd == mpq_ADD)
00136     fprintf (stdout, "%s mpq_ADD:\t%s.\n",
00137              mpq_commands[mpq_COL], "add a col; enter in LP format");
00138   /* if (cmd == mpq_ROW && subcmd == mpq_NEW) 
00139    * fprintf(stdout, "%s mpq_NEW:\t%s.\n", 
00140    * mpq_commands[mpq_ROW], "new row; enter rowname: sense rhs");  
00141    */
00142   if (cmd == mpq_ROW && subcmd == mpq_DEL)
00143     fprintf (stdout, "%s mpq_DEL:\t%s.\n",
00144              mpq_commands[mpq_ROW], "delete a row; give rowname");
00145   if (cmd == mpq_COL && subcmd == mpq_DEL)
00146     fprintf (stdout, "%s mpq_DEL:\t%s.\n",
00147              mpq_commands[mpq_COL], "delete a col; give colname");
00148   if (cmd == mpq_SOLVE)
00149     fprintf (stdout, "%s:\t%s.\n", mpq_commands[mpq_SOLVE], "solve problem");
00150   if (cmd == mpq_PRTX)
00151     fprintf (stdout, "%s:\t%s.\n",
00152              mpq_commands[mpq_PRTX], "print variable values for optimal solution");
00153   if (cmd == mpq_PLP)
00154     fprintf (stdout, "%s [file]:\t%s.\n",
00155              mpq_commands[mpq_PLP], "print problem in LP format to file or stdout");
00156   if (cmd == mpq_PMPS)
00157     fprintf (stdout, "%s [file]:\t%s.\n",
00158              mpq_commands[mpq_PMPS], "print problem in MPS format to file or stdout");
00159   if (cmd == mpq_QS_EXIT)
00160     fprintf (stdout, "%s:\t%s.\n", mpq_commands[mpq_QS_EXIT], "mpq_QS_EXIT");
00161   if (cmd == mpq_HELP)
00162     fprintf (stdout, "%s:\t%s.\n", mpq_commands[mpq_HELP], "print this help");
00163 }
00164 
00165 static void mpq_getCmd (
00166   mpq_ILLread_lp_state * state,
00167   int *cmd,
00168   int *subcmd)
00169 {
00170   const char *cmd_str, *subcmd_str;
00171   int tmp;
00172 
00173   *cmd = mpq_ILLutil_index (mpq_commands, state->field);
00174   *subcmd = -1;
00175   if (mpq_hasSubCmd[*cmd] && (mpq_ILLread_lp_state_next_field_on_line (state) == 0))
00176   {
00177     *subcmd = mpq_ILLutil_index (mpq_commands, state->field);
00178     if ((*subcmd == mpq_ROW) || (*subcmd == mpq_COL) || (*subcmd == mpq_SOLVE))
00179     {
00180       mpq_ILL_SWAP (*subcmd, *cmd, tmp);
00181     }
00182   }
00183   cmd_str = (*cmd >= 0) ? mpq_commands[*cmd] : "???";
00184   subcmd_str = (*subcmd >= 0) ? mpq_commands[*subcmd] : "???";
00185   ILL_IFTRACE ("cmd = %s, subcmd = %s\n", cmd_str, subcmd_str);
00186 }
00187 
00188 void mpq_ILLeditor (
00189   mpq_QSdata * p)
00190 {
00191   mpq_rawlpdata raw, *lp = &raw;
00192   int cmd, subcmd, tval, rval = 0;
00193   mpq_ILLread_lp_state lpstate, *state = &lpstate;
00194   mpq_qsline_reader *reader;
00195 
00196   ILL_IFTRACE ("mpq_ILLeditor\n");
00197 
00198   reader = mpq_ILLline_reader_new ((mpq_qsread_line_fct) fgets, stdin);
00199   rval = mpq_ILLread_lp_state_init (state, reader, "STDIN", 1);
00200   rval = rval || mpq_pull_info_from_p (p, lp);
00201   mpq_ILL_BREAK_BODY_IF (rval);
00202 
00203   while (mpq_ILLread_lp_state_next_field (state) == 0)
00204   {
00205     mpq_getCmd (state, &cmd, &subcmd);
00206     switch (cmd)
00207     {
00208     case mpq_QS_EXIT:
00209       mpq_ILL_BREAK_BODY;
00210 
00211     case mpq_ROW:
00212       {
00213         switch (subcmd)
00214         {
00215         case mpq_ADD:
00216           mpq_add_row (p, lp, state);
00217           break;
00218           /* case mpq_NEW: rval = new_row(p, lp, state); break; */
00219         case mpq_DEL:
00220           mpq_del_row (p, lp, state);
00221           break;
00222         default:
00223           mpq_ILLeditor_help ();
00224           break;
00225         }
00226         break;
00227       }
00228     case mpq_COL:
00229       {
00230         switch (subcmd)
00231         {
00232         case mpq_ADD:
00233           mpq_add_col (p, lp, state);
00234           break;
00235         case mpq_DEL:
00236           mpq_del_col (p, lp, state);
00237           break;
00238         default:
00239           mpq_ILLeditor_help ();
00240           break;
00241         }
00242         break;
00243       }
00244 
00245     case mpq_SOLVE:
00246       {
00247         if (subcmd == mpq_PRIMAL)
00248         {
00249           (void) mpq_ILLeditor_solve (p, PRIMAL_SIMPLEX);
00250         }
00251         else if (subcmd == mpq_DUAL)
00252         {
00253           (void) mpq_ILLeditor_solve (p, DUAL_SIMPLEX);
00254         }
00255         else
00256         {
00257           mpq_ILLeditor_help ();
00258         }
00259         break;
00260       }
00261 
00262     case mpq_PRTX:
00263       {
00264         EGioFile_t*lout = EGioOpenFILE(stdout);
00265         if ((rval = mpq_ILLlib_print_x (lout, p->lp, 0, 0, 1)))
00266         {
00267           fprintf (stdout, "The problem may not be feasible.\n");
00268         }
00269         EGioClose(lout);
00270         break;
00271       }
00272 
00273     case mpq_PLP:
00274     case mpq_PMPS:
00275       {
00276         if (mpq_ILLread_lp_state_next_field_on_line (state) == 0)
00277         {
00278           if (cmd == mpq_PMPS)
00279           {
00280             tval = mpq_QSwrite_prob (p, state->field, "MPS");
00281           }
00282           else
00283           {
00284             tval = mpq_QSwrite_prob (p, state->field, "LP");
00285           }
00286           if (tval)
00287           {
00288             fprintf (stdout, "Could not write problem to \"%s\".\n",
00289                      state->field);
00290           }
00291           else
00292           {
00293             fprintf (stdout, "Saved to \"%s\".\n", state->field);
00294           }
00295         }
00296         else
00297         {
00298           if (cmd == mpq_PMPS)
00299           {
00300             (void) mpq_QSwrite_prob_file (p, stdout, "MPS");
00301           }
00302           else
00303           {
00304             (void) mpq_QSwrite_prob_file (p, stdout, "LP");
00305           }
00306         }
00307         break;
00308       }
00309 
00310     case mpq_NONE:
00311       fprintf (stdout, "Unknown command: %s\n", state->field);
00312     default:
00313       mpq_ILLeditor_help ();
00314       break;
00315     }
00316     fflush (stdout);
00317     mpq_ILLread_lp_state_next_line (state);
00318   }
00319 CLEANUP:
00320   mpq_ILLline_reader_free (reader);
00321   mpq_ILLfree_rawlpdata (lp);
00322 }
00323 
00324 int mpq_ILLeditor_solve (
00325   mpq_QSdata * p,
00326   int salgo)
00327 {
00328   int rval = 0;
00329   int status = 0;
00330   mpq_t val;
00331 
00332   mpq_EGlpNumInitVar (val);
00333 
00334   if (salgo == PRIMAL_SIMPLEX)
00335   {
00336     rval = mpq_QSopt_primal (p, &status);
00337   }
00338   else
00339   {
00340     rval = mpq_QSopt_dual (p, &status);
00341   }
00342   mpq_ILL_BREAK_BODY_IF (rval);
00343   rval = mpq_QSget_objval (p, &val);
00344   if (p->simplex_display)
00345     if (rval == 0)
00346     {
00347       fprintf (stdout, "LP Value: %.6f, status %d\n", mpq_EGlpNumToLf (val),
00348                status);
00349       fflush (stdout);
00350     }
00351 CLEANUP:
00352   mpq_EGlpNumClearVar (val);
00353   ILL_RESULT (rval, "mpq_ILLeditor_solve");
00354 }
00355 
00356 
00357 static int mpq_pull_info_from_p (
00358   mpq_QSdata * p,
00359   mpq_rawlpdata * lp)
00360 {
00361   int i, rval = 0;
00362   mpq_ILLlpdata *qslp = p->lp->O;
00363   int nrows, ncols;
00364 
00365   mpq_ILLinit_rawlpdata (lp, NULL);
00366   rval = ILLsymboltab_create (&lp->rowtab, 100) ||
00367     ILLsymboltab_create (&lp->coltab, 100);
00368   mpq_ILL_BREAK_BODY_IF (rval);
00369 
00370   nrows = qslp->nrows;
00371   ncols = qslp->nstruct;
00372   /* add rows to lp */
00373   mpq_ILLraw_add_row (lp, qslp->objname, 'N', mpq_zeroLpNum);
00374   for (i = 0; i < nrows; i++)
00375   {
00376     ILL_FAILfalse (qslp->rownames[i] != NULL, "should have no NULL names");
00377     mpq_ILLraw_add_row (lp, qslp->rownames[i], qslp->sense[i], qslp->rhs[i]);
00378   }
00379 
00380   /* add cols to coltab and lp */
00381   for (i = 0; i < ncols; i++)
00382   {
00383     ILL_FAILfalse (qslp->colnames[i] != NULL, "should have no NULL names");
00384     mpq_ILLraw_add_col (lp, qslp->colnames[i],
00385                     (qslp->intmarker) ? qslp->intmarker[i] : 0);
00386   }
00387 CLEANUP:
00388   ILL_RETURN (rval, "mpq_pull_info_from_p");
00389 }
00390 
00391 static int mpq_transpose (
00392   mpq_rawlpdata * lp)
00393 {
00394   int rval = 0;
00395   int tmp;
00396   ILLsymboltab tmptab;
00397 
00398   tmp = QSMAX (lp->nrows, lp->ncols);
00399   if (tmp >= lp->sensesize)
00400   {
00401     lp->sensesize *= 1.3;
00402     lp->sensesize += 1000;
00403     if (lp->sensesize < tmp + 1)
00404       lp->sensesize = tmp + 1;
00405     lp->rowsense = EGrealloc (lp->rowsense, sizeof (char) * lp->sensesize);
00406     //rval = ILLutil_reallocrus_scale ((void **) &lp->rowsense,
00407     //                                 &lp->sensesize, tmp + 1,
00408     //                                 1.3, sizeof (char));
00409     //ILL_CLEANUP_IF (rval);
00410   }
00411   if (tmp >= lp->rhssize)
00412   {
00413     lp->rhssize *= 1.3;
00414     lp->rhssize += 1000;
00415     if (lp->rhssize < tmp + 1)
00416       lp->rhssize = tmp + 1;
00417     mpq_EGlpNumReallocArray (&(lp->rhs), lp->rhssize);
00418     //lp->rhs = EGrealloc(lp->rhs, sizeof(double)*lp->rhssize);
00419     //rval = ILLutil_reallocrus_scale ((void **) &lp->rhs,
00420     //                                 &lp->sensesize, tmp + 1,
00421     //                                 1.3, sizeof (double));
00422     //ILL_CLEANUP_IF (rval);
00423   }
00424   mpq_ILL_SWAP (lp->nrows, lp->ncols, tmp);
00425   mpq_ILL_SWAP (lp->rowtab, lp->coltab, tmptab);
00426   ILL_RETURN (rval, "mpq_transpose");
00427 }
00428 
00429 static char *mpq_get_row_col_name (
00430   mpq_QSdata * p,
00431   mpq_rawlpdata * lp,
00432   mpq_ILLread_lp_state * state,
00433   int doRow)
00434 {
00435   int rval = 0;
00436   int ind;
00437   char *rname, *thename = NULL;
00438   char buf[ILL_namebufsize];
00439   ILLsymboltab *tab = (doRow) ? &lp->rowtab : &lp->coltab;
00440   int id = (doRow) ? lp->nrows : lp->ncols;
00441 
00442   id--;                         /* in mpq_rawlpdata obj counts as a row */
00443 
00444   rval = mpq_ILLread_constraint_name (state, &rname);
00445   mpq_ILL_BREAK_BODY_IF (rval);
00446 
00447   if (rname == NULL)
00448   {
00449     mpq_ILLlib_findName (p->qslp, doRow /* forRow */ , rname, id, buf);
00450     mpq_ILL_UTIL_STR (thename, buf);
00451   }
00452   else
00453   {
00454     mpq_ILL_UTIL_STR (thename, rname);
00455   }
00456   if (ILLsymboltab_lookup (tab, thename, &ind) == 0)
00457   {
00458     rval = mpq_ILLlp_error (state, "\"%s\" already exists.", thename);
00459   }
00460 CLEANUP:
00461   if (rval != 0)
00462   {
00463     ILL_IFFREE (thename, char);
00464   }
00465   return thename;
00466 }
00467 
00468 static int mpq_fill_matrix (
00469   mpq_rawlpdata * lp,
00470   mpq_ILLread_lp_state * state,
00471   mpq_ILLmatrix * m,
00472   mpq_t * obj,
00473   int n)
00474 {
00475   int i, cnt, rval = 0;
00476   mpq_colptr *cp;
00477   mpq_t val;
00478   int newCol = (obj != NULL);
00479 
00480   mpq_EGlpNumInitVar (val);
00481 
00482   /* rely on fact that objective has rowindex 0 */
00483 
00484   m->matrows = lp->nrows;
00485   m->matcols = 1;
00486   m->matval = mpq_EGlpNumAllocArray (lp->ncols);
00487   ILL_SAFE_MALLOC (m->matind, lp->ncols, int);
00488   ILL_SAFE_MALLOC (m->matbeg, 1, int);
00489   ILL_SAFE_MALLOC (m->matcnt, 1, int);
00490 
00491   m->matsize = lp->ncols;
00492   m->matbeg[0] = 0;
00493   m->matcnt[0] = 0;
00494   for (i = 0; i < lp->ncols; i++)
00495   {
00496     cnt = 0;
00497     mpq_EGlpNumZero (val);
00498     for (cp = lp->cols[i]; cp != NULL; cp = cp->next)
00499     {
00500       ILL_FAILfalse (cp->this_val == n, "n should be the only row around");
00501       if (mpq_EGlpNumIsNeqqZero (cp->coef))
00502       {
00503         mpq_EGlpNumAddTo (val, cp->coef);
00504         cnt++;
00505       }
00506     }
00507     if (cnt > 1)
00508     {
00509       mpq_ILLlp_warn (state, "Multiple coefficients for \"%s\".",
00510                   mpq_ILLraw_colname (lp, i));
00511     }
00512     if (mpq_EGlpNumIsNeqqZero (val))
00513     {
00514       if ((i - newCol) >= 0)
00515       {
00516         mpq_EGlpNumCopy (m->matval[m->matcnt[0]], val);
00517         m->matind[m->matcnt[0]] = i - newCol;
00518         m->matcnt[0]++;
00519       }
00520       else
00521       {
00522         mpq_EGlpNumCopy (obj[0], val);
00523       }
00524     }
00525   }
00526   if (m->matcnt[0] == 0)
00527   {
00528     rval = mpq_ILLlp_error (state, "There are no non zero coefficients.");
00529   }
00530 CLEANUP:
00531   mpq_EGlpNumClearVar (val);
00532   ILL_RESULT (rval, "mpq_fill_matrix");
00533 }
00534 
00535 static void mpq_add_row (
00536   mpq_QSdata * p,
00537   mpq_rawlpdata * lp,
00538   mpq_ILLread_lp_state * state)
00539 {
00540   int rval = 0;
00541   int n;
00542   char *name;
00543   mpq_ILLmatrix m;
00544   char sense[1];
00545 
00546   mpq_ILLmatrix_init (&m);
00547   n = lp->nrows;
00548   name = mpq_get_row_col_name (p, lp, state, 1 /*doRow */ );
00549 
00550   if (name == NULL)
00551   {
00552     rval = 1;
00553   }
00554   else
00555   {
00556     rval = mpq_ILLread_one_constraint (state, name, lp, 0);
00557 
00558     /* adds row name to lp->rowtab the checks constraint expression  */
00559     if (rval != 0)
00560     {
00561       /* failed because of error in expression => 
00562        * must remove name from symbol table */
00563       fprintf (stdout, "Incorrect expression.\n");
00564     }
00565     else
00566     {
00567       ILL_FAILfalse (lp->nrows == (n + 1), "Should have one row");
00568       ILL_IFTRACE ("ADDING row %s.\n", name);
00569 
00570       sense[0] = lp->rowsense[n];
00571 
00572       rval = mpq_fill_matrix (lp, state, &m, NULL, n);
00573       mpq_ILL_BREAK_BODY_IF (rval);
00574 
00575       mpq_QSadd_rows (p, 1, m.matcnt, m.matbeg, m.matind, m.matval,
00576                   &(lp->rhs[n]), sense, (const char **) &name);
00577     }
00578   }
00579 CLEANUP:
00580   mpq_ILLmatrix_free (&m);
00581   if (name != NULL)
00582   {
00583     if (rval != 0)
00584       ILLsymboltab_delete (&lp->rowtab, name);
00585     ILL_IFFREE (name, char);
00586   }
00587   if (rval != 0)
00588   {
00589     lp->nrows = n;
00590   }
00591   mpq_ILLraw_clear_matrix (lp);
00592 }
00593 
00594 static void mpq_add_col (
00595   mpq_QSdata * p,
00596   mpq_rawlpdata * lp,
00597   mpq_ILLread_lp_state * state)
00598 {
00599   int rval = 0;
00600   int n;
00601   char *name[1];
00602   int transposed = 1;
00603   mpq_ILLmatrix matrix, *m = &matrix;
00604   mpq_t obj[1], lower[1], upper[2];
00605 
00606   mpq_EGlpNumInitVar (*obj);
00607   mpq_EGlpNumInitVar (*lower);
00608   mpq_EGlpNumInitVar (upper[0]);
00609   mpq_EGlpNumInitVar (upper[1]);
00610 
00611   n = lp->ncols;
00612   mpq_ILLmatrix_init (m);
00613   name[0] = mpq_get_row_col_name (p, lp, state, 0 /*doRow */ );
00614   rval = (name[0] == NULL);
00615   mpq_ILL_BREAK_BODY_IF (rval);
00616 
00617   transposed = !mpq_transpose (lp);
00618   rval = mpq_ILLread_one_constraint (state, name[0], lp, 0);
00619 
00620   /* adds row name to lp->rowtab the checks constraint expression  */
00621   if (rval != 0)
00622   {
00623     /* failed because of error in expression => 
00624      * must remove name from symbol table */
00625     fprintf (stdout, "Incorrect expression.\n");
00626   }
00627   else
00628   {
00629     ILL_FAILfalse (lp->nrows == (n + 1), "Should have one row");
00630 
00631     rval = mpq_fill_matrix (lp, state, m, obj, n);
00632     mpq_ILL_BREAK_BODY_IF (rval);
00633 
00634     fprintf (stdout, "lower ");
00635     rval = mpq_ILLread_lp_state_next_line (state) ||
00636       mpq_ILLread_lp_state_value (state, &(lower[0]));
00637     mpq_ILL_BREAK_BODY_IF (rval);
00638 
00639     fprintf (stdout, "upper ");
00640     rval = mpq_ILLread_lp_state_next_line (state) ||
00641       mpq_ILLread_lp_state_value (state, &(upper[0]));
00642     mpq_ILL_BREAK_BODY_IF (rval);
00643 
00644     ILL_IFTRACE ("ADDING col %s.\n", name[0]);
00645 
00646     mpq_QSadd_cols (p, 1, m->matcnt, m->matbeg, m->matind, m->matval,
00647                 obj, lower, upper, (const char **) name);
00648 
00649   }
00650 CLEANUP:
00651   mpq_ILLmatrix_free (m);
00652   if (name[0] != NULL)
00653   {
00654     if (rval != 0)
00655       ILLsymboltab_delete (&lp->rowtab, name[0]);
00656     ILL_IFFREE (name[0], char);
00657   }
00658   if (rval != 0)
00659   {
00660     lp->nrows = n;
00661   }
00662   mpq_ILLraw_clear_matrix (lp);
00663   if (transposed)
00664     mpq_transpose (lp);
00665   ILL_IFFREE (name[0], char);
00666 
00667   mpq_EGlpNumClearVar (*obj);
00668   mpq_EGlpNumClearVar (*lower);
00669   mpq_EGlpNumClearVar (upper[0]);
00670   mpq_EGlpNumClearVar (upper[1]);
00671 }
00672 
00673 #if 0
00674 #ifndef JAVA_PORT
00675 static void new_row (
00676   mpq_QSdata * p,
00677   mpq_rawlpdata * lp,
00678   mpq_ILLread_lp_state * state)
00679 {
00680   int rval = 0;
00681   char *rowname = NULL, *rname = NULL;
00682   char sense;
00683   double d;
00684   int ind, hit;
00685 
00686   rval = mpq_ILLread_constraint_name (state, &rname);
00687   if (rname == NULL)
00688   {
00689     rval = 1;
00690     mpq_ILLeditor_help_cmd (mpq_ROW, mpq_NEW);
00691   }
00692   mpq_ILL_BREAK_BODY_IF (rval);
00693 
00694   ILLsymboltab_lookup (&lp->rowtab, rname, &ind);
00695   if (ind != ILL_SYM_NOINDEX)
00696   {
00697     rval = mpq_ILLlp_error (state, "\"%s\" is already defined.\n", rname);
00698     mpq_ILL_BREAK_BODY_IF (rval);
00699   }
00700   mpq_ILL_UTIL_STR (rowname, rname);
00701 
00702   rval = mpq_ILLread_lp_state_sense (state);
00703   sense = state->sense_val;
00704   mpq_ILL_BREAK_BODY_IF (rval);
00705 
00706   rval = mpq_ILLread_lp_state_value (state, &d);
00707   mpq_ILL_BREAK_BODY_IF (rval);
00708 
00709   rval = mpq_QSnew_row (p, d, sense, rowname);
00710   if (rval != 0)
00711   {
00712     fprintf (stderr, "could not add row\n");
00713   }
00714   else
00715   {
00716     ILLsymboltab_register (&lp->rowtab, rname, &ind, &hit);
00717   }
00718 CLEANUP:
00719   ILL_IFFREE (rowname, char);
00720 }
00721 #endif
00722 #endif
00723 
00724 static int mpq_del_row_or_col (
00725   mpq_QSdata * p,
00726   mpq_rawlpdata * lp,
00727   mpq_ILLread_lp_state * state,
00728   int isRow)
00729 {
00730   int i[1], rval = 0;
00731   char **names = (isRow) ? p->qslp->rownames : p->qslp->colnames;
00732   int nnames = (isRow) ? p->qslp->nrows : p->qslp->nstruct;
00733   ILLsymboltab *tab = (isRow) ? &lp->rowtab : &lp->coltab;
00734 
00735   rval = mpq_ILLread_lp_state_next_field_on_line (state);
00736   mpq_ILL_BREAK_BODY_IF (rval);
00737 
00738   i[0] = mpq_ILLutil_array_index (names, nnames, state->field);
00739   if (i[0] >= 0)
00740   {
00741     rval = (isRow) ? mpq_QSdelete_rows (p, 1, i) : mpq_QSdelete_cols (p, 1, i);
00742     if (rval == 0)
00743     {
00744       ILLsymboltab_delete (tab, state->field);
00745     }
00746   }
00747   else
00748   {
00749     rval = mpq_ILLlp_error (state, "\"%s\" is not defined.\n", state->field);
00750   }
00751 
00752 CLEANUP:
00753   ILL_RESULT (rval, "mpq_del_row_or_col");
00754 }
00755 
00756 static void mpq_del_row (
00757   mpq_QSdata * p,
00758   mpq_rawlpdata * lp,
00759   mpq_ILLread_lp_state * state)
00760 {
00761   int rval = mpq_del_row_or_col (p, lp, state, 1);
00762 
00763   if (rval == 0)
00764   {
00765     lp->nrows--;
00766   }
00767 }
00768 
00769 static void mpq_del_col (
00770   mpq_QSdata * p,
00771   mpq_rawlpdata * lp,
00772   mpq_ILLread_lp_state * state)
00773 {
00774   int rval = mpq_del_row_or_col (p, lp, state, 0);
00775 
00776   if (rval == 0)
00777   {
00778     lp->ncols--;
00779   }
00780 }

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