00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
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"
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
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
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
00139
00140
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
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
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
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
00405
00406
00407
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
00417
00418
00419
00420
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--;
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 , 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
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 );
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
00557 if (rval != 0)
00558 {
00559
00560
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 );
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
00619 if (rval != 0)
00620 {
00621
00622
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 }