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 "qs_config.h"
00026 #include "float128_qsopt.h"
00027 #include "float128_lpdata.h"
00028 #include "float128_qstruct.h"
00029 #include "float128_qsopt.h"
00030 #include "float128_editor.h"
00031 #include "float128_readline.h"
00032 #include "float128_rawlp.h"
00033 #include "stddefs.h"
00034 #include "float128_read_lp.h"
00035 #include "float128_lp.h"
00036 #include "float128_lib.h"
00037 #ifdef USEDMALLOC
00038 #include "dmalloc.h"
00039 #endif
00040
00041 static int TRACE = 0;
00042
00043 #define float128_ILL_BREAK_BODY_IF(rval) if (rval != 0) goto CLEANUP
00044 #define float128_ILL_BREAK_BODY goto CLEANUP
00045
00046 static int float128_transpose ( float128_rawlpdata * lp);
00047 static int float128_pull_info_from_p ( float128_QSdata * p, float128_rawlpdata * lp);
00048 static void float128_add_row ( float128_QSdata * p, float128_rawlpdata * lp, float128_ILLread_lp_state * state);
00049
00050
00051 static void float128_del_row ( float128_QSdata * p, float128_rawlpdata * lp, float128_ILLread_lp_state * state);
00052
00053 static void float128_add_col ( float128_QSdata * p, float128_rawlpdata * lp, float128_ILLread_lp_state * state);
00054 static void float128_del_col ( float128_QSdata * p, float128_rawlpdata * lp, float128_ILLread_lp_state * state);
00055
00056 #define float128_NONE -1
00057 #define float128_QS_EXIT 0
00058 #define float128_ROW 1
00059 #define float128_COL 2
00060 #define float128_PLP 3
00061 #define float128_PRTX 4
00062 #define float128_SOLVE 5
00063 #define float128_PMPS 6
00064 #define float128_HELP 7
00065 #define float128_DEL 8
00066 #define float128_NEW 9
00067 #define float128_ADD 10
00068 #define float128_PRIMAL 11
00069 #define float128_DUAL 12
00070 #define float128_NCOMMAND 13
00071 static const char *float128_commands[float128_NCOMMAND + 1];
00072 static char float128_hasSubCmd[float128_NCOMMAND + 1];
00073
00074 void float128_ILLeditor_init (
00075 void)
00076 {
00077 float128_commands[float128_QS_EXIT] = "float128_QS_EXIT";
00078 float128_commands[float128_ROW] = "float128_ROW";
00079 float128_commands[float128_COL] = "float128_COL";
00080 float128_commands[float128_PLP] = "LP";
00081 float128_commands[float128_PMPS] = "MPS";
00082 float128_commands[float128_SOLVE] = "float128_SOLVE";
00083 float128_commands[float128_PRTX] = "PRT";
00084 float128_commands[float128_HELP] = "float128_HELP";
00085 float128_commands[float128_ADD] = "float128_ADD";
00086 float128_commands[float128_DEL] = "float128_DEL";
00087 float128_commands[float128_NEW] = "float128_NEW";
00088 float128_commands[float128_PRIMAL] = "float128_PRIMAL";
00089 float128_commands[float128_DUAL] = "float128_DUAL";
00090 float128_commands[float128_NCOMMAND] = NULL;
00091
00092 float128_hasSubCmd[float128_QS_EXIT] = 0;
00093 float128_hasSubCmd[float128_ROW] = 1;
00094 float128_hasSubCmd[float128_COL] = 1;
00095 float128_hasSubCmd[float128_PLP] = 0;
00096 float128_hasSubCmd[float128_PMPS] = 0;
00097 float128_hasSubCmd[float128_SOLVE] = 1;
00098 float128_hasSubCmd[float128_PRTX] = 0;
00099 float128_hasSubCmd[float128_HELP] = 0;
00100 float128_hasSubCmd[float128_ADD] = 1;
00101 float128_hasSubCmd[float128_DEL] = 1;
00102 float128_hasSubCmd[float128_NEW] = 1;
00103 float128_hasSubCmd[float128_PRIMAL] = 1;
00104 float128_hasSubCmd[float128_DUAL] = 1;
00105 float128_hasSubCmd[float128_NCOMMAND] = 0;
00106 }
00107
00108 static void float128_ILLeditor_help_cmd (
00109 int cmd,
00110 int subcmd);
00111
00112 static void float128_ILLeditor_help (
00113 void)
00114 {
00115 float128_ILLeditor_help_cmd (float128_ROW, float128_ADD);
00116
00117 float128_ILLeditor_help_cmd (float128_ROW, float128_DEL);
00118 float128_ILLeditor_help_cmd (float128_COL, float128_ADD);
00119 float128_ILLeditor_help_cmd (float128_COL, float128_DEL);
00120 float128_ILLeditor_help_cmd (float128_SOLVE, float128_NONE);
00121 float128_ILLeditor_help_cmd (float128_PRTX, float128_NONE);
00122 float128_ILLeditor_help_cmd (float128_PLP, float128_NONE);
00123 float128_ILLeditor_help_cmd (float128_PMPS, float128_NONE);
00124 float128_ILLeditor_help_cmd (float128_QS_EXIT, float128_NONE);
00125 float128_ILLeditor_help_cmd (float128_HELP, float128_NONE);
00126 }
00127
00128 static void float128_ILLeditor_help_cmd (
00129 int cmd,
00130 int subcmd)
00131 {
00132 if (cmd == float128_ROW && subcmd == float128_ADD)
00133 fprintf (stdout, "%s float128_ADD:\t%s.\n",
00134 float128_commands[float128_ROW], "add a row; enter in LP format");
00135 if (cmd == float128_COL && subcmd == float128_ADD)
00136 fprintf (stdout, "%s float128_ADD:\t%s.\n",
00137 float128_commands[float128_COL], "add a col; enter in LP format");
00138
00139
00140
00141
00142 if (cmd == float128_ROW && subcmd == float128_DEL)
00143 fprintf (stdout, "%s float128_DEL:\t%s.\n",
00144 float128_commands[float128_ROW], "delete a row; give rowname");
00145 if (cmd == float128_COL && subcmd == float128_DEL)
00146 fprintf (stdout, "%s float128_DEL:\t%s.\n",
00147 float128_commands[float128_COL], "delete a col; give colname");
00148 if (cmd == float128_SOLVE)
00149 fprintf (stdout, "%s:\t%s.\n", float128_commands[float128_SOLVE], "solve problem");
00150 if (cmd == float128_PRTX)
00151 fprintf (stdout, "%s:\t%s.\n",
00152 float128_commands[float128_PRTX], "print variable values for optimal solution");
00153 if (cmd == float128_PLP)
00154 fprintf (stdout, "%s [file]:\t%s.\n",
00155 float128_commands[float128_PLP], "print problem in LP format to file or stdout");
00156 if (cmd == float128_PMPS)
00157 fprintf (stdout, "%s [file]:\t%s.\n",
00158 float128_commands[float128_PMPS], "print problem in MPS format to file or stdout");
00159 if (cmd == float128_QS_EXIT)
00160 fprintf (stdout, "%s:\t%s.\n", float128_commands[float128_QS_EXIT], "float128_QS_EXIT");
00161 if (cmd == float128_HELP)
00162 fprintf (stdout, "%s:\t%s.\n", float128_commands[float128_HELP], "print this help");
00163 }
00164
00165 static void float128_getCmd (
00166 float128_ILLread_lp_state * state,
00167 int *cmd,
00168 int *subcmd)
00169 {
00170 const char *cmd_str, *subcmd_str;
00171 int tmp;
00172
00173 *cmd = float128_ILLutil_index (float128_commands, state->field);
00174 *subcmd = -1;
00175 if (float128_hasSubCmd[*cmd] && (float128_ILLread_lp_state_next_field_on_line (state) == 0))
00176 {
00177 *subcmd = float128_ILLutil_index (float128_commands, state->field);
00178 if ((*subcmd == float128_ROW) || (*subcmd == float128_COL) || (*subcmd == float128_SOLVE))
00179 {
00180 float128_ILL_SWAP (*subcmd, *cmd, tmp);
00181 }
00182 }
00183 cmd_str = (*cmd >= 0) ? float128_commands[*cmd] : "???";
00184 subcmd_str = (*subcmd >= 0) ? float128_commands[*subcmd] : "???";
00185 ILL_IFTRACE ("cmd = %s, subcmd = %s\n", cmd_str, subcmd_str);
00186 }
00187
00188 void float128_ILLeditor (
00189 float128_QSdata * p)
00190 {
00191 float128_rawlpdata raw, *lp = &raw;
00192 int cmd, subcmd, tval, rval = 0;
00193 float128_ILLread_lp_state lpstate, *state = &lpstate;
00194 float128_qsline_reader *reader;
00195
00196 ILL_IFTRACE ("float128_ILLeditor\n");
00197
00198 reader = float128_ILLline_reader_new ((float128_qsread_line_fct) fgets, stdin);
00199 rval = float128_ILLread_lp_state_init (state, reader, "STDIN", 1);
00200 rval = rval || float128_pull_info_from_p (p, lp);
00201 float128_ILL_BREAK_BODY_IF (rval);
00202
00203 while (float128_ILLread_lp_state_next_field (state) == 0)
00204 {
00205 float128_getCmd (state, &cmd, &subcmd);
00206 switch (cmd)
00207 {
00208 case float128_QS_EXIT:
00209 float128_ILL_BREAK_BODY;
00210
00211 case float128_ROW:
00212 {
00213 switch (subcmd)
00214 {
00215 case float128_ADD:
00216 float128_add_row (p, lp, state);
00217 break;
00218
00219 case float128_DEL:
00220 float128_del_row (p, lp, state);
00221 break;
00222 default:
00223 float128_ILLeditor_help ();
00224 break;
00225 }
00226 break;
00227 }
00228 case float128_COL:
00229 {
00230 switch (subcmd)
00231 {
00232 case float128_ADD:
00233 float128_add_col (p, lp, state);
00234 break;
00235 case float128_DEL:
00236 float128_del_col (p, lp, state);
00237 break;
00238 default:
00239 float128_ILLeditor_help ();
00240 break;
00241 }
00242 break;
00243 }
00244
00245 case float128_SOLVE:
00246 {
00247 if (subcmd == float128_PRIMAL)
00248 {
00249 (void) float128_ILLeditor_solve (p, PRIMAL_SIMPLEX);
00250 }
00251 else if (subcmd == float128_DUAL)
00252 {
00253 (void) float128_ILLeditor_solve (p, DUAL_SIMPLEX);
00254 }
00255 else
00256 {
00257 float128_ILLeditor_help ();
00258 }
00259 break;
00260 }
00261
00262 case float128_PRTX:
00263 {
00264 EGioFile_t*lout = EGioOpenFILE(stdout);
00265 if ((rval = float128_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 float128_PLP:
00274 case float128_PMPS:
00275 {
00276 if (float128_ILLread_lp_state_next_field_on_line (state) == 0)
00277 {
00278 if (cmd == float128_PMPS)
00279 {
00280 tval = float128_QSwrite_prob (p, state->field, "MPS");
00281 }
00282 else
00283 {
00284 tval = float128_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 == float128_PMPS)
00299 {
00300 (void) float128_QSwrite_prob_file (p, stdout, "MPS");
00301 }
00302 else
00303 {
00304 (void) float128_QSwrite_prob_file (p, stdout, "LP");
00305 }
00306 }
00307 break;
00308 }
00309
00310 case float128_NONE:
00311 fprintf (stdout, "Unknown command: %s\n", state->field);
00312 default:
00313 float128_ILLeditor_help ();
00314 break;
00315 }
00316 fflush (stdout);
00317 float128_ILLread_lp_state_next_line (state);
00318 }
00319 CLEANUP:
00320 float128_ILLline_reader_free (reader);
00321 float128_ILLfree_rawlpdata (lp);
00322 }
00323
00324 int float128_ILLeditor_solve (
00325 float128_QSdata * p,
00326 int salgo)
00327 {
00328 int rval = 0;
00329 int status = 0;
00330 float128 val;
00331
00332 float128_EGlpNumInitVar (val);
00333
00334 if (salgo == PRIMAL_SIMPLEX)
00335 {
00336 rval = float128_QSopt_primal (p, &status);
00337 }
00338 else
00339 {
00340 rval = float128_QSopt_dual (p, &status);
00341 }
00342 float128_ILL_BREAK_BODY_IF (rval);
00343 rval = float128_QSget_objval (p, &val);
00344 if (p->simplex_display)
00345 if (rval == 0)
00346 {
00347 fprintf (stdout, "LP Value: %.6f, status %d\n", float128_EGlpNumToLf (val),
00348 status);
00349 fflush (stdout);
00350 }
00351 CLEANUP:
00352 float128_EGlpNumClearVar (val);
00353 ILL_RESULT (rval, "float128_ILLeditor_solve");
00354 }
00355
00356
00357 static int float128_pull_info_from_p (
00358 float128_QSdata * p,
00359 float128_rawlpdata * lp)
00360 {
00361 int i, rval = 0;
00362 float128_ILLlpdata *qslp = p->lp->O;
00363 int nrows, ncols;
00364
00365 float128_ILLinit_rawlpdata (lp, NULL);
00366 rval = ILLsymboltab_create (&lp->rowtab, 100) ||
00367 ILLsymboltab_create (&lp->coltab, 100);
00368 float128_ILL_BREAK_BODY_IF (rval);
00369
00370 nrows = qslp->nrows;
00371 ncols = qslp->nstruct;
00372
00373 float128_ILLraw_add_row (lp, qslp->objname, 'N', float128_zeroLpNum);
00374 for (i = 0; i < nrows; i++)
00375 {
00376 ILL_FAILfalse (qslp->rownames[i] != NULL, "should have no NULL names");
00377 float128_ILLraw_add_row (lp, qslp->rownames[i], qslp->sense[i], qslp->rhs[i]);
00378 }
00379
00380
00381 for (i = 0; i < ncols; i++)
00382 {
00383 ILL_FAILfalse (qslp->colnames[i] != NULL, "should have no NULL names");
00384 float128_ILLraw_add_col (lp, qslp->colnames[i],
00385 (qslp->intmarker) ? qslp->intmarker[i] : 0);
00386 }
00387 CLEANUP:
00388 ILL_RETURN (rval, "float128_pull_info_from_p");
00389 }
00390
00391 static int float128_transpose (
00392 float128_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
00407
00408
00409
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 float128_EGlpNumReallocArray (&(lp->rhs), lp->rhssize);
00418
00419
00420
00421
00422
00423 }
00424 float128_ILL_SWAP (lp->nrows, lp->ncols, tmp);
00425 float128_ILL_SWAP (lp->rowtab, lp->coltab, tmptab);
00426 ILL_RETURN (rval, "float128_transpose");
00427 }
00428
00429 static char *float128_get_row_col_name (
00430 float128_QSdata * p,
00431 float128_rawlpdata * lp,
00432 float128_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--;
00443
00444 rval = float128_ILLread_constraint_name (state, &rname);
00445 float128_ILL_BREAK_BODY_IF (rval);
00446
00447 if (rname == NULL)
00448 {
00449 float128_ILLlib_findName (p->qslp, doRow , rname, id, buf);
00450 float128_ILL_UTIL_STR (thename, buf);
00451 }
00452 else
00453 {
00454 float128_ILL_UTIL_STR (thename, rname);
00455 }
00456 if (ILLsymboltab_lookup (tab, thename, &ind) == 0)
00457 {
00458 rval = float128_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 float128_fill_matrix (
00469 float128_rawlpdata * lp,
00470 float128_ILLread_lp_state * state,
00471 float128_ILLmatrix * m,
00472 float128 * obj,
00473 int n)
00474 {
00475 int i, cnt, rval = 0;
00476 float128_colptr *cp;
00477 float128 val;
00478 int newCol = (obj != NULL);
00479
00480 float128_EGlpNumInitVar (val);
00481
00482
00483
00484 m->matrows = lp->nrows;
00485 m->matcols = 1;
00486 m->matval = float128_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 float128_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 (float128_EGlpNumIsNeqqZero (cp->coef))
00502 {
00503 float128_EGlpNumAddTo (val, cp->coef);
00504 cnt++;
00505 }
00506 }
00507 if (cnt > 1)
00508 {
00509 float128_ILLlp_warn (state, "Multiple coefficients for \"%s\".",
00510 float128_ILLraw_colname (lp, i));
00511 }
00512 if (float128_EGlpNumIsNeqqZero (val))
00513 {
00514 if ((i - newCol) >= 0)
00515 {
00516 float128_EGlpNumCopy (m->matval[m->matcnt[0]], val);
00517 m->matind[m->matcnt[0]] = i - newCol;
00518 m->matcnt[0]++;
00519 }
00520 else
00521 {
00522 float128_EGlpNumCopy (obj[0], val);
00523 }
00524 }
00525 }
00526 if (m->matcnt[0] == 0)
00527 {
00528 rval = float128_ILLlp_error (state, "There are no non zero coefficients.");
00529 }
00530 CLEANUP:
00531 float128_EGlpNumClearVar (val);
00532 ILL_RESULT (rval, "float128_fill_matrix");
00533 }
00534
00535 static void float128_add_row (
00536 float128_QSdata * p,
00537 float128_rawlpdata * lp,
00538 float128_ILLread_lp_state * state)
00539 {
00540 int rval = 0;
00541 int n;
00542 char *name;
00543 float128_ILLmatrix m;
00544 char sense[1];
00545
00546 float128_ILLmatrix_init (&m);
00547 n = lp->nrows;
00548 name = float128_get_row_col_name (p, lp, state, 1 );
00549
00550 if (name == NULL)
00551 {
00552 rval = 1;
00553 }
00554 else
00555 {
00556 rval = float128_ILLread_one_constraint (state, name, lp, 0);
00557
00558
00559 if (rval != 0)
00560 {
00561
00562
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 = float128_fill_matrix (lp, state, &m, NULL, n);
00573 float128_ILL_BREAK_BODY_IF (rval);
00574
00575 float128_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 float128_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 float128_ILLraw_clear_matrix (lp);
00592 }
00593
00594 static void float128_add_col (
00595 float128_QSdata * p,
00596 float128_rawlpdata * lp,
00597 float128_ILLread_lp_state * state)
00598 {
00599 int rval = 0;
00600 int n;
00601 char *name[1];
00602 int transposed = 1;
00603 float128_ILLmatrix matrix, *m = &matrix;
00604 float128 obj[1], lower[1], upper[2];
00605
00606 float128_EGlpNumInitVar (*obj);
00607 float128_EGlpNumInitVar (*lower);
00608 float128_EGlpNumInitVar (upper[0]);
00609 float128_EGlpNumInitVar (upper[1]);
00610
00611 n = lp->ncols;
00612 float128_ILLmatrix_init (m);
00613 name[0] = float128_get_row_col_name (p, lp, state, 0 );
00614 rval = (name[0] == NULL);
00615 float128_ILL_BREAK_BODY_IF (rval);
00616
00617 transposed = !float128_transpose (lp);
00618 rval = float128_ILLread_one_constraint (state, name[0], lp, 0);
00619
00620
00621 if (rval != 0)
00622 {
00623
00624
00625 fprintf (stdout, "Incorrect expression.\n");
00626 }
00627 else
00628 {
00629 ILL_FAILfalse (lp->nrows == (n + 1), "Should have one row");
00630
00631 rval = float128_fill_matrix (lp, state, m, obj, n);
00632 float128_ILL_BREAK_BODY_IF (rval);
00633
00634 fprintf (stdout, "lower ");
00635 rval = float128_ILLread_lp_state_next_line (state) ||
00636 float128_ILLread_lp_state_value (state, &(lower[0]));
00637 float128_ILL_BREAK_BODY_IF (rval);
00638
00639 fprintf (stdout, "upper ");
00640 rval = float128_ILLread_lp_state_next_line (state) ||
00641 float128_ILLread_lp_state_value (state, &(upper[0]));
00642 float128_ILL_BREAK_BODY_IF (rval);
00643
00644 ILL_IFTRACE ("ADDING col %s.\n", name[0]);
00645
00646 float128_QSadd_cols (p, 1, m->matcnt, m->matbeg, m->matind, m->matval,
00647 obj, lower, upper, (const char **) name);
00648
00649 }
00650 CLEANUP:
00651 float128_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 float128_ILLraw_clear_matrix (lp);
00663 if (transposed)
00664 float128_transpose (lp);
00665 ILL_IFFREE (name[0], char);
00666
00667 float128_EGlpNumClearVar (*obj);
00668 float128_EGlpNumClearVar (*lower);
00669 float128_EGlpNumClearVar (upper[0]);
00670 float128_EGlpNumClearVar (upper[1]);
00671 }
00672
00673 #if 0
00674 #ifndef JAVA_PORT
00675 static void new_row (
00676 float128_QSdata * p,
00677 float128_rawlpdata * lp,
00678 float128_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 = float128_ILLread_constraint_name (state, &rname);
00687 if (rname == NULL)
00688 {
00689 rval = 1;
00690 float128_ILLeditor_help_cmd (float128_ROW, float128_NEW);
00691 }
00692 float128_ILL_BREAK_BODY_IF (rval);
00693
00694 ILLsymboltab_lookup (&lp->rowtab, rname, &ind);
00695 if (ind != ILL_SYM_NOINDEX)
00696 {
00697 rval = float128_ILLlp_error (state, "\"%s\" is already defined.\n", rname);
00698 float128_ILL_BREAK_BODY_IF (rval);
00699 }
00700 float128_ILL_UTIL_STR (rowname, rname);
00701
00702 rval = float128_ILLread_lp_state_sense (state);
00703 sense = state->sense_val;
00704 float128_ILL_BREAK_BODY_IF (rval);
00705
00706 rval = float128_ILLread_lp_state_value (state, &d);
00707 float128_ILL_BREAK_BODY_IF (rval);
00708
00709 rval = float128_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 float128_del_row_or_col (
00725 float128_QSdata * p,
00726 float128_rawlpdata * lp,
00727 float128_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 = float128_ILLread_lp_state_next_field_on_line (state);
00736 float128_ILL_BREAK_BODY_IF (rval);
00737
00738 i[0] = float128_ILLutil_array_index (names, nnames, state->field);
00739 if (i[0] >= 0)
00740 {
00741 rval = (isRow) ? float128_QSdelete_rows (p, 1, i) : float128_QSdelete_cols (p, 1, i);
00742 if (rval == 0)
00743 {
00744 ILLsymboltab_delete (tab, state->field);
00745 }
00746 }
00747 else
00748 {
00749 rval = float128_ILLlp_error (state, "\"%s\" is not defined.\n", state->field);
00750 }
00751
00752 CLEANUP:
00753 ILL_RESULT (rval, "float128_del_row_or_col");
00754 }
00755
00756 static void float128_del_row (
00757 float128_QSdata * p,
00758 float128_rawlpdata * lp,
00759 float128_ILLread_lp_state * state)
00760 {
00761 int rval = float128_del_row_or_col (p, lp, state, 1);
00762
00763 if (rval == 0)
00764 {
00765 lp->nrows--;
00766 }
00767 }
00768
00769 static void float128_del_col (
00770 float128_QSdata * p,
00771 float128_rawlpdata * lp,
00772 float128_ILLread_lp_state * state)
00773 {
00774 int rval = float128_del_row_or_col (p, lp, state, 0);
00775
00776 if (rval == 0)
00777 {
00778 lp->ncols--;
00779 }
00780 }