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

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