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
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120 #include "qs_config.h"
00121 #include "iqsutil.h"
00122 #include "lpdata.h"
00123 #include "lpdefs.h"
00124 #include "simplex.h"
00125 #include "price.h"
00126 #include "basis.h"
00127 #include "lib.h"
00128 #include "qstruct.h"
00129 #include "qsopt.h"
00130 #include "lp.h"
00131 #include "mps.h"
00132 #ifdef USEDMALLOC
00133 #include "dmalloc.h"
00134 #endif
00135
00136 static void check_pinf (
00137 price_info * pinf,
00138 int *it_exists);
00139
00140 static int matrix_addrow (
00141 ILLmatrix * A,
00142 int rowcnt,
00143 int *rowind,
00144 const EGlpNum_t * rowval),
00145 matrix_addrow_end (
00146 ILLmatrix * A,
00147 int row,
00148 int rowcnt,
00149 int *rowind,
00150 const EGlpNum_t * rowval),
00151 matrix_addcoef (
00152 lpinfo * lp,
00153 ILLmatrix * A,
00154 int row,
00155 int col,
00156 EGlpNum_t val),
00157 matrix_addcol (
00158 ILLmatrix * A,
00159 int colcnt,
00160 int *colind,
00161 EGlpNum_t * colval),
00162 delcols_work (
00163 lpinfo * lp,
00164 char *colmark),
00165 reset_colindex (
00166 lpinfo * lp),
00167 reset_rowindex (
00168 lpinfo * lp);
00169
00170 int ILLlib_optimize (
00171 lpinfo * lp,
00172 ILLlp_basis * B,
00173 price_info * pinf,
00174 int algo,
00175 int *status,
00176 int simplex_display,
00177 itcnt_t*itcnt)
00178 {
00179 int rval = 0;
00180 int sol_status;
00181
00182 if (status)
00183 *status = QS_LP_UNSOLVED;
00184
00185
00186
00187 rval = ILLsimplex (lp, algo, B, pinf, &sol_status, simplex_display, itcnt);
00188 CHECKRVALG (rval, CLEANUP);
00189
00190 if (status)
00191 *status = sol_status;
00192
00193 CLEANUP:
00194
00195 if (rval == E_SIMPLEX_ERROR)
00196 {
00197 EGioFile_t *eout = 0;
00198 int tval;
00199
00200 printf ("write bad lp to error.lp\n");
00201 fflush (stdout);
00202 #ifdef HAVE_ZLIB_H
00203 eout = EGioOpen ("error.lp.gz", "w");
00204 #else
00205 #ifdef HAVE_BZLIB_H
00206 eout = EGioOpen ("error.lp.bz2", "w");
00207 #else
00208 eout = EGioOpen ("error.lp", "w");
00209 #endif
00210 #endif
00211 if (!eout)
00212 {
00213 fprintf (stderr, "could not open file to write bad lp\n");
00214 }
00215 else
00216 {
00217 tval = ILLwrite_lp (lp->O, NULL);
00218 if (tval)
00219 {
00220 fprintf (stderr, "error while writing bad lp\n");
00221 }
00222 EGioClose (eout);
00223 }
00224
00225 printf ("write bad basis to error.bas\n");
00226 fflush (stdout);
00227 tval = ILLlib_writebasis (lp, 0, "error.bas");
00228 if (tval)
00229 {
00230 fprintf (stderr, "error while writing bad basis\n");
00231 }
00232 }
00233 if (rval == QS_LP_CHANGE_PREC)
00234 {
00235 MESSAGE (__QS_SB_VERB, "Changing precision");
00236 return rval;
00237 }
00238 MESSAGE (rval ? 0 : 1000, "Error code %d", rval);
00239 EG_RETURN (rval);
00240 }
00241
00242 int ILLlib_cache_solution (
00243 lpinfo * lp,
00244 ILLlp_cache * C)
00245 {
00246 int rval = 0;
00247
00248 if (C)
00249 {
00250 if (C->nstruct != lp->O->nstruct || C->nrows != lp->O->nrows)
00251 {
00252 fprintf (stderr, "lp_cache does not match size of lp\n");
00253 rval = 1;
00254 ILL_CLEANUP;
00255 }
00256 rval = ILLlib_solution (lp, 0, &(C->val), C->x, C->pi, C->slack, C->rc);
00257 CHECKRVALG (rval, CLEANUP);
00258 }
00259
00260 CLEANUP:
00261
00262 EG_RETURN (rval);
00263 }
00264
00265 int ILLlib_solution (
00266 lpinfo * lp,
00267 ILLlp_cache * C,
00268 EGlpNum_t * val,
00269 EGlpNum_t * x,
00270 EGlpNum_t * pi,
00271 EGlpNum_t * slack,
00272 EGlpNum_t * rc)
00273 {
00274 int i, rval = 0;
00275 EGlpNum_t *tempx = 0;
00276 EGlpNum_t *temprc = 0;
00277 int ncols = lp->O->ncols;
00278 int nrows = lp->O->nrows;
00279 int nstruct = lp->O->nstruct;
00280 ILLlpdata *qslp = lp->O;
00281
00282 if (C)
00283 {
00284 if (C->nrows != nrows || C->nstruct != nstruct)
00285 {
00286 fprintf (stderr, "cache mismatch in ILLlib_solution\n");
00287 rval = 0;
00288 ILL_CLEANUP;
00289 }
00290 if (val)
00291 {
00292 EGlpNumCopy (*val, C->val);
00293 }
00294 if (x)
00295 {
00296 for (i = 0; i < nstruct; i++)
00297 {
00298 EGlpNumCopy (x[i], C->x[i]);
00299 }
00300 }
00301 if (pi)
00302 {
00303 for (i = 0; i < nrows; i++)
00304 {
00305 EGlpNumCopy (pi[i], C->pi[i]);
00306 }
00307 }
00308 if (slack)
00309 {
00310 for (i = 0; i < nrows; i++)
00311 {
00312 EGlpNumCopy (slack[i], C->slack[i]);
00313 }
00314 }
00315 if (rc)
00316 {
00317 for (i = 0; i < nstruct; i++)
00318 {
00319 EGlpNumCopy (rc[i], C->rc[i]);
00320 }
00321 }
00322 }
00323 else
00324 {
00325 if (x || slack)
00326 tempx = EGlpNumAllocArray (ncols);
00327
00328 if (rc)
00329 temprc = EGlpNumAllocArray (ncols);
00330
00331 rval = ILLsimplex_solution (lp, tempx, pi, temprc, val);
00332 CHECKRVALG (rval, CLEANUP);
00333
00334 if (x)
00335 {
00336 for (i = 0; i < nstruct; i++)
00337 {
00338 EGlpNumCopy (x[i], tempx[qslp->structmap[i]]);
00339 }
00340 }
00341 if (slack)
00342 {
00343 for (i = 0; i < nrows; i++)
00344 {
00345 EGlpNumCopy (slack[i], tempx[qslp->rowmap[i]]);
00346 }
00347 }
00348
00349 if (rc)
00350 {
00351 for (i = 0; i < nstruct; i++)
00352 {
00353 EGlpNumCopy (rc[i], temprc[qslp->structmap[i]]);
00354 }
00355 }
00356
00357
00358 if (lp->O->objsense == ILL_MAX)
00359 {
00360 if (val)
00361 {
00362 EGlpNumSign (*val);
00363 }
00364 if (pi)
00365 {
00366 for (i = 0; i < nrows; i++)
00367 {
00368 EGlpNumSign (pi[i]);
00369 }
00370 }
00371 if (rc)
00372 {
00373 for (i = 0; i < nstruct; i++)
00374 {
00375 EGlpNumSign (rc[i]);
00376 }
00377 }
00378 }
00379 }
00380
00381 CLEANUP:
00382
00383 EGlpNumFreeArray (tempx);
00384 EGlpNumFreeArray (temprc);
00385 EG_RETURN (rval);
00386 }
00387
00388 int ILLlib_get_x (
00389 lpinfo * lp,
00390 ILLlp_cache * C,
00391 EGlpNum_t * x)
00392 {
00393 int rval = 0;
00394
00395 rval = ILLlib_solution (lp, C, 0, x, 0, 0, 0);
00396 CHECKRVALG (rval, CLEANUP);
00397
00398 CLEANUP:
00399
00400 EG_RETURN (rval);
00401 }
00402
00403 int ILLlib_get_slack (
00404 lpinfo * lp,
00405 ILLlp_cache * C,
00406 EGlpNum_t * slack)
00407 {
00408 int rval = 0;
00409
00410 rval = ILLlib_solution (lp, C, 0, 0, 0, slack, 0);
00411 CHECKRVALG (rval, CLEANUP);
00412
00413 CLEANUP:
00414
00415 EG_RETURN (rval);
00416 }
00417
00418
00419 int ILLlib_objval (
00420 lpinfo * lp,
00421 ILLlp_cache * C,
00422 EGlpNum_t * val)
00423 {
00424 int rval = 0;
00425
00426 if (lp->basisstat.optimal)
00427 {
00428 rval = ILLlib_solution (lp, C, val, 0, 0, 0, 0);
00429 CHECKRVALG (rval, CLEANUP);
00430 }
00431 else
00432 {
00433 EGlpNumCopy (*val, lp->dobjval);
00434 }
00435
00436 CLEANUP:
00437
00438 EG_RETURN (rval);
00439 }
00440
00441 int ILLlib_tableau (
00442 lpinfo * lp,
00443 int row,
00444 EGlpNum_t * binv,
00445 EGlpNum_t * tabrow)
00446 {
00447 int rval = 0;
00448 int i;
00449 int ncols = lp->O->ncols;
00450 int nrows = lp->O->nrows;
00451 int nstruct = lp->O->nstruct;
00452 EGlpNum_t *brow = 0;
00453 EGlpNum_t *trow = 0;
00454 ILLlpdata *qslp = lp->O;
00455
00456 if (row < 0 || row >= qslp->nrows)
00457 {
00458 fprintf (stderr, "ILLlib_tableau called with bad row: %d\n", row);
00459 rval = 1;
00460 ILL_CLEANUP;
00461 }
00462 brow = EGlpNumAllocArray (nrows);
00463
00464 if (tabrow)
00465 trow = EGlpNumAllocArray (ncols);
00466
00467 rval = ILLbasis_tableau_row (lp, row, brow, trow, 0, 0);
00468 CHECKRVALG (rval, CLEANUP);
00469
00470 if (binv)
00471 {
00472 for (i = 0; i < nrows; i++)
00473 {
00474 EGlpNumCopy (binv[i], brow[i]);
00475 }
00476 }
00477
00478 if (tabrow)
00479 {
00480 for (i = 0; i < nstruct; i++)
00481 {
00482 EGlpNumCopy (tabrow[i], trow[qslp->structmap[i]]);
00483 }
00484 for (i = 0; i < nrows; i++)
00485 {
00486 EGlpNumCopy (tabrow[nstruct + i], trow[qslp->rowmap[i]]);
00487 }
00488 }
00489
00490 CLEANUP:
00491
00492 EGlpNumFreeArray (brow);
00493 EGlpNumFreeArray (trow);
00494 EG_RETURN (rval);
00495 }
00496
00497 int ILLlib_basis_order (
00498 lpinfo * lp,
00499 int *header)
00500 {
00501 int rval = 0;
00502 int i, j;
00503 int ncols = lp->O->ncols;
00504 int nrows = lp->O->nrows;
00505 int nstruct = lp->O->nstruct;
00506 ILLlpdata *qslp = lp->O;
00507 int *invmap = 0;
00508
00509 ILL_SAFE_MALLOC (invmap, ncols, int);
00510
00511 for (j = 0; j < nstruct; j++)
00512 {
00513 invmap[qslp->structmap[j]] = j;
00514 }
00515 for (i = 0; i < nrows; i++)
00516 {
00517 invmap[qslp->rowmap[i]] = nstruct + i;
00518 }
00519
00520 for (i = 0; i < nrows; i++)
00521 {
00522 header[i] = invmap[lp->baz[i]];
00523 }
00524
00525 CLEANUP:
00526
00527 ILL_IFFREE (invmap, int);
00528
00529 EG_RETURN (rval);
00530 }
00531
00532 int ILLlib_chgbnd (
00533 lpinfo * lp,
00534 int indx,
00535 int lu,
00536 const EGlpNum_t bnd)
00537 {
00538 int rval = 0;
00539 int col;
00540
00541 if (!lp)
00542 {
00543 fprintf (stderr, "ILLlib_chgbnd called without an lp\n");
00544 rval = 1;
00545 ILL_CLEANUP;
00546 }
00547
00548 if (indx < 0 || indx > lp->O->nstruct)
00549 {
00550 fprintf (stderr, "ILLlib_chgbnd called with bad indx: %d\n", indx);
00551 rval = 1;
00552 ILL_CLEANUP;
00553 }
00554
00555 if (lp->O->sinfo)
00556 {
00557 ILLlp_sinfo_free (lp->O->sinfo);
00558 ILL_IFFREE (lp->O->sinfo, ILLlp_sinfo);
00559 }
00560
00561 col = lp->O->structmap[indx];
00562
00563 switch (lu)
00564 {
00565 case 'L':
00566 EGlpNumCopy (lp->O->lower[col], bnd);
00567 break;
00568 case 'U':
00569 EGlpNumCopy (lp->O->upper[col], bnd);
00570 break;
00571 case 'B':
00572 EGlpNumCopy (lp->O->lower[col], bnd);
00573 EGlpNumCopy (lp->O->upper[col], bnd);
00574 break;
00575 default:
00576 fprintf (stderr, "ILLlib_chgbnd called with lu: %c\n", lu);
00577 rval = 1;
00578 ILL_CLEANUP;
00579 }
00580
00581 CLEANUP:
00582
00583 EG_RETURN (rval);
00584 }
00585
00586 int ILLlib_chgbnds (
00587 lpinfo * lp,
00588 int cnt,
00589 int *indx,
00590 char *lu,
00591 const EGlpNum_t * bnd)
00592 {
00593 int rval = 0;
00594 int i;
00595
00596 for (i = 0; i < cnt; i++)
00597 {
00598 rval = ILLlib_chgbnd (lp, indx[i], lu[i], bnd[i]);
00599 if (rval)
00600 ILL_CLEANUP;
00601 }
00602
00603 CLEANUP:
00604
00605 EG_RETURN (rval);
00606 }
00607
00608 int ILLlib_getbnd (
00609 lpinfo * lp,
00610 int indx,
00611 int lu,
00612 EGlpNum_t * bnd)
00613 {
00614 int rval = 0;
00615 int col;
00616
00617 if (!lp)
00618 {
00619 fprintf (stderr, "ILLlib_getbnd called without an lp\n");
00620 rval = 1;
00621 ILL_CLEANUP;
00622 }
00623
00624 if (indx < 0 || indx > lp->O->nstruct)
00625 {
00626 fprintf (stderr, "ILLlib_getbnd called with bad indx: %d\n", indx);
00627 rval = 1;
00628 ILL_CLEANUP;
00629 }
00630
00631 col = lp->O->structmap[indx];
00632
00633 switch (lu)
00634 {
00635 case 'L':
00636 EGlpNumCopy (*bnd, lp->O->lower[col]);
00637 break;
00638 case 'U':
00639 EGlpNumCopy (*bnd, lp->O->upper[col]);
00640 break;
00641 default:
00642 fprintf (stderr, "ILLlib_getbnd called with lu: %c\n", lu);
00643 rval = 1;
00644 ILL_CLEANUP;
00645 }
00646
00647 CLEANUP:
00648
00649 EG_RETURN (rval);
00650 }
00651
00652 int ILLlib_getbnds_list (
00653 lpinfo *lp,
00654 int num,
00655 int*collist,
00656 EGlpNum_t *lower,
00657 EGlpNum_t *upper)
00658 {
00659 int rval = 0;
00660 ILLlpdata *qslp;
00661 int nstruct;
00662 int j, col;
00663
00664 if (!lp) {
00665 fprintf (stderr, "ILLlib_getbnds_list called without an lp\n");
00666 rval = 1; ILL_CLEANUP;
00667 }
00668
00669 qslp = lp->O;
00670 nstruct = qslp->nstruct;
00671 for (j = 0; j < num ; j++) {
00672 if(collist[j]<0|| collist[j] >= nstruct)
00673 {
00674 fprintf (stderr, "ILLlib_getbnds_list collist[%d] = %d out "
00675 "of range\n", j, collist[j]);
00676 }
00677 col = qslp->structmap[collist[j]];
00678 if (lower)
00679 EGlpNumCopy(lower[j], qslp->lower[col]);
00680 if (upper)
00681 EGlpNumCopy(upper[j], qslp->upper[col]);
00682 }
00683
00684 CLEANUP:
00685
00686 EG_RETURN(rval);
00687 }
00688
00689
00690 int ILLlib_getbnds (
00691 lpinfo * lp,
00692 EGlpNum_t * lower,
00693 EGlpNum_t * upper)
00694 {
00695 int rval = 0;
00696 ILLlpdata *qslp;
00697 int nstruct;
00698 int j, col;
00699
00700 if (!lp)
00701 {
00702 fprintf (stderr, "ILLlib_getbnd called without an lp\n");
00703 rval = 1;
00704 ILL_CLEANUP;
00705 }
00706
00707 qslp = lp->O;
00708 nstruct = qslp->nstruct;
00709
00710 for (j = 0; j < nstruct; j++)
00711 {
00712 col = qslp->structmap[j];
00713 if (lower)
00714 EGlpNumCopy (lower[j], qslp->lower[col]);
00715 if (upper)
00716 EGlpNumCopy (upper[j], qslp->upper[col]);
00717 }
00718
00719 CLEANUP:
00720
00721 EG_RETURN (rval);
00722 }
00723
00724 int ILLlib_strongbranch (
00725 lpinfo * lp,
00726 price_info * pinf,
00727 int *candidatelist,
00728 int ncand,
00729 EGlpNum_t * xlist,
00730 EGlpNum_t * downpen,
00731 EGlpNum_t * uppen,
00732 int iterations,
00733 EGlpNum_t objbound,
00734 itcnt_t*itcnt)
00735 {
00736 int rval = 0;
00737 int i, k, status, have_norms;
00738 int olditer = lp->maxiter;
00739 int nstruct = lp->O->nstruct;
00740 int nrows = lp->O->nrows;
00741 EGlpNum_t *myx = 0;
00742 EGlpNum_t xi, t, oldbnd;
00743 price_info lpinf;
00744 ILLlp_basis B, origB;
00745
00746 EGlpNumInitVar (lpinf.htrigger);
00747 EGlpNumInitVar (xi);
00748 EGlpNumInitVar (t);
00749 EGlpNumInitVar (oldbnd);
00750 EGlpNumZero (oldbnd);
00751 ILLlp_basis_init (&B);
00752 ILLlp_basis_init (&origB);
00753 ILLprice_init_pricing_info (&lpinf);
00754 lpinf.dI_price = QS_PRICE_DSTEEP;
00755 lpinf.dII_price = QS_PRICE_DSTEEP;
00756
00757 if (xlist == 0)
00758 {
00759 myx = EGlpNumAllocArray (nstruct);
00760 rval = ILLlib_get_x (lp, 0, myx);
00761 CHECKRVALG (rval, CLEANUP);
00762 }
00763
00764 rval = ILLlp_basis_alloc (&origB, nstruct, nrows);
00765 CHECKRVALG (rval, CLEANUP);
00766
00767 rval = ILLlib_getbasis (lp, origB.cstat, origB.rstat);
00768 CHECKRVALG (rval, CLEANUP);
00769
00770 check_pinf (pinf, &have_norms);
00771 if (have_norms == 0)
00772 {
00773 origB.rownorms = EGlpNumAllocArray (nrows);
00774 rval = ILLlib_getrownorms (lp, pinf, origB.rownorms);
00775 CHECKRVALG (rval, CLEANUP);
00776 }
00777 else
00778 {
00779 lp->basisid = -1;
00780 rval = ILLlib_optimize (lp, 0, &lpinf, DUAL_SIMPLEX, &status, 0, itcnt);
00781 CHECKRVALG (rval, CLEANUP);
00782 }
00783
00784 rval = ILLlp_basis_alloc (&B, nstruct, nrows);
00785
00786 CHECKRVALG (rval, CLEANUP);
00787
00788 rval = ILLlib_getbasis (lp, B.cstat, B.rstat);
00789 CHECKRVALG (rval, CLEANUP);
00790 B.rownorms = EGlpNumAllocArray (nrows);
00791
00792 if (have_norms == 0)
00793 {
00794 rval = ILLlib_getrownorms (lp, pinf, B.rownorms);
00795 CHECKRVALG (rval, CLEANUP);
00796 }
00797 else
00798 {
00799 rval = ILLlib_getrownorms (lp, &lpinf, B.rownorms);
00800 CHECKRVALG (rval, CLEANUP);
00801 }
00802
00803 lp->maxiter = iterations;
00804
00805 for (i = 0; i < ncand; i++)
00806 {
00807 k = candidatelist[i];
00808 rval = ILLlib_getbnd (lp, k, 'U', &oldbnd);
00809 CHECKRVALG (rval, CLEANUP);
00810 if (xlist)
00811 EGlpNumCopy (xi, xlist[i]);
00812 else
00813 EGlpNumCopy (xi, myx[k]);
00814 EGlpNumFloor (t, xi);
00815 if (EGlpNumIsLessDbl (t, 0.1) && EGlpNumIsGreaDbl (t, -0.1))
00816 EGlpNumZero (t);
00817
00818 rval = ILLlib_chgbnd (lp, k, 'U', t);
00819 CHECKRVALG (rval, CLEANUP);
00820
00821 rval = ILLlib_optimize (lp, &B, &lpinf, DUAL_SIMPLEX, &status, 0, itcnt);
00822 CHECKRVALG (rval, CLEANUP);
00823
00824 EGlpNumCopy (downpen[i], lp->dobjval);
00825 rval = ILLlib_chgbnd (lp, k, 'U', oldbnd);
00826 CHECKRVALG (rval, CLEANUP);
00827
00828 rval = ILLlib_getbnd (lp, k, 'L', &oldbnd);
00829 CHECKRVALG (rval, CLEANUP);
00830 EGlpNumCeil (t, xi);
00831 if (EGlpNumIsLessDbl (t, 1.1) && EGlpNumIsGreaDbl (t, 0.9))
00832 EGlpNumOne (t);
00833 rval = ILLlib_chgbnd (lp, k, 'L', t);
00834 CHECKRVALG (rval, CLEANUP);
00835
00836 rval = ILLlib_optimize (lp, &B, &lpinf, DUAL_SIMPLEX, &status, 0, itcnt);
00837 CHECKRVALG (rval, CLEANUP);
00838
00839 EGlpNumCopy (uppen[i], lp->dobjval);
00840 rval = ILLlib_chgbnd (lp, k, 'L', oldbnd);
00841 CHECKRVALG (rval, CLEANUP);
00842 }
00843
00844 if (lp->O->objsense == ILL_MAX)
00845 {
00846
00847 }
00848 else
00849 {
00850 for (i = 0; i < ncand; i++)
00851 {
00852 if (EGlpNumIsLess (objbound, downpen[i]))
00853 EGlpNumCopy (downpen[i], objbound);
00854 if (EGlpNumIsLess (objbound, uppen[i]))
00855 EGlpNumCopy (uppen[i], objbound);
00856 }
00857 }
00858
00859
00860
00861 lp->maxiter = olditer;
00862 rval = ILLlib_optimize (lp, &origB, pinf, DUAL_SIMPLEX, &status, 0, itcnt);
00863 CHECKRVALG (rval, CLEANUP);
00864
00865 CLEANUP:
00866
00867 EGlpNumClearVar (xi);
00868 EGlpNumClearVar (t);
00869 EGlpNumClearVar (oldbnd);
00870 lp->maxiter = olditer;
00871 ILLprice_free_pricing_info (&lpinf);
00872 ILLlp_basis_free (&B);
00873 ILLlp_basis_free (&origB);
00874 if (xlist == 0)
00875 EGlpNumFreeArray (myx);
00876 EGlpNumClearVar (lpinf.htrigger);
00877 EG_RETURN (rval);
00878 }
00879
00880 #define EXTRA_ROWS (100)
00881 #define EXTRA_COLS (100)
00882 #define EXTRA_MAT (1000)
00883
00884 int ILLlib_newrow (
00885 lpinfo * lp,
00886 ILLlp_basis * B,
00887 const EGlpNum_t rhs,
00888 int sense,
00889 const EGlpNum_t range,
00890 const char *name)
00891 {
00892 int rval = 0;
00893
00894 rval = ILLlib_addrow (lp, B, 0, 0, 0, rhs, sense, range, name);
00895 CHECKRVALG (rval, CLEANUP);
00896
00897 CLEANUP:
00898
00899 EG_RETURN (rval);
00900 }
00901
00902 int ILLlib_newrows (
00903 lpinfo * lp,
00904 ILLlp_basis * B,
00905 int num,
00906 const EGlpNum_t * rhs,
00907 char *sense,
00908 const EGlpNum_t * range,
00909 const char **names)
00910 {
00911 int rval = 0;
00912 int *rmatcnt = 0;
00913 int *rmatbeg = 0;
00914 int i;
00915
00916 if (!num)
00917 ILL_CLEANUP;
00918
00919 ILL_SAFE_MALLOC (rmatcnt, num, int);
00920
00921 ILL_SAFE_MALLOC (rmatbeg, num, int);
00922
00923 for (i = 0; i < num; i++)
00924 {
00925 rmatcnt[i] = 0;
00926 rmatbeg[i] = 0;
00927 }
00928
00929 rval = ILLlib_addrows (lp, B, num, rmatcnt, rmatbeg, 0, 0, rhs, sense,
00930 range, names, 0);
00931 CHECKRVALG (rval, CLEANUP);
00932
00933 CLEANUP:
00934
00935 ILL_IFFREE (rmatcnt, int);
00936 ILL_IFFREE (rmatbeg, int);
00937
00938 EG_RETURN (rval);
00939 }
00940
00941 int ILLlib_addrows (
00942 lpinfo * lp,
00943 ILLlp_basis * B,
00944 int num,
00945 int *rmatcnt,
00946 int *rmatbeg,
00947 int *rmatind,
00948 const EGlpNum_t * rmatval,
00949 const EGlpNum_t * rhs,
00950 char *sense,
00951 const EGlpNum_t * range,
00952 const char **names,
00953 int *factorok)
00954 {
00955 int rval = 0;
00956 int i, j, total, bsing;
00957 int *imap = 0;
00958 int *bbeg = 0;
00959 int *bcnt = 0;
00960 int *bindi = 0;
00961 int *rindi = 0;
00962 int *jstat = 0;
00963 EGlpNum_t *bval = 0;
00964 EGlpNum_t rng;
00965 int badfactor = 0;
00966
00967 EGlpNumInitVar (rng);
00968
00969 if (B == 0 || B->rownorms == 0)
00970 {
00971 if (factorok)
00972 *factorok = 0;
00973 }
00974
00975 if (B)
00976 EGlpNumFreeArray (B->colnorms);
00977
00978 if (B && B->rownorms && factorok && *factorok == 1)
00979 {
00980 int *structmap = lp->O->structmap;
00981
00982 lp->matbeg = lp->O->A.matbeg;
00983 lp->matcnt = lp->O->A.matcnt;
00984 lp->matind = lp->O->A.matind;
00985 lp->matval = lp->O->A.matval;
00986
00987 lp->nrows = lp->O->nrows;
00988 lp->ncols = lp->O->ncols;
00989 if (B->rownorms_size < lp->O->nrows + num)
00990 EGlpNumReallocArray (&(B->rownorms), lp->O->nrows + num);
00991
00992 ILL_SAFE_MALLOC (bcnt, num, int);
00993 ILL_SAFE_MALLOC (bbeg, num, int);
00994 ILL_SAFE_MALLOC (imap, lp->O->nstruct, int);
00995
00996 ILL_SAFE_MALLOC (jstat, lp->ncols, int);
00997
00998 for (i = 0; i < lp->ncols; i++)
00999 {
01000 jstat[i] = -1;
01001 }
01002 for (i = 0; i < lp->O->nstruct; i++)
01003 {
01004 jstat[structmap[i]] = i;
01005 }
01006
01007 for (i = 0; i < lp->O->nstruct; i++)
01008 {
01009 imap[i] = -1;
01010 }
01011 for (i = 0; i < lp->O->nrows; i++)
01012 {
01013 if (jstat[lp->baz[i]] != -1)
01014 {
01015 imap[jstat[lp->baz[i]]] = i;
01016 }
01017 }
01018
01019 for (i = 0, total = 0; i < num; i++)
01020 {
01021 bcnt[i] = 0;
01022 bbeg[i] = total;
01023 for (j = 0; j < rmatcnt[i]; j++)
01024 {
01025 if (imap[rmatind[rmatbeg[i] + j]] != -1)
01026 {
01027 bcnt[i]++;
01028 total++;
01029 }
01030 }
01031 }
01032 if (total)
01033 {
01034 ILL_SAFE_MALLOC (bindi, total, int);
01035
01036 bval = EGlpNumAllocArray (total);
01037 }
01038 for (i = 0, total = 0; i < num; i++)
01039 {
01040 for (j = 0; j < rmatcnt[i]; j++)
01041 {
01042 if (imap[rmatind[rmatbeg[i] + j]] != -1)
01043 {
01044 EGlpNumCopy (bval[total], rmatval[rmatbeg[i] + j]);
01045 bindi[total] = imap[rmatind[rmatbeg[i] + j]];
01046 total++;
01047 }
01048 }
01049 }
01050
01051 rval = ILLprice_get_new_rownorms (lp, num, B->rownorms + lp->O->nrows,
01052 bcnt, bbeg, bindi, bval);
01053 CHECKRVALG (rval, CLEANUP);
01054
01055 ILL_IFFREE (bcnt, int);
01056 ILL_IFFREE (bbeg, int);
01057 ILL_IFFREE (bindi, int);
01058
01059 EGlpNumFreeArray (bval);
01060 ILL_IFFREE (imap, int);
01061
01062 badfactor = 1;
01063 }
01064
01065 for (i = 0; i < num; i++)
01066 {
01067 if (range)
01068 EGlpNumCopy (rng, range[i]);
01069 else
01070 EGlpNumZero (rng);
01071 if (names)
01072 {
01073 rval = ILLlib_addrow (lp, B, rmatcnt[i], rmatind + rmatbeg[i],
01074 rmatval + rmatbeg[i], rhs[i], sense[i], rng,
01075 names[i]);
01076 }
01077 else
01078 {
01079 rval = ILLlib_addrow (lp, B, rmatcnt[i], rmatind + rmatbeg[i],
01080 rmatval + rmatbeg[i], rhs[i], sense[i], rng, 0);
01081 }
01082 CHECKRVALG (rval, CLEANUP);
01083 }
01084
01085
01086 if (B && B->rownorms && (factorok && *factorok == 0))
01087 {
01088 lp->matbeg = lp->O->A.matbeg;
01089 lp->matcnt = lp->O->A.matcnt;
01090 lp->matind = lp->O->A.matind;
01091 lp->matval = lp->O->A.matval;
01092 lp->nrows = lp->O->nrows;
01093 lp->ncols = lp->O->ncols;
01094 lp->bz = lp->O->rhs;
01095 lp->nnbasic = lp->ncols - lp->nrows;
01096
01097 rval = ILLbasis_load (lp, B);
01098 CHECKRVALG (rval, CLEANUP);
01099
01100 if (lp->f)
01101 ILLfactor_free_factor_work (lp->f);
01102
01103 rval = ILLbasis_factor (lp, &bsing);
01104 CHECKRVALG (rval, CLEANUP);
01105 if (bsing)
01106 MESSAGE (__QS_SB_VERB, "Singular Basis found!");
01107 *factorok = 1;
01108
01109 if (B->rownorms_size < lp->O->nrows)
01110 EGlpNumReallocArray (&(B->rownorms), lp->O->nrows);
01111
01112 ILL_SAFE_MALLOC (rindi, lp->O->nrows , int);
01113
01114 for (i = 0; i < num; i++)
01115 {
01116 rindi[i] = lp->O->nrows - num + i;
01117 }
01118
01119 rval = ILLprice_get_dsteep_norms (lp, num, rindi,
01120 B->rownorms + lp->O->nrows - num);
01121 CHECKRVALG (rval, CLEANUP);
01122 }
01123
01124 if (factorok != 0 && badfactor == 1)
01125 {
01126 *factorok = 0;
01127 }
01128
01129
01130 CLEANUP:
01131
01132 ILL_IFFREE (bcnt, int);
01133 ILL_IFFREE (bbeg, int);
01134 ILL_IFFREE (bindi, int);
01135
01136 EGlpNumFreeArray (bval);
01137 ILL_IFFREE (imap, int);
01138 ILL_IFFREE (jstat, int);
01139 ILL_IFFREE (rindi, int);
01140
01141 EGlpNumClearVar (rng);
01142 EG_RETURN (rval);
01143 }
01144
01145 int ILLlib_addrow (
01146 lpinfo * lp,
01147 ILLlp_basis * B,
01148 int cnt,
01149 int *ind,
01150 const EGlpNum_t * val,
01151 const EGlpNum_t rhs,
01152 int sense,
01153 const EGlpNum_t range,
01154 const char *name)
01155 {
01156 int rval = 0;
01157 ILLlpdata *qslp;
01158 ILLmatrix *A;
01159 int i, nrows, ncols;
01160 char buf[ILL_namebufsize];
01161 int tind[1];
01162 EGlpNum_t tval[1];
01163 int *tempind = 0;
01164 int pind, hit;
01165
01166 EGlpNumInitVar (tval[0]);
01167
01168 if (!lp)
01169 {
01170 fprintf (stderr, "ILLlib_addrow called without an lp\n");
01171 rval = 1;
01172 ILL_CLEANUP;
01173 }
01174
01175 qslp = lp->O;
01176 A = &qslp->A;
01177
01178 if (qslp->rA)
01179 {
01180 ILLlp_rows_clear (qslp->rA);
01181 ILL_IFFREE (qslp->rA, ILLlp_rows);
01182 }
01183
01184 if (qslp->sinfo)
01185 {
01186 ILLlp_sinfo_free (qslp->sinfo);
01187 ILL_IFFREE (qslp->sinfo, ILLlp_sinfo);
01188 }
01189
01190 nrows = qslp->nrows;
01191 ncols = qslp->ncols;
01192
01193
01194
01195 if (sense == 'R' && !(qslp->rangeval) && qslp->rowsize > 0)
01196 {
01197 qslp->rangeval = EGlpNumAllocArray (qslp->rowsize);
01198 for (i = 0; i < qslp->nrows; i++)
01199 {
01200 EGlpNumZero (qslp->rangeval[i]);
01201 }
01202 }
01203
01204
01205
01206 if (qslp->rowsize < nrows + 1)
01207 {
01208 EGlpNumReallocArray (&(qslp->rhs), qslp->rowsize + EXTRA_ROWS);
01209 qslp->sense = EGrealloc (qslp->sense,
01210 sizeof (char) * (qslp->rowsize + EXTRA_ROWS));
01211
01212
01213
01214
01215 qslp->rowmap = EGrealloc (qslp->rowmap,
01216 sizeof (int) * (qslp->rowsize + EXTRA_ROWS));
01217
01218
01219
01220
01221 if (qslp->rangeval || sense == 'R')
01222 EGlpNumReallocArray (&(qslp->rangeval), qslp->rowsize + EXTRA_ROWS);
01223
01224 qslp->rownames = EGrealloc (qslp->rownames,
01225 sizeof (char *) * (qslp->rowsize + EXTRA_ROWS));
01226
01227
01228
01229
01230 qslp->rowsize += EXTRA_ROWS;
01231 }
01232
01233 EGlpNumCopy (qslp->rhs[nrows], rhs);
01234 qslp->sense[nrows] = sense;
01235 qslp->rowmap[nrows] = ncols;
01236 if (qslp->rangeval)
01237 {
01238 if (sense == 'R')
01239 EGlpNumCopy (qslp->rangeval[nrows], range);
01240 else
01241 EGlpNumZero (qslp->rangeval[nrows]);
01242 }
01243 ILL_FAILtrue (qslp->rownames == NULL, "must always be non NULL");
01244 ILLlib_findName (qslp, 1 , name, nrows, buf);
01245 ILL_UTIL_STR (qslp->rownames[nrows], buf);
01246 ILLsymboltab_register (&qslp->rowtab, buf, qslp->nrows, &pind, &hit);
01247 ILL_FAILfalse (hit == 0, "must be new");
01248
01249
01250
01251
01252 if (qslp->colsize < ncols + 1)
01253 {
01254 EGlpNumReallocArray (&(qslp->lower), qslp->colsize + EXTRA_COLS);
01255 EGlpNumReallocArray (&(qslp->upper), qslp->colsize + EXTRA_COLS);
01256 EGlpNumReallocArray (&(qslp->obj), qslp->colsize + EXTRA_COLS);
01257 qslp->colsize += EXTRA_COLS;
01258 }
01259
01260 EGlpNumZero (qslp->obj[ncols]);
01261 EGlpNumZero (qslp->lower[ncols]);
01262 if (sense == 'E')
01263 {
01264 EGlpNumZero (qslp->upper[ncols]);
01265 }
01266 else if (sense == 'R')
01267 {
01268 EGlpNumCopy (qslp->upper[ncols], range);
01269 }
01270 else
01271 {
01272 EGlpNumCopy (qslp->upper[ncols], ILL_MAXDOUBLE);
01273 }
01274
01275
01276
01277
01278
01279 if (cnt)
01280 {
01281 ILL_SAFE_MALLOC (tempind, cnt, int);
01282
01283 for (i = 0; i < cnt; i++)
01284 {
01285 tempind[i] = qslp->structmap[ind[i]];
01286 }
01287 }
01288
01289 rval = matrix_addrow (A, cnt, tempind, val);
01290 CHECKRVALG (rval, CLEANUP);
01291
01292 tind[0] = nrows;
01293 EGlpNumOne (*tval);
01294 if (sense == 'G' || sense == 'R')
01295 EGlpNumSign (*tval);
01296
01297 rval = matrix_addcol (A, 1, tind, tval);
01298 CHECKRVALG (rval, CLEANUP);
01299
01300 if (B != 0)
01301 {
01302 B->rstat = EGrealloc (B->rstat, sizeof (char) * (nrows + 1));
01303
01304
01305
01306 B->rstat[nrows] = QS_ROW_BSTAT_BASIC;
01307 }
01308
01309 #if 0
01310 lp->basisid = -1;
01311 #endif
01312
01313 qslp->ncols++;
01314 qslp->nrows++;
01315 qslp->nzcount += (cnt + 1);
01316
01317 if (B != 0)
01318 {
01319 B->nrows++;
01320 }
01321
01322 CLEANUP:
01323 ILL_IFFREE (tempind, int);
01324
01325 EGlpNumClearVar (tval[0]);
01326 EG_RETURN (rval);
01327 }
01328
01329 int ILLlib_delrows (
01330 lpinfo * lp,
01331 ILLlp_basis * B,
01332 ILLlp_cache * C,
01333 int num,
01334 int *dellist,
01335 int *basis_ok,
01336 int *cache_ok)
01337 {
01338 int rval = 0;
01339 int i, j, k, nrows, ncols, nstruct, spot, dk, bok = 0, cok = 0;
01340 ILLlpdata *qslp;
01341 ILLmatrix *A;
01342 char *rowmark = 0;
01343 char *colmark = 0;
01344 int *newrowindex = 0;
01345 int *newcolindex = 0;
01346 int *ind, *beg, *cnt;
01347 EGlpNum_t *val;
01348
01349 if (!lp)
01350 {
01351 fprintf (stderr, "ILLlib_delrows called without an lp\n");
01352 rval = 1;
01353 ILL_CLEANUP;
01354 }
01355
01356 if (num <= 0)
01357 {
01358 if (basis_ok)
01359 *basis_ok = 1;
01360 if (cache_ok)
01361 *cache_ok = 1;
01362 ILL_CLEANUP;
01363 }
01364
01365 if (basis_ok)
01366 *basis_ok = 0;
01367 if (cache_ok)
01368 *cache_ok = 0;
01369
01370 qslp = lp->O;
01371 A = &qslp->A;
01372
01373 if (qslp->rA)
01374 {
01375 ILLlp_rows_clear (qslp->rA);
01376 ILL_IFFREE (qslp->rA, ILLlp_rows);
01377 }
01378
01379 nrows = A->matrows;
01380 ncols = A->matcols;
01381 ind = A->matind;
01382 beg = A->matbeg;
01383 cnt = A->matcnt;
01384 val = A->matval;
01385 nstruct = qslp->nstruct;
01386
01387 ILL_SAFE_MALLOC (rowmark, nrows, char);
01388
01389 for (i = 0; i < nrows; i++)
01390 {
01391 rowmark[i] = 0;
01392 }
01393 for (i = 0; i < num; i++)
01394 {
01395 rowmark[dellist[i]] = 1;
01396 }
01397
01398
01399
01400
01401 if (B)
01402 {
01403 bok = 1;
01404 cok = 1;
01405 for (i = 0; i < num; i++)
01406 {
01407 j = dellist[i];
01408 if (B->rstat[j] == QS_ROW_BSTAT_LOWER ||
01409 B->rstat[j] == QS_ROW_BSTAT_UPPER)
01410 {
01411 bok = 0;
01412 break;
01413 }
01414 if (C && EGlpNumIsLess (DFEAS_TOLER, C->pi[j]))
01415 {
01416
01417
01418
01419
01420 cok = 0;
01421 }
01422 }
01423 if (bok == 1)
01424 {
01425 EGlpNumFreeArray (B->colnorms);
01426 if (B->rownorms)
01427 {
01428 for (i = 0, k = 0; i < nstruct; i++)
01429 {
01430 if (B->cstat[i] == QS_COL_BSTAT_BASIC)
01431 k++;
01432 }
01433 for (i = 0, j = k; i < nrows; i++)
01434 {
01435 if (B->rstat[i] == QS_ROW_BSTAT_BASIC)
01436 {
01437 if (rowmark[i] == 0)
01438 {
01439 EGlpNumCopy (B->rownorms[k++], B->rownorms[j]);
01440 }
01441 j++;
01442 }
01443 }
01444 if (k != nrows - num)
01445 {
01446 fprintf (stderr, "error in ILLlib_delrows\n");
01447 rval = 1;
01448 ILL_CLEANUP;
01449 }
01450 }
01451
01452 for (i = 0, j = 0; i < nrows; i++)
01453 {
01454 if (rowmark[i] == 0)
01455 {
01456 B->rstat[j++] = B->rstat[i];
01457 }
01458 }
01459 B->nrows = j;
01460
01461 if (C && cok == 1)
01462 {
01463 for (i = 0, j = 0; i < nrows; i++)
01464 {
01465 if (rowmark[i] == 0)
01466 {
01467 EGlpNumCopy (C->pi[j], C->pi[i]);
01468 EGlpNumCopy (C->slack[j++], C->slack[i]);
01469 }
01470 }
01471 C->nrows = j;
01472 if (cache_ok)
01473 *cache_ok = 1;
01474 }
01475 if (basis_ok)
01476 *basis_ok = 1;
01477 }
01478 }
01479
01480 ILL_SAFE_MALLOC (newrowindex, nrows, int);
01481
01482
01483
01484
01485 ILL_FAILtrue (qslp->rownames == NULL, "must always be non NULL");
01486 for (i = 0, j = 0; i < nrows; i++)
01487 {
01488 if (rowmark[i] == 0)
01489 {
01490 if (i != j)
01491 {
01492 EGlpNumCopy (qslp->rhs[j], qslp->rhs[i]);
01493 qslp->sense[j] = qslp->sense[i];
01494 if (qslp->rangeval)
01495 EGlpNumCopy (qslp->rangeval[j], qslp->rangeval[i]);
01496 if (qslp->rownames)
01497 qslp->rownames[j] = qslp->rownames[i];
01498 }
01499 newrowindex[i] = j++;
01500 }
01501 else
01502 {
01503 if (qslp->rownames)
01504 {
01505 rval = ILLsymboltab_delete (&qslp->rowtab, qslp->rownames[i]);
01506 CHECKRVALG (rval, CLEANUP);
01507 ILL_IFFREE (qslp->rownames[i], char);
01508 }
01509 }
01510 }
01511
01512
01513
01514
01515 ILL_SAFE_MALLOC (colmark, ncols, char);
01516
01517 for (i = 0; i < ncols; i++)
01518 {
01519 colmark[i] = 0;
01520 }
01521 for (i = 0; i < num; i++)
01522 {
01523 colmark[qslp->rowmap[dellist[i]]] = 1;
01524 }
01525
01526 rval = delcols_work (lp, colmark);
01527 CHECKRVALG (rval, CLEANUP);
01528
01529 A->matcols -= num;
01530 qslp->ncols -= num;
01531
01532
01533
01534
01535 for (i = 0, j = 0; i < nrows; i++)
01536 {
01537 if (rowmark[i] == 0)
01538 {
01539 qslp->rowmap[j++] = qslp->rowmap[i];
01540 }
01541 }
01542
01543
01544
01545 for (i = 0; i < ncols - num; i++)
01546 {
01547 dk = 0;
01548 spot = beg[i];
01549 for (j = 0; j < cnt[i]; j++)
01550 {
01551 if (rowmark[ind[beg[i] + j]] == 1)
01552 {
01553 dk++;
01554 }
01555 else
01556 {
01557 EGlpNumCopy (val[spot], val[beg[i] + j]);
01558 ind[spot] = newrowindex[ind[beg[i] + j]];
01559 spot++;
01560 }
01561 }
01562 for (; spot < beg[i] + cnt[i]; spot++)
01563 {
01564 ind[spot] = -1;
01565 }
01566
01567 cnt[i] -= dk;
01568 if (cnt[i] == 0)
01569 {
01570 ind[beg[i]] = 1;
01571 }
01572 }
01573
01574 A->matrows -= num;
01575 qslp->nrows -= num;
01576
01577 #if 0
01578 lp->basisid = -1;
01579 #endif
01580
01581
01582 if(bok)
01583 {
01584 rval = ILLbasis_load( lp, B);
01585 CHECKRVALG (rval, CLEANUP);
01586 }
01587 CLEANUP:
01588
01589 ILL_IFFREE (rowmark, char);
01590 ILL_IFFREE (colmark, char);
01591 ILL_IFFREE (newcolindex, int);
01592 ILL_IFFREE (newrowindex, int);
01593
01594 EG_RETURN (rval);
01595 }
01596
01597 int ILLlib_delcols (
01598 lpinfo * lp,
01599 ILLlp_basis * B,
01600 int num,
01601 int *dellist,
01602 int *basis_ok)
01603 {
01604 int rval = 0;
01605 int i, j, bok = 0, ncols;
01606 char *colmark = 0;
01607 ILLlpdata *qslp;
01608
01609 if (!lp)
01610 {
01611 fprintf (stderr, "ILLlib_delcols called without an lp\n");
01612 rval = 1;
01613 ILL_CLEANUP;
01614 }
01615
01616 if (basis_ok)
01617 *basis_ok = 0;
01618
01619 if (num <= 0)
01620 {
01621 *basis_ok = 1;
01622 ILL_CLEANUP;
01623 }
01624
01625 qslp = lp->O;
01626 ncols = qslp->A.matcols;
01627
01628 if (qslp->rA)
01629 {
01630 ILLlp_rows_clear (qslp->rA);
01631 ILL_IFFREE (qslp->rA, ILLlp_rows);
01632 }
01633
01634 ILL_SAFE_MALLOC (colmark, ncols, char);
01635
01636 for (i = 0; i < ncols; i++)
01637 {
01638 colmark[i] = 0;
01639 }
01640 for (i = 0; i < num; i++)
01641 {
01642 colmark[qslp->structmap[dellist[i]]] = 1;
01643 }
01644
01645 if (B)
01646 {
01647 B->nstruct -= num;
01648 bok = 1;
01649 for (i = 0; i < num; i++)
01650 {
01651 j = dellist[i];
01652 if (B->cstat[j] == QS_COL_BSTAT_BASIC)
01653 {
01654 bok = 0;
01655
01656
01657 break;
01658 }
01659 }
01660 if (bok == 1)
01661 {
01662 EGlpNumFreeArray (B->colnorms);
01663 for (i = 0, j = 0; i < qslp->nstruct; i++)
01664 {
01665 if (colmark[qslp->structmap[i]] == 0)
01666 {
01667 B->cstat[j++] = B->cstat[i];
01668 }
01669 }
01670 if (basis_ok)
01671 *basis_ok = 1;
01672 }
01673 }
01674
01675 rval = delcols_work (lp, colmark);
01676 CHECKRVALG (rval, CLEANUP);
01677
01678
01679 qslp->A.matcols -= num;
01680 qslp->ncols -= num;
01681 qslp->nstruct -= num;
01682
01683
01684 if(bok)
01685 {
01686 rval = ILLbasis_load( lp, B);
01687 CHECKRVALG (rval, CLEANUP);
01688 }
01689 #if 0
01690 lp->basisid = -1;
01691 #endif
01692
01693 CLEANUP:
01694
01695 ILL_IFFREE (colmark, char);
01696
01697 EG_RETURN (rval);
01698 }
01699
01700 static int matrix_getcoef (
01701 ILLmatrix *A,
01702 int row,
01703 int col,
01704 EGlpNum_t*val)
01705 {
01706 int i;
01707 int rval = 0;
01708 if (row >= A->matrows || row < 0)
01709 {
01710 fprintf (stderr, "illegal row index in matrix_getcoef\n");
01711 rval= 1;
01712 ILL_CLEANUP;
01713 }
01714
01715 if (col >= A->matcols || col < 0)
01716 {
01717 fprintf (stderr, "illegal col index in matrix_getcoef\n");
01718 rval= 1;
01719 ILL_CLEANUP;
01720 }
01721
01722
01723 EGlpNumZero(*val);
01724 for (i = A->matbeg[col]; i < A->matbeg[col] + A->matcnt[col]; i++)
01725 {
01726 if (A->matind[i] == row)
01727 {
01728 EGlpNumCopy(*val, A->matval[i]);
01729 ILL_CLEANUP;
01730 }
01731 }
01732
01733 CLEANUP:
01734
01735 EG_RETURN(rval);
01736 }
01737
01738 static int delcols_work (
01739 lpinfo * lp,
01740 char *colmark)
01741 {
01742 int rval = 0;
01743 int i, j, k, nrows, ncols;
01744 ILLlpdata *qslp;
01745 ILLmatrix *A;
01746 int *newcolindex = 0;
01747 int *ind, *beg, *cnt;
01748
01749
01750
01751 qslp = lp->O;
01752 A = &qslp->A;
01753 nrows = A->matrows;
01754 ncols = A->matcols;
01755 ind = A->matind;
01756 beg = A->matbeg;
01757 cnt = A->matcnt;
01758
01759 ILL_SAFE_MALLOC (newcolindex, ncols, int);
01760
01761
01762
01763 for (i = 0, j = 0; i < ncols; i++)
01764 {
01765 if (colmark[i] == 0)
01766 {
01767 if (i != j)
01768 {
01769 beg[j] = beg[i];
01770 cnt[j] = cnt[i];
01771 EGlpNumCopy (qslp->obj[j], qslp->obj[i]);
01772 EGlpNumCopy (qslp->lower[j], qslp->lower[i]);
01773 EGlpNumCopy (qslp->upper[j], qslp->upper[i]);
01774 }
01775 newcolindex[i] = j++;
01776 }
01777 else
01778 {
01779 for (k = 0; k < cnt[i]; k++)
01780 {
01781 ind[beg[i] + k] = -1;
01782 }
01783 newcolindex[i] = -1;
01784 }
01785 }
01786
01787
01788
01789 for (i = 0, j = 0; i < qslp->nstruct; i++)
01790 {
01791 k = qslp->structmap[i];
01792 if (colmark[k] == 0)
01793 {
01794 qslp->structmap[j] = newcolindex[k];
01795 qslp->colnames[j] = qslp->colnames[i];
01796 if (qslp->intmarker)
01797 qslp->intmarker[j] = qslp->intmarker[i];
01798 j++;
01799 }
01800 else
01801 {
01802 rval = ILLsymboltab_delete (&qslp->coltab, qslp->colnames[i]);
01803 CHECKRVALG (rval, CLEANUP);
01804 ILL_IFFREE (qslp->colnames[i], char);
01805 }
01806 }
01807
01808
01809
01810 for (i = 0; i < nrows; i++)
01811 {
01812 qslp->rowmap[i] = newcolindex[qslp->rowmap[i]];
01813 }
01814
01815 CLEANUP:
01816
01817 ILL_IFFREE (newcolindex, int);
01818
01819 EG_RETURN (rval);
01820 }
01821
01822 int ILLlib_getcoef (
01823 lpinfo *lp,
01824 int rowindex,
01825 int colindex,
01826 EGlpNum_t* coef)
01827 {
01828 int rval = 0;
01829 ILLlpdata *qslp;
01830 ILLmatrix *A;
01831 int nrows, nstruct, j;
01832 if (!lp)
01833 {
01834 fprintf (stderr, "ILLlib_chgcoef called without an lp\n");
01835 rval = 1;
01836 ILL_CLEANUP;
01837 }
01838
01839 qslp = lp->O;
01840 A = &qslp->A;
01841 nrows = qslp->nrows;
01842 nstruct = qslp->nstruct;
01843
01844 if (rowindex < 0 || rowindex >= nrows || colindex < 0 || colindex >= nstruct)
01845 {
01846 fprintf (stderr, "ILLlib_getcoef called with out-of-range index\n");
01847 rval = 1;
01848 ILL_CLEANUP;
01849 }
01850
01851 j = qslp->structmap[colindex];
01852 rval = matrix_getcoef (A, rowindex, j, coef);
01853 CHECKRVALG(rval, CLEANUP);
01854
01855 CLEANUP:
01856
01857 EG_RETURN (rval);
01858 }
01859
01860 int ILLlib_chgcoef (
01861 lpinfo * lp,
01862 int rowindex,
01863 int colindex,
01864 EGlpNum_t coef)
01865 {
01866 int rval = 0;
01867 ILLlpdata *qslp;
01868 ILLmatrix *A;
01869 int nrows, nstruct, j;
01870
01871 if (!lp)
01872 {
01873 fprintf (stderr, "ILLlib_chgcoef called without an lp\n");
01874 rval = 1;
01875 ILL_CLEANUP;
01876 }
01877
01878 qslp = lp->O;
01879 A = &qslp->A;
01880
01881 nrows = qslp->nrows;
01882 nstruct = qslp->nstruct;
01883
01884 if (rowindex < 0 || rowindex >= nrows || colindex < 0 || colindex >= nstruct)
01885 {
01886 fprintf (stderr, "ILLlib_chgcoef called with out-of-range index\n");
01887 rval = 1;
01888 ILL_CLEANUP;
01889 }
01890
01891 if (qslp->rA)
01892 {
01893 ILLlp_rows_clear (qslp->rA);
01894 ILL_IFFREE (qslp->rA, ILLlp_rows);
01895 }
01896
01897 if (qslp->sinfo)
01898 {
01899 ILLlp_sinfo_free (qslp->sinfo);
01900 ILL_IFFREE (qslp->sinfo, ILLlp_sinfo);
01901 }
01902
01903 j = qslp->structmap[colindex];
01904
01905 rval = matrix_addcoef (lp, A, rowindex, j, coef);
01906 CHECKRVALG (rval, CLEANUP);
01907
01908 CLEANUP:
01909
01910 EG_RETURN (rval);
01911 }
01912
01913 int ILLlib_chgsense (
01914 lpinfo * lp,
01915 int num,
01916 int *rowlist,
01917 char *sense)
01918 {
01919 int rval = 0;
01920 int i, j, k;
01921 ILLlpdata *qslp = lp->O;
01922 ILLmatrix *A = &(lp->O->A);
01923
01924 for (i = 0; i < num; i++)
01925 {
01926 j = qslp->rowmap[rowlist[i]];
01927 if (A->matcnt[j] != 1)
01928 {
01929 fprintf (stderr, "logical variable is not a singleton\n");
01930 rval = 1;
01931 ILL_CLEANUP;
01932 }
01933 k = A->matbeg[j];
01934 switch (sense[i])
01935 {
01936 case 'R':
01937
01938
01939 qslp->sense[rowlist[i]] = 'R';
01940 EGlpNumZero(qslp->lower[j]);
01941 EGlpNumZero(qslp->upper[j]);
01942 EGlpNumOne(A->matval[k]);
01943 break;
01944 case 'E':
01945 qslp->sense[rowlist[i]] = 'E';
01946 EGlpNumZero (qslp->lower[j]);
01947 EGlpNumZero (qslp->upper[j]);
01948 EGlpNumOne (A->matval[k]);
01949 break;
01950 case 'G':
01951 qslp->sense[rowlist[i]] = 'G';
01952 EGlpNumZero (qslp->lower[j]);
01953 EGlpNumCopy (qslp->upper[j], ILL_MAXDOUBLE);
01954 EGlpNumOne (A->matval[k]);
01955 EGlpNumSign (A->matval[k]);
01956 break;
01957 case 'L':
01958 qslp->sense[rowlist[i]] = 'L';
01959 EGlpNumZero (qslp->lower[j]);
01960 EGlpNumCopy (qslp->upper[j], ILL_MAXDOUBLE);
01961 EGlpNumOne (A->matval[k]);
01962 break;
01963 default:
01964 fprintf (stderr, "illegal sense %c in ILLlib_chgsense\n", sense[i]);
01965 rval = 1;
01966 ILL_CLEANUP;
01967 }
01968 }
01969
01970 CLEANUP:
01971
01972 EG_RETURN (rval);
01973 }
01974
01975 int ILLlib_getsenses (
01976 lpinfo *lp,
01977 char *senses)
01978 {
01979 ILLlpdata *qslp;
01980 int nrows, i;
01981 int rval = 0;
01982
01983 if (!lp) {
01984 fprintf (stderr, "ILLlib_getsense called without an LP\n");
01985 rval = 1;
01986 ILL_CLEANUP;
01987 }
01988
01989 qslp = lp->O;
01990 nrows = qslp->nrows;
01991
01992 for (i = 0; i < nrows; i++)
01993 {
01994 senses[i] = qslp->sense[i];
01995 }
01996
01997 CLEANUP:
01998
01999 EG_RETURN(rval);
02000 }
02001
02002 int ILLlib_newcol (
02003 lpinfo * lp,
02004 ILLlp_basis * B,
02005 const EGlpNum_t obj,
02006 const EGlpNum_t lower,
02007 const EGlpNum_t upper,
02008 const char *name,
02009 int factorok)
02010 {
02011 int rval = 0;
02012
02013 rval = ILLlib_addcol (lp, B, 0, 0, 0, obj, lower, upper, name, factorok);
02014 CHECKRVALG (rval, CLEANUP);
02015
02016 CLEANUP:
02017
02018 EG_RETURN (rval);
02019 }
02020
02021 int ILLlib_newcols (
02022 lpinfo * lp,
02023 ILLlp_basis * B,
02024 int num,
02025 EGlpNum_t * obj,
02026 EGlpNum_t * lower,
02027 EGlpNum_t * upper,
02028 const char **names,
02029 int factorok)
02030 {
02031 int rval = 0;
02032 int *cmatcnt = 0;
02033 int *cmatbeg = 0;
02034 int i;
02035
02036 ILL_SAFE_MALLOC (cmatcnt, num, int);
02037
02038 ILL_SAFE_MALLOC (cmatbeg, num, int);
02039
02040 for (i = 0; i < num; i++)
02041 {
02042 cmatcnt[i] = 0;
02043 cmatbeg[i] = 0;
02044 }
02045
02046 rval = ILLlib_addcols (lp, B, num, cmatcnt, cmatbeg, 0,
02047 0, obj, lower, upper, names, factorok);
02048 CHECKRVALG (rval, CLEANUP);
02049
02050
02051 CLEANUP:
02052
02053 ILL_IFFREE (cmatcnt, int);
02054 ILL_IFFREE (cmatbeg, int);
02055
02056 EG_RETURN (rval);
02057 }
02058
02059 int ILLlib_addcols (
02060 lpinfo * lp,
02061 ILLlp_basis * B,
02062 int num,
02063 int *cmatcnt,
02064 int *cmatbeg,
02065 int *cmatind,
02066 EGlpNum_t * cmatval,
02067 EGlpNum_t * obj,
02068 EGlpNum_t * lower,
02069 EGlpNum_t * upper,
02070 const char **names,
02071 int factorok)
02072 {
02073 int rval = 0;
02074 int i;
02075
02076 for (i = 0; i < num; i++)
02077 {
02078 if (names)
02079 {
02080 rval = ILLlib_addcol (lp, B, cmatcnt[i], cmatind + cmatbeg[i],
02081 cmatval + cmatbeg[i], obj[i], lower[i],
02082 upper[i], names[i], factorok);
02083 }
02084 else
02085 {
02086 rval = ILLlib_addcol (lp, B, cmatcnt[i], cmatind + cmatbeg[i],
02087 cmatval + cmatbeg[i], obj[i], lower[i],
02088 upper[i], 0, factorok);
02089 }
02090 CHECKRVALG (rval, CLEANUP);
02091 }
02092
02093 CLEANUP:
02094
02095 EG_RETURN (rval);
02096 }
02097
02098 int ILLlib_addcol (
02099 lpinfo * lp,
02100 ILLlp_basis * B,
02101 int cnt,
02102 int *ind,
02103 EGlpNum_t * val,
02104 const EGlpNum_t obj,
02105 const EGlpNum_t lower,
02106 const EGlpNum_t upper,
02107 const char *name,
02108 int factorok)
02109 {
02110 int rval = 0;
02111 ILLlpdata *qslp;
02112 ILLmatrix *A;
02113 int ncols;
02114 char buf[ILL_namebufsize];
02115 int pind, hit;
02116 EGlpNum_t l, u;
02117
02118 EGlpNumInitVar (l);
02119 EGlpNumInitVar (u);
02120
02121 if (!lp)
02122 {
02123 fprintf (stderr, "ILLlib_addcol called without an lp\n");
02124 rval = 1;
02125 ILL_CLEANUP;
02126 }
02127
02128 qslp = lp->O;
02129 A = &qslp->A;
02130 ncols = qslp->ncols;
02131
02132 if (qslp->rA)
02133 {
02134 ILLlp_rows_clear (qslp->rA);
02135 ILL_IFFREE (qslp->rA, ILLlp_rows);
02136 }
02137
02138 if (qslp->sinfo)
02139 {
02140 ILLlp_sinfo_free (qslp->sinfo);
02141 ILL_IFFREE (qslp->sinfo, ILLlp_sinfo);
02142 }
02143
02144
02145
02146
02147 if (qslp->colsize < ncols + 1)
02148 {
02149 EGlpNumReallocArray (&(qslp->lower), qslp->colsize + EXTRA_COLS);
02150 EGlpNumReallocArray (&(qslp->upper), qslp->colsize + EXTRA_COLS);
02151 EGlpNumReallocArray (&(qslp->obj), qslp->colsize + EXTRA_COLS);
02152 qslp->colsize += EXTRA_COLS;
02153 }
02154
02155 EGlpNumCopy (qslp->obj[ncols], obj);
02156 EGlpNumCopy (qslp->lower[ncols], lower);
02157 EGlpNumCopy (qslp->upper[ncols], upper);
02158
02159
02160
02161 if (qslp->structsize < qslp->nstruct + 1)
02162 {
02163 qslp->structmap = EGrealloc (qslp->structmap,
02164 sizeof (int) * (qslp->structsize +
02165 EXTRA_COLS));
02166
02167
02168
02169
02170
02171 qslp->colnames = EGrealloc (qslp->colnames,
02172 sizeof (char *) * (qslp->structsize +
02173 EXTRA_COLS));
02174
02175
02176
02177
02178
02179 if (qslp->intmarker)
02180 {
02181 qslp->intmarker = EGrealloc (qslp->intmarker,
02182 sizeof (char) * (qslp->structsize +
02183 EXTRA_COLS));
02184
02185
02186
02187
02188 }
02189 qslp->structsize += EXTRA_COLS;
02190 }
02191
02192 qslp->structmap[qslp->nstruct] = ncols;
02193 if (qslp->intmarker)
02194 {
02195
02196 qslp->intmarker[qslp->nstruct] = (char) 0;
02197 }
02198
02199 ILL_FAILtrue (qslp->colnames == NULL, "must always be non NULL");
02200 ILLlib_findName (qslp, 0 , name, qslp->nstruct, buf);
02201 ILLsymboltab_register (&qslp->coltab, buf, qslp->nstruct, &pind, &hit);
02202 ILL_FAILfalse ((pind == qslp->nstruct) && (hit == 0), "must be new");
02203 ILL_UTIL_STR (qslp->colnames[qslp->nstruct], buf);
02204
02205
02206
02207
02208 rval = matrix_addcol (A, cnt, ind, val);
02209 CHECKRVALG (rval, CLEANUP);
02210
02211
02212 if (B)
02213 {
02214 B->cstat = EGrealloc (B->cstat, sizeof (char) * (qslp->nstruct + 1));
02215
02216
02217
02218 if (EGlpNumIsEqual (lower, ILL_MINDOUBLE, oneLpNum) &&
02219 EGlpNumIsEqual (upper, ILL_MAXDOUBLE, oneLpNum))
02220 {
02221 B->cstat[qslp->nstruct] = QS_COL_BSTAT_FREE;
02222 }
02223 else if (EGlpNumIsEqual (upper, ILL_MAXDOUBLE, oneLpNum))
02224 {
02225 B->cstat[qslp->nstruct] = QS_COL_BSTAT_LOWER;
02226 }
02227
02228 else if (EGlpNumIsEqual (lower, ILL_MAXDOUBLE, oneLpNum))
02229 {
02230 B->cstat[qslp->nstruct] = QS_COL_BSTAT_UPPER;
02231 }
02232 else
02233 {
02234
02235
02236 EGlpNumCopyAbs (l, lower);
02237 EGlpNumCopyAbs (u, upper);
02238 if (EGlpNumIsLess (l, u))
02239 {
02240 B->cstat[qslp->nstruct] = QS_COL_BSTAT_LOWER;
02241 }
02242 else
02243 {
02244 B->cstat[qslp->nstruct] = QS_COL_BSTAT_UPPER;
02245 }
02246 }
02247
02248
02249 EGlpNumFreeArray (B->colnorms);
02250 }
02251
02252 if (factorok == 0)
02253 {
02254 #if 0
02255 lp->basisid = -1;
02256 #endif
02257 }
02258 else
02259 {
02260 if (!lp->nbaz || !lp->vindex || !lp->vstat)
02261 {
02262 fprintf (stderr, "ERROR: factorok set without a current basis\n");
02263 rval = 1;
02264 ILL_CLEANUP;
02265 }
02266
02267 lp->nbaz = EGrealloc (lp->nbaz, sizeof (int) * (qslp->nstruct + 1));
02268
02269
02270
02271
02272 lp->vindex = EGrealloc (lp->vindex, sizeof (int) * (qslp->ncols + 1));
02273
02274
02275
02276
02277 lp->vstat = EGrealloc (lp->vstat, sizeof (int) * (qslp->ncols + 1));
02278
02279
02280
02281
02282 lp->nbaz[qslp->nstruct] = qslp->ncols;
02283 lp->vindex[qslp->ncols] = qslp->nstruct;
02284
02285 if (EGlpNumIsEqual (lower, ILL_MINDOUBLE, oneLpNum) &&
02286 EGlpNumIsEqual (upper, ILL_MAXDOUBLE, oneLpNum))
02287 {
02288 lp->vstat[qslp->ncols] = STAT_ZERO;
02289 }
02290 else if (EGlpNumIsEqual (upper, ILL_MAXDOUBLE, oneLpNum))
02291 {
02292 lp->vstat[qslp->ncols] = STAT_LOWER;
02293 }
02294
02295 else if (EGlpNumIsEqual (lower, ILL_MAXDOUBLE, oneLpNum))
02296 {
02297 lp->vstat[qslp->ncols] = STAT_UPPER;
02298 }
02299 else
02300 {
02301
02302
02303 EGlpNumCopyAbs (l, lower);
02304 EGlpNumCopyAbs (u, upper);
02305 if (EGlpNumIsLess (l, u))
02306 {
02307 lp->vstat[qslp->ncols] = STAT_LOWER;
02308 }
02309 else
02310 {
02311 lp->vstat[qslp->ncols] = STAT_UPPER;
02312 }
02313 }
02314 }
02315
02316
02317 qslp->ncols++;
02318 qslp->nstruct++;
02319 (qslp->nzcount) += cnt;
02320
02321 if (B)
02322 {
02323 B->nstruct++;
02324 }
02325
02326 CLEANUP:
02327 EGlpNumClearVar (l);
02328 EGlpNumClearVar (u);
02329 EG_RETURN (rval);
02330 }
02331
02332 static int matrix_addrow (
02333 ILLmatrix * A,
02334 int rowcnt,
02335 int *rowind,
02336 const EGlpNum_t * rowval)
02337 {
02338 int rval = 0;
02339 int i, j, k, ind, memo, stop, delta = 0;
02340
02341
02342
02343
02344 for (i = 0; i < rowcnt; i++)
02345 {
02346 if (rowind[i] >= A->matcols || rowind[i] < 0)
02347 {
02348 fprintf (stderr, "illegal col index in matrix_addrow\n");
02349 rval = 1;
02350 ILL_CLEANUP;
02351 }
02352 }
02353
02354 for (i = 0; i < rowcnt; i++)
02355 {
02356 j = rowind[i];
02357 if (A->matcnt[j] > 0 &&
02358 (A->matbeg[j] + A->matcnt[j] + 1 > A->matsize ||
02359 A->matind[A->matbeg[j] + A->matcnt[j]] != -1))
02360 {
02361 delta += (A->matcnt[j] + 2);
02362
02363 }
02364 }
02365
02366 if (delta < A->matfree)
02367 {
02368 for (i = 0; i < rowcnt; i++)
02369 {
02370 j = rowind[i];
02371 if (A->matcnt[j] == 0)
02372 {
02373 A->matind[A->matbeg[j]] = A->matrows;
02374 EGlpNumCopy (A->matval[A->matbeg[j]], rowval[i]);
02375 A->matcnt[j] = 1;
02376 }
02377 else if (A->matind[A->matbeg[j] + A->matcnt[j]] == -1)
02378 {
02379
02380
02381 A->matind[A->matbeg[j] + A->matcnt[j]] = A->matrows;
02382 EGlpNumCopy (A->matval[A->matbeg[j] + A->matcnt[j]], rowval[i]);
02383 if ((A->matbeg[j] + A->matcnt[j]) == (A->matsize - A->matfree))
02384 {
02385 A->matfree--;
02386 }
02387 (A->matcnt[j])++;
02388 }
02389 else
02390 {
02391 ind = A->matsize - A->matfree + 1;
02392 memo = ind;
02393 stop = A->matbeg[j] + A->matcnt[j];
02394 for (k = A->matbeg[j]; k < stop; k++)
02395 {
02396 if (ind >= A->matsize)
02397 {
02398 printf ("WHAT: %d, %d\n", A->matsize, ind);
02399 fflush (stdout);
02400 exit (1);
02401 }
02402 A->matind[ind] = A->matind[k];
02403 EGlpNumCopy (A->matval[ind], A->matval[k]);
02404 A->matind[k] = -1;
02405 ind++;
02406 }
02407 A->matind[ind] = A->matrows;
02408 EGlpNumCopy (A->matval[ind], rowval[i]);
02409 A->matbeg[j] = memo;
02410 (A->matcnt[j])++;
02411 (A->matfree) -= (A->matcnt[j] + 1);
02412 }
02413 }
02414 }
02415 else
02416 {
02417 rval = matrix_addrow_end (A, A->matrows, rowcnt, rowind, rowval);
02418 CHECKRVALG (rval, CLEANUP);
02419 }
02420 A->matrows++;
02421
02422 CLEANUP:
02423
02424 EG_RETURN (rval);
02425 }
02426
02427 static int matrix_addrow_end (
02428 ILLmatrix * A,
02429 int row,
02430 int rowcnt,
02431 int *rowind,
02432 const EGlpNum_t * rowval)
02433 {
02434 int rval = 0;
02435 int i, j, k, start, stop, total;
02436 int *newbeg = 0;
02437 int *newind = 0;
02438 EGlpNum_t *newval = 0;
02439 int ncols = A->matcols;
02440
02441 if (A->matcolsize > 0)
02442 {
02443 ILL_SAFE_MALLOC (newbeg, A->matcolsize, int);
02444 }
02445 ILL_SAFE_MALLOC (newind, A->matsize + rowcnt + EXTRA_MAT, int);
02446
02447 newval = EGlpNumAllocArray (A->matsize + rowcnt + EXTRA_MAT);
02448
02449 A->matsize += (rowcnt + EXTRA_MAT);
02450
02451 for (i = 0; i < rowcnt; i++)
02452 {
02453 A->matcnt[rowind[i]]++;
02454 }
02455 for (total = 0, j = 0; j < ncols; j++)
02456 {
02457 newbeg[j] = total;
02458 if (A->matcnt[j] > 0)
02459 total += A->matcnt[j];
02460 else
02461 total += 1;
02462 }
02463 for (i = 0; i < rowcnt; i++)
02464 {
02465 A->matcnt[rowind[i]]--;
02466 }
02467 for (j = total; j < A->matsize; j++)
02468 {
02469 newind[j] = -1;
02470 }
02471 A->matfree = A->matsize - total;
02472
02473 for (j = 0; j < ncols; j++)
02474 {
02475 if (A->matcnt[j] > 0)
02476 {
02477 stop = A->matbeg[j] + A->matcnt[j];
02478 start = newbeg[j];
02479 for (k = A->matbeg[j]; k < stop; k++)
02480 {
02481 newind[start] = A->matind[k];
02482 EGlpNumCopy (newval[start], A->matval[k]);
02483 start++;
02484 }
02485 }
02486 else
02487 {
02488 newind[newbeg[j]] = 1;
02489 }
02490 }
02491 for (i = 0; i < rowcnt; i++)
02492 {
02493 j = rowind[i];
02494 newind[newbeg[j] + A->matcnt[j]] = row;
02495 EGlpNumCopy (newval[newbeg[j] + A->matcnt[j]], rowval[i]);
02496 (A->matcnt[j])++;
02497 }
02498
02499 ILL_IFFREE (A->matbeg, int);
02500 ILL_IFFREE (A->matind, int);
02501
02502 EGlpNumFreeArray (A->matval);
02503
02504 A->matbeg = newbeg;
02505 A->matind = newind;
02506 A->matval = newval;
02507
02508 CLEANUP:
02509
02510 if (rval)
02511 {
02512 ILL_IFFREE (newbeg, int);
02513 ILL_IFFREE (newind, int);
02514
02515 EGlpNumFreeArray (newval);
02516 }
02517
02518 EG_RETURN (rval);
02519 }
02520
02521 static int matrix_addcoef (
02522 lpinfo * lp,
02523 ILLmatrix * A,
02524 int row,
02525 int col,
02526 EGlpNum_t val)
02527 {
02528 int i, k, delta, ind, stop, memo;
02529 int tind[1];
02530 EGlpNum_t tval[1];
02531 int rval = 0;
02532
02533 EGlpNumInitVar (tval[0]);
02534 EGlpNumCopy (tval[0], val);
02535
02536 if (row >= A->matrows || row < 0)
02537 {
02538 fprintf (stderr, "illegal row index in matrix_addcoef\n");
02539 rval = 1;
02540 ILL_CLEANUP;
02541 }
02542
02543 if (col >= A->matcols || col < 0)
02544 {
02545 fprintf (stderr, "illegal col index in matrix_addcoef\n");
02546 rval = 1;
02547 ILL_CLEANUP;
02548 }
02549
02550 for (i = A->matbeg[col]; i < A->matbeg[col] + A->matcnt[col]; i++)
02551 {
02552 if (A->matind[i] == row)
02553 {
02554 EGlpNumCopy (A->matval[i], val);
02555 ILL_CLEANUP;
02556 }
02557 }
02558
02559
02560
02561 lp->O->nzcount++;
02562 delta = A->matcnt[col] + 2;
02563
02564 if (A->matcnt[col] == 0)
02565 {
02566
02567 A->matind[A->matbeg[col]] = row;
02568 EGlpNumCopy (A->matval[A->matbeg[col]], val);
02569 A->matcnt[col] = 1;
02570 }
02571 else if (A->matbeg[col] + A->matcnt[col] < A->matsize &&
02572 A->matind[A->matbeg[col] + A->matcnt[col]] == -1)
02573 {
02574
02575 A->matind[A->matbeg[col] + A->matcnt[col]] = row;
02576 EGlpNumCopy (A->matval[A->matbeg[col] + A->matcnt[col]], val);
02577 if ((A->matbeg[col] + A->matcnt[col]) == (A->matsize - A->matfree))
02578 {
02579 A->matfree--;
02580 }
02581 (A->matcnt[col])++;
02582 }
02583 else if (A->matfree > delta)
02584 {
02585
02586 ind = A->matsize - A->matfree + 1;
02587 memo = ind;
02588 stop = A->matbeg[col] + A->matcnt[col];
02589 for (k = A->matbeg[col]; k < stop; k++)
02590 {
02591 A->matind[ind] = A->matind[k];
02592 EGlpNumCopy (A->matval[ind], A->matval[k]);
02593 A->matind[k] = -1;
02594 ind++;
02595 }
02596 A->matind[ind] = row;
02597 EGlpNumCopy (A->matval[ind], val);
02598
02599 A->matbeg[col] = memo;
02600 (A->matcnt[col])++;
02601 (A->matfree) -= (A->matcnt[col] + 1);
02602 }
02603 else
02604 {
02605
02606
02607 tind[0] = col;
02608
02609 rval = matrix_addrow_end (A, row, 1, tind, tval);
02610 CHECKRVALG (rval, CLEANUP);
02611 }
02612
02613 CLEANUP:
02614
02615 EGlpNumClearVar (tval[0]);
02616 EG_RETURN (rval);
02617 }
02618
02619 static int matrix_addcol (
02620 ILLmatrix * A,
02621 int colcnt,
02622 int *colind,
02623 EGlpNum_t * colval)
02624 {
02625 int rval = 0;
02626 int i, ind;
02627
02628 for (i = 0; i < colcnt; i++)
02629 {
02630 if (colind[i] >= A->matrows || colind[i] < 0)
02631 {
02632 fprintf (stderr, "illegal row index in matrix_addcol\n");
02633 rval = 1;
02634 ILL_CLEANUP;
02635 }
02636 }
02637
02638 if (A->matcolsize < A->matcols + 1)
02639 {
02640 A->matbeg =
02641 EGrealloc (A->matbeg, sizeof (int) * (A->matcolsize + EXTRA_COLS));
02642
02643
02644
02645
02646 A->matcnt =
02647 EGrealloc (A->matcnt, sizeof (int) * (A->matcolsize + EXTRA_COLS));
02648
02649
02650
02651
02652 (A->matcolsize) += EXTRA_COLS;
02653 }
02654
02655 if (A->matfree < colcnt + 1)
02656 {
02657 A->matind = EGrealloc (A->matind,
02658 sizeof (int) * (A->matsize + colcnt + EXTRA_MAT +
02659 1));
02660
02661
02662
02663
02664 EGlpNumReallocArray (&(A->matval), A->matsize + colcnt + EXTRA_MAT + 1);
02665
02666 for (i = 0; i < colcnt + EXTRA_MAT + 1; i++)
02667 {
02668 A->matind[A->matsize + i] = -1;
02669 }
02670 A->matsize += (colcnt + EXTRA_MAT + 1);
02671 A->matfree += (colcnt + EXTRA_MAT + 1);
02672 }
02673
02674 ind = A->matsize - A->matfree;
02675 A->matbeg[A->matcols] = ind;
02676 A->matcnt[A->matcols] = colcnt;
02677 if (colcnt == 0)
02678 {
02679 A->matind[ind] = 1;
02680
02681 A->matfree -= 1;
02682 }
02683 else
02684 {
02685 for (i = 0; i < colcnt; i++)
02686 {
02687 EGlpNumCopy (A->matval[ind], colval[i]);
02688 A->matind[ind] = colind[i];
02689 ind++;
02690 }
02691 A->matfree -= colcnt;
02692 }
02693 A->matcols++;
02694
02695 CLEANUP:
02696
02697 EG_RETURN (rval);
02698 }
02699
02700 int ILLlib_getrows (
02701 lpinfo * lp,
02702 int num,
02703 int *rowlist,
02704 int **rowcnt,
02705 int **rowbeg,
02706 int **rowind,
02707 EGlpNum_t ** rowval,
02708 EGlpNum_t ** rhs,
02709 char **sense,
02710 EGlpNum_t ** range,
02711 char ***names)
02712 {
02713 int rval = 0;
02714 int *allbeg = 0;
02715 int *allcnt = 0;
02716 int *allind = 0;
02717 EGlpNum_t *allval = 0;
02718 int i, row, k, start, stop, len, tcnt, cnt = 0;
02719 ILLlpdata *qslp;
02720 ILLlp_rows lprows;
02721
02722 if (rowcnt) *rowcnt = 0;
02723 if (rowbeg) *rowbeg = 0;
02724 if (rowind) *rowind = 0;
02725 if (rowval) *rowval = 0;
02726 if (rhs) *rhs = 0;
02727 if (range) *range = 0;
02728 if (sense) *sense = 0;
02729 if (names) *names = 0;
02730
02731 if (!lp)
02732 {
02733 fprintf (stderr, "ILLlib_getrows called without an LP\n");
02734 rval = 1;
02735 ILL_CLEANUP;
02736 }
02737
02738 if (!num)
02739 ILL_CLEANUP;
02740
02741 qslp = lp->O;
02742
02743 rval = ILLlp_rows_init (&lprows, qslp, 0);
02744 CHECKRVALG (rval, CLEANUP);
02745 allbeg = lprows.rowbeg;
02746 allcnt = lprows.rowcnt;
02747 allind = lprows.rowind;
02748 allval = lprows.rowval;
02749
02750 for (i = 0; i < num; i++)
02751 {
02752 cnt += allcnt[rowlist[i]];
02753 }
02754
02755 if (rowcnt)
02756 {
02757 ILL_SAFE_MALLOC (*rowcnt, num, int);
02758
02759 for (i = 0; i < num; i++)
02760 {
02761 (*rowcnt)[i] = allcnt[rowlist[i]];
02762 }
02763 }
02764
02765 if (rowbeg)
02766 {
02767 ILL_SAFE_MALLOC (*rowbeg, num, int);
02768
02769 tcnt = 0;
02770 for (i = 0; i < num; i++)
02771 {
02772 (*rowbeg)[i] = tcnt;
02773 tcnt += allcnt[rowlist[i]];
02774 }
02775 }
02776
02777 if (cnt && rowind)
02778 {
02779 ILL_SAFE_MALLOC (*rowind, cnt, int);
02780
02781 tcnt = 0;
02782 for (i = 0; i < num; i++)
02783 {
02784 row = rowlist[i];
02785 start = allbeg[row];
02786 stop = start + allcnt[row];
02787 for (k = start; k < stop; k++)
02788 {
02789 (*rowind)[tcnt++] = allind[k];
02790 }
02791 }
02792 }
02793
02794 if (cnt && rowval)
02795 {
02796 *rowval = EGlpNumAllocArray (cnt);
02797 tcnt = 0;
02798 for (i = 0; i < num; i++)
02799 {
02800 row = rowlist[i];
02801 start = allbeg[row];
02802 stop = start + allcnt[row];
02803 for (k = start; k < stop; k++)
02804 {
02805 EGlpNumCopy ((*rowval)[tcnt++], allval[k]);
02806 }
02807 }
02808 }
02809
02810 if (rhs)
02811 {
02812 *rhs = EGlpNumAllocArray (num);
02813 for (i = 0; i < num; i++)
02814 {
02815 EGlpNumCopy ((*rhs)[i], qslp->rhs[rowlist[i]]);
02816 }
02817 }
02818
02819 if (range)
02820 {
02821 *range = EGlpNumAllocArray(num);
02822 if(qslp->rangeval)
02823 {
02824 for(i = 0; i < num ; i++)
02825 {
02826 EGlpNumCopy((*range)[i], qslp->rangeval[rowlist[i]]);
02827 }
02828 }
02829 else
02830 {
02831 for(i = 0; i < num ; i++)
02832 {
02833 EGlpNumZero((*range)[i]);
02834 }
02835 }
02836 }
02837
02838 if (sense)
02839 {
02840 ILL_SAFE_MALLOC (*sense, num, char);
02841
02842 for (i = 0; i < num; i++)
02843 {
02844 (*sense)[i] = qslp->sense[rowlist[i]];
02845 }
02846 }
02847
02848 if (names)
02849 {
02850 if (qslp->rownames == 0)
02851 {
02852 fprintf (stderr, "LP does not have row names\n");
02853 rval = 1;
02854 ILL_CLEANUP;
02855 }
02856 ILL_SAFE_MALLOC (*names, num, char *);
02857
02858 for (i = 0; i < num; i++)
02859 {
02860 (*names)[i] = 0;
02861 }
02862 for (i = 0; i < num; i++)
02863 {
02864 len = strlen (qslp->rownames[rowlist[i]]) + 1;
02865 ILL_SAFE_MALLOC ((*names)[i], len, char);
02866
02867 strcpy ((*names)[i], qslp->rownames[rowlist[i]]);
02868 }
02869 }
02870
02871 CLEANUP:
02872
02873 ILL_IFFREE (allbeg, int);
02874 ILL_IFFREE (allcnt, int);
02875 ILL_IFFREE (allind, int);
02876
02877 EGlpNumFreeArray (allval);
02878
02879 if (rval)
02880 {
02881 if (rowcnt)
02882 ILL_IFFREE (*rowcnt, int);
02883
02884 if (rowbeg)
02885 ILL_IFFREE (*rowbeg, int);
02886
02887 if (rowind)
02888 ILL_IFFREE (*rowind, int);
02889
02890 if (rowval)
02891 EGlpNumFreeArray (*rowval);
02892 if (rhs)
02893 EGlpNumFreeArray (*rhs);
02894 if (sense)
02895 ILL_IFFREE (*sense, char);
02896
02897 if (names && (*names))
02898 {
02899 for (i = 0; i < num; i++)
02900 {
02901 ILL_IFFREE ((*names)[i], char);
02902 }
02903 ILL_IFFREE (*names, char *);
02904 }
02905 }
02906
02907 EG_RETURN (rval);
02908 }
02909
02910 int ILLlib_getcols (
02911 lpinfo * lp,
02912 int num,
02913 int *collist,
02914 int **colcnt,
02915 int **colbeg,
02916 int **colind,
02917 EGlpNum_t ** colval,
02918 EGlpNum_t ** obj,
02919 EGlpNum_t ** lower,
02920 EGlpNum_t ** upper,
02921 char ***names)
02922 {
02923 int rval = 0;
02924 int i, col, k, start, stop, len, tcnt, cnt = 0;
02925 ILLlpdata *qslp;
02926 ILLmatrix *A;
02927 int *tlist = 0;
02928
02929 if (colcnt)
02930 *colcnt = 0;
02931 if (colbeg)
02932 *colbeg = 0;
02933 if (colind)
02934 *colind = 0;
02935 if (colval)
02936 *colval = 0;
02937 if (lower)
02938 *lower = 0;
02939 if (upper)
02940 *upper = 0;
02941 if (obj)
02942 *obj = 0;
02943 if (names)
02944 *names = 0;
02945
02946 if (!lp)
02947 {
02948 fprintf (stderr, "ILLlib_getcols called without an LP\n");
02949 rval = 1;
02950 ILL_CLEANUP;
02951 }
02952
02953 if (!num)
02954 ILL_CLEANUP;
02955
02956 qslp = lp->O;
02957 A = &(qslp->A);
02958
02959 ILL_SAFE_MALLOC (tlist, num, int);
02960
02961 for (i = 0; i < num; i++)
02962 {
02963 tlist[i] = qslp->structmap[collist[i]];
02964 }
02965
02966 for (i = 0; i < num; i++)
02967 {
02968 cnt += A->matcnt[tlist[i]];
02969 }
02970
02971 if (colcnt)
02972 {
02973 ILL_SAFE_MALLOC (*colcnt, num, int);
02974
02975 for (i = 0; i < num; i++)
02976 {
02977 (*colcnt)[i] = A->matcnt[tlist[i]];
02978 }
02979 }
02980
02981 if (colbeg)
02982 {
02983 ILL_SAFE_MALLOC (*colbeg, num, int);
02984
02985 tcnt = 0;
02986 for (i = 0; i < num; i++)
02987 {
02988 (*colbeg)[i] = tcnt;
02989 tcnt += A->matcnt[tlist[i]];
02990 }
02991 }
02992
02993 if (cnt && colind)
02994 {
02995 ILL_SAFE_MALLOC (*colind, cnt, int);
02996
02997 tcnt = 0;
02998 for (i = 0; i < num; i++)
02999 {
03000 col = tlist[i];
03001 start = A->matbeg[col];
03002 stop = start + A->matcnt[col];
03003 for (k = start; k < stop; k++)
03004 {
03005 (*colind)[tcnt++] = A->matind[k];
03006 }
03007 }
03008 }
03009
03010 if (cnt && colval)
03011 {
03012 *colval = EGlpNumAllocArray (cnt);
03013 tcnt = 0;
03014 for (i = 0; i < num; i++)
03015 {
03016 col = tlist[i];
03017 start = A->matbeg[col];
03018 stop = start + A->matcnt[col];
03019 for (k = start; k < stop; k++)
03020 {
03021 EGlpNumCopy ((*colval)[tcnt++], A->matval[k]);
03022 }
03023 }
03024 }
03025
03026 if (obj)
03027 {
03028 *obj = EGlpNumAllocArray (num);
03029 for (i = 0; i < num; i++)
03030 {
03031 EGlpNumCopy ((*obj)[i], qslp->obj[tlist[i]]);
03032 }
03033 }
03034
03035 if (lower)
03036 {
03037 *lower = EGlpNumAllocArray (num);
03038 for (i = 0; i < num; i++)
03039 {
03040 EGlpNumCopy ((*lower)[i], qslp->lower[tlist[i]]);
03041 }
03042 }
03043
03044 if (upper)
03045 {
03046 *upper = EGlpNumAllocArray (num);
03047 for (i = 0; i < num; i++)
03048 {
03049 EGlpNumCopy ((*upper)[i], qslp->upper[tlist[i]]);
03050 }
03051 }
03052
03053 if (names)
03054 {
03055 if (qslp->colnames == 0)
03056 {
03057 fprintf (stderr, "LP does not have col names\n");
03058 rval = 1;
03059 ILL_CLEANUP;
03060 }
03061 ILL_SAFE_MALLOC (*names, num, char *);
03062
03063 for (i = 0; i < num; i++)
03064 {
03065 (*names)[i] = 0;
03066 }
03067 for (i = 0; i < num; i++)
03068 {
03069 len = strlen (qslp->colnames[collist[i]]) + 1;
03070 ILL_SAFE_MALLOC ((*names)[i], len, char);
03071
03072 strcpy ((*names)[i], qslp->colnames[collist[i]]);
03073 }
03074 }
03075
03076 CLEANUP:
03077
03078 if (rval)
03079 {
03080 if (colcnt)
03081 ILL_IFFREE (*colcnt, int);
03082
03083 if (colbeg)
03084 ILL_IFFREE (*colbeg, int);
03085
03086 if (colind)
03087 ILL_IFFREE (*colind, int);
03088
03089 if (colval)
03090 EGlpNumFreeArray (*colval);
03091 if (obj)
03092 EGlpNumFreeArray (*obj);
03093 if (lower)
03094 EGlpNumFreeArray (*lower);
03095 if (upper)
03096 EGlpNumFreeArray (*upper);
03097 if (names && (*names))
03098 {
03099 for (i = 0; i < num; i++)
03100 {
03101 ILL_IFFREE ((*names)[i], char);
03102 }
03103 ILL_IFFREE (*names, char *);
03104 }
03105 }
03106 ILL_IFFREE (tlist, int);
03107
03108 EG_RETURN (rval);
03109 }
03110
03111 int ILLlib_getobj_list (
03112 lpinfo *lp,
03113 int num,
03114 int* collist,
03115 EGlpNum_t* obj)
03116 {
03117 const int*const structmap = lp->O->structmap;
03118 ILLlpdata *qslp;
03119 int nstruct, j, col;
03120 int rval = 0;
03121
03122 if (!lp)
03123 {
03124 fprintf (stderr, "ILLlib_getobj_list called without an LP\n");
03125 rval = 1;
03126 ILL_CLEANUP;
03127 }
03128
03129 qslp = lp->O;
03130 nstruct = qslp->nstruct;
03131
03132 for (j = 0; j < num; j++)
03133 {
03134 col = collist[j];
03135 if(col<0 || col >= nstruct)
03136 {
03137 fprintf(stderr, "ILLlib_getobj_list collist[%d] = %d outside"
03138 " valid range\n", j, col);
03139 rval = 1;
03140 ILL_CLEANUP;
03141 }
03142 EGlpNumCopy(obj[j],qslp->obj[structmap[col]]);
03143 }
03144
03145 CLEANUP:
03146
03147 EG_RETURN (rval);
03148 }
03149
03150
03151 int ILLlib_getobj (
03152 lpinfo * lp,
03153 EGlpNum_t * obj)
03154 {
03155 const int*const structmap = lp->O->structmap;
03156 ILLlpdata *qslp;
03157 int nstruct, j;
03158 int rval = 0;
03159
03160 if (!lp)
03161 {
03162 fprintf (stderr, "ILLlib_getobj called without an LP\n");
03163 rval = 1;
03164 ILL_CLEANUP;
03165 }
03166
03167 qslp = lp->O;
03168 nstruct = qslp->nstruct;
03169
03170 for (j = 0; j < nstruct; j++)
03171 {
03172 EGlpNumCopy (obj[j], qslp->obj[structmap[j]]);
03173 }
03174
03175 CLEANUP:
03176
03177 EG_RETURN (rval);
03178 }
03179
03180 int ILLlib_chgobj (
03181 lpinfo * lp,
03182 int indx,
03183 EGlpNum_t coef)
03184 {
03185 int rval = 0;
03186 int col;
03187
03188 if (!lp)
03189 {
03190 fprintf (stderr, "ILLlib_chgobj called without an lp\n");
03191 rval = 1;
03192 ILL_CLEANUP;
03193 }
03194
03195 if (indx < 0 || indx >= lp->O->nstruct)
03196 {
03197 fprintf (stderr, "ILLlib_chgrhs called with bad indx: %d\n", indx);
03198 rval = 1;
03199 ILL_CLEANUP;
03200 }
03201
03202 if (lp->O->sinfo)
03203 {
03204 ILLlp_sinfo_free (lp->O->sinfo);
03205 ILL_IFFREE (lp->O->sinfo, ILLlp_sinfo);
03206 }
03207
03208 col = lp->O->structmap[indx];
03209 EGlpNumCopy (lp->O->obj[col], coef);
03210
03211 CLEANUP:
03212
03213 EG_RETURN (rval);
03214 }
03215
03216 int ILLlib_getrhs (
03217 lpinfo * lp,
03218 EGlpNum_t * rhs)
03219 {
03220 ILLlpdata *qslp;
03221 int nrows, i;
03222 int rval = 0;
03223
03224 if (!lp)
03225 {
03226 fprintf (stderr, "ILLlib_getrhs called without an LP\n");
03227 rval = 1;
03228 ILL_CLEANUP;
03229 }
03230
03231 qslp = lp->O;
03232 nrows = qslp->nrows;
03233
03234 for (i = 0; i < nrows; i++)
03235 {
03236 EGlpNumCopy (rhs[i], qslp->rhs[i]);
03237 }
03238
03239 CLEANUP:
03240
03241 EG_RETURN (rval);
03242 }
03243
03244 int ILLlib_chgrange (
03245 lpinfo *lp,
03246 int indx,
03247 EGlpNum_t coef)
03248 {
03249 register int i;
03250 int rval = 0;
03251 ILLlpdata *qslp;
03252
03253 if (!lp)
03254 {
03255 fprintf (stderr, "ILLlib_chgrhs called without an lp\n");
03256 rval = 1;
03257 ILL_CLEANUP;
03258 }
03259
03260 if (indx < 0 || indx >= lp->O->nrows)
03261 {
03262 fprintf (stderr, "ILLlib_chgrhs called with bad indx: %d\n", indx);
03263 rval = 1;
03264 ILL_CLEANUP;
03265 }
03266
03267 if (lp->O->sinfo)
03268 {
03269 ILLlp_sinfo_free (lp->O->sinfo);
03270 ILL_IFFREE (lp->O->sinfo, ILLlp_sinfo);
03271 }
03272
03273 qslp = lp->O;
03274 if(qslp->rangeval == 0)
03275 {
03276 qslp->rangeval = EGlpNumAllocArray(qslp->rowsize);
03277 for( i = qslp->nrows ; i-- ; )
03278 {
03279 EGlpNumZero(qslp->rangeval[i]);
03280 }
03281 }
03282
03283 if(qslp->sense[indx] != 'R')
03284 {
03285 fprintf(stderr,"setting range for non-range constraint\n");
03286 rval = 1;
03287 ILL_CLEANUP;
03288 }
03289
03290 EGlpNumCopy(qslp->rangeval[indx], coef);
03291
03292 CLEANUP:
03293
03294 EG_RETURN (rval);
03295 }
03296
03297
03298 int ILLlib_chgrhs (
03299 lpinfo * lp,
03300 int indx,
03301 EGlpNum_t coef)
03302 {
03303 int rval = 0;
03304
03305 if (!lp)
03306 {
03307 fprintf (stderr, "ILLlib_chgrhs called without an lp\n");
03308 rval = 1;
03309 ILL_CLEANUP;
03310 }
03311
03312 if (indx < 0 || indx >= lp->O->nrows)
03313 {
03314 fprintf (stderr, "ILLlib_chgrhs called with bad indx: %d\n", indx);
03315 rval = 1;
03316 ILL_CLEANUP;
03317 }
03318
03319 if (lp->O->sinfo)
03320 {
03321 ILLlp_sinfo_free (lp->O->sinfo);
03322 ILL_IFFREE (lp->O->sinfo, ILLlp_sinfo);
03323 }
03324
03325 EGlpNumCopy (lp->O->rhs[indx], coef);
03326
03327 CLEANUP:
03328
03329 EG_RETURN (rval);
03330 }
03331
03332 int ILLlib_rownames (
03333 lpinfo * lp,
03334 char **rownames)
03335 {
03336 ILLlpdata *qslp;
03337 int nrows, len, i, rcount = 0;
03338 int rval = 0;
03339
03340 if (!lp)
03341 {
03342 fprintf (stderr, "ILLlib_rownames called without an LP\n");
03343 rval = 1;
03344 ILL_CLEANUP;
03345 }
03346 if (!rownames)
03347 {
03348 fprintf (stderr, "ILLlib_rownames called with NULL rownames\n");
03349 rval = 1;
03350 ILL_CLEANUP;
03351 }
03352
03353 qslp = lp->O;
03354 nrows = qslp->nrows;
03355
03356 if (qslp->rownames == 0)
03357 {
03358 fprintf (stderr, "LP does not have rownames assigned\n");
03359 rval = 1;
03360 ILL_CLEANUP;
03361 }
03362
03363 for (i = 0; i < nrows; i++)
03364 {
03365 len = strlen (qslp->rownames[i]) + 1;
03366 ILL_SAFE_MALLOC (rownames[i], len, char);
03367
03368 strcpy (rownames[i], qslp->rownames[i]);
03369 rcount++;
03370 }
03371
03372 CLEANUP:
03373
03374 if (rval)
03375 {
03376 for (i = 0; i < rcount; i++)
03377 {
03378 ILL_IFFREE (rownames[i], char);
03379 }
03380 }
03381 EG_RETURN (rval);
03382 }
03383
03384 int ILLlib_getintflags (
03385 lpinfo * lp,
03386 int *intflags)
03387 {
03388 int j, nstruct, rval = 0;
03389 ILLlpdata *qslp;
03390
03391 if (!lp)
03392 {
03393 fprintf (stderr, "ILLlib_getintflags called without an LP\n");
03394 rval = 1;
03395 ILL_CLEANUP;
03396 }
03397
03398 qslp = lp->O;
03399 nstruct = qslp->nstruct;
03400
03401 if (qslp->intmarker == 0)
03402 {
03403 for (j = 0; j < nstruct; j++)
03404 {
03405 intflags[j] = 0;
03406 }
03407 }
03408 else
03409 {
03410 for (j = 0; j < nstruct; j++)
03411 {
03412 if (qslp->intmarker[j])
03413 {
03414 intflags[j] = 1;
03415 }
03416 else
03417 {
03418 intflags[j] = 0;
03419 }
03420 }
03421 }
03422
03423 CLEANUP:
03424
03425 EG_RETURN (rval);
03426 }
03427
03428 int ILLlib_colnames (
03429 lpinfo * lp,
03430 char **colnames)
03431 {
03432 ILLlpdata *qslp;
03433 int nstruct, len, i, ccount = 0;
03434 int rval = 0;
03435
03436 if (!lp)
03437 {
03438 fprintf (stderr, "ILLlib_colnames called without an LP\n");
03439 rval = 1;
03440 ILL_CLEANUP;
03441 }
03442 if (!colnames)
03443 {
03444 fprintf (stderr, "ILLlib_colnames called with NULL colnames\n");
03445 rval = 1;
03446 ILL_CLEANUP;
03447 }
03448
03449 qslp = lp->O;
03450 nstruct = qslp->nstruct;
03451
03452 if (qslp->colnames == 0)
03453 {
03454 fprintf (stderr, "LP does not have colnames assigned\n");
03455 rval = 1;
03456 ILL_CLEANUP;
03457 }
03458
03459 for (i = 0; i < nstruct; i++)
03460 {
03461 len = strlen (qslp->colnames[i]) + 1;
03462 ILL_SAFE_MALLOC (colnames[i], len, char);
03463
03464 strcpy (colnames[i], qslp->colnames[i]);
03465 ccount++;
03466 }
03467
03468
03469 CLEANUP:
03470
03471 if (rval)
03472 {
03473 for (i = 0; i < ccount; i++)
03474 {
03475 ILL_IFFREE (colnames[i], char);
03476 }
03477 }
03478
03479 EG_RETURN (rval);
03480 }
03481
03482 static int reset_colindex (
03483 lpinfo * lp)
03484 {
03485 int rval = 0;
03486 int test;
03487 ILLlpdata *qslp = lp->O;
03488
03489 test = ILLsymboltab_index_ok (&qslp->coltab);
03490 if (!test)
03491 {
03492 rval = ILLsymboltab_index_reset (&qslp->coltab, qslp->nstruct,
03493 qslp->colnames);
03494 CHECKRVALG (rval, CLEANUP);
03495 }
03496
03497 CLEANUP:
03498
03499 EG_RETURN (rval);
03500 }
03501
03502 static int reset_rowindex (
03503 lpinfo * lp)
03504 {
03505 int rval = 0;
03506 int test;
03507 ILLlpdata *qslp = lp->O;
03508
03509 test = ILLsymboltab_index_ok (&qslp->rowtab);
03510 if (!test)
03511 {
03512 rval = ILLsymboltab_index_reset (&qslp->rowtab, qslp->nrows,
03513 qslp->rownames);
03514 CHECKRVALG (rval, CLEANUP);
03515 }
03516
03517 CLEANUP:
03518
03519 EG_RETURN (rval);
03520 }
03521
03522 int ILLlib_colindex (
03523 lpinfo * lp,
03524 const char *name,
03525 int *colindex)
03526 {
03527 int rval = 0;
03528 ILLlpdata *qslp;
03529
03530 *colindex = -1;
03531
03532 if (!lp)
03533 {
03534 fprintf (stderr, "ILLlib_colindex called without an LP\n");
03535 rval = 1;
03536 ILL_CLEANUP;
03537 }
03538
03539 qslp = lp->O;
03540
03541 rval = reset_colindex (lp);
03542 CHECKRVALG (rval, CLEANUP);
03543
03544 rval = ILLsymboltab_getindex (&qslp->coltab, name, colindex);
03545 CHECKRVALG (rval, CLEANUP);
03546
03547 CLEANUP:
03548
03549 EG_RETURN (rval);
03550 }
03551
03552 int ILLlib_rowindex (
03553 lpinfo * lp,
03554 const char *name,
03555 int *rowindex)
03556 {
03557 int rval = 0;
03558 ILLlpdata *qslp;
03559
03560 *rowindex = -1;
03561
03562 if (!lp)
03563 {
03564 fprintf (stderr, "ILLlib_rowindex called without an LP\n");
03565 rval = 1;
03566 ILL_CLEANUP;
03567 }
03568
03569 qslp = lp->O;
03570
03571 rval = reset_rowindex (lp);
03572 CHECKRVALG (rval, CLEANUP);
03573
03574 rval = ILLsymboltab_getindex (&qslp->rowtab, name, rowindex);
03575 CHECKRVALG (rval, CLEANUP);
03576
03577 CLEANUP:
03578
03579 EG_RETURN (rval);
03580 }
03581
03582 int ILLlib_getbasis (
03583 lpinfo * lp,
03584 char *cstat,
03585 char *rstat)
03586 {
03587 int rval = 0;
03588 int i, j, nrows;
03589 ILLlpdata *qslp;
03590
03591 if (!lp)
03592 {
03593 fprintf (stderr, "ILLlib_getbasis called without an LP\n");
03594 rval = 1;
03595 ILL_CLEANUP;
03596 }
03597
03598 if (lp->basisid == -1)
03599 {
03600 fprintf (stderr, "ILLlib_getbasis called with modifed LP\n");
03601 rval = 1;
03602 ILL_CLEANUP;
03603 }
03604
03605 nrows = lp->O->nrows;
03606 qslp = lp->O;
03607
03608 for (i = 0; i < qslp->nstruct; i++)
03609 {
03610 j = qslp->structmap[i];
03611 switch (lp->vstat[j])
03612 {
03613 case STAT_BASIC:
03614 cstat[i] = QS_COL_BSTAT_BASIC;
03615 break;
03616 case STAT_LOWER:
03617 cstat[i] = QS_COL_BSTAT_LOWER;
03618 break;
03619 case STAT_UPPER:
03620 cstat[i] = QS_COL_BSTAT_UPPER;
03621 break;
03622 case STAT_ZERO:
03623 cstat[i] = QS_COL_BSTAT_FREE;
03624 break;
03625 default:
03626 fprintf (stderr, "unknown vstat in ILLlib_getbasis: %d\n", lp->vstat[j]);
03627 rval = 1;
03628 ILL_CLEANUP;
03629 }
03630 }
03631
03632 for (i = 0; i < nrows; i++)
03633 {
03634 j = qslp->rowmap[i];
03635 if (qslp->rangeval && EGlpNumIsNeqqZero (qslp->rangeval[i]))
03636 {
03637 switch (lp->vstat[j])
03638 {
03639 case STAT_BASIC:
03640 rstat[i] = QS_ROW_BSTAT_BASIC;
03641 break;
03642 case STAT_LOWER:
03643 rstat[i] = QS_ROW_BSTAT_LOWER;
03644 break;
03645 case STAT_UPPER:
03646 rstat[i] = QS_ROW_BSTAT_UPPER;
03647 break;
03648 default:
03649 fprintf (stderr, "unknown vstat in ILLlib_getbasis 2\n");
03650 rval = 1;
03651 ILL_CLEANUP;
03652 }
03653 }
03654 else
03655 {
03656 switch (lp->vstat[j])
03657 {
03658 case STAT_BASIC:
03659 rstat[i] = QS_ROW_BSTAT_BASIC;
03660 break;
03661 case STAT_UPPER:
03662 case STAT_LOWER:
03663 rstat[i] = QS_ROW_BSTAT_LOWER;
03664 break;
03665 default:
03666 fprintf (stderr, "unknown vstat in ILLlib_getbasis 3: %d, %d\n",
03667 i, lp->vstat[j]);
03668 rval = 1;
03669 ILL_CLEANUP;
03670 }
03671 }
03672 }
03673
03674 CLEANUP:
03675
03676 EG_RETURN (rval);
03677 }
03678
03679 int ILLlib_loadbasis (
03680 ILLlp_basis * B,
03681 int nstruct,
03682 int nrows,
03683 char *cstat,
03684 char *rstat)
03685 {
03686 int i;
03687 int rval = 0;
03688
03689 ILLlp_basis_init (B);
03690
03691 if (!cstat || !rstat)
03692 {
03693 rval = 1;
03694 CHECKRVALG (rval, CLEANUP);
03695 }
03696
03697 rval = ILLlp_basis_alloc (B, nstruct, nrows);
03698 CHECKRVALG (rval, CLEANUP);
03699
03700 for (i = 0; i < nstruct; i++)
03701 {
03702 B->cstat[i] = cstat[i];
03703 }
03704 for (i = 0; i < nrows; i++)
03705 {
03706 B->rstat[i] = rstat[i];
03707 }
03708
03709 CLEANUP:
03710
03711 EG_RETURN (rval);
03712 }
03713
03714 #define READ_BASIS_XL 0
03715 #define READ_BASIS_XU 1
03716 #define READ_BASIS_LL 2
03717 #define READ_BASIS_UL 3
03718
03719 int ILLlib_readbasis (
03720 lpinfo * lp,
03721 ILLlp_basis * B,
03722 const char *fname)
03723 {
03724 int rval = 0;
03725 ILLlpdata *qslp = lp->O;
03726 int nstruct = qslp->nstruct;
03727 int nrows = qslp->nrows;
03728 int i, j, end = 0, sec, havename = 0;
03729 int rowtype, row, col;
03730 char *bname = 0;
03731 EGioFile_t *file_in = 0;
03732 ILLread_mps_state state;
03733 qsline_reader *in = NULL;
03734
03735 ILLlp_basis_init (B);
03736
03737 ILL_SAFE_MALLOC (B->cstat, qslp->nstruct, char);
03738 ILL_SAFE_MALLOC (B->rstat, qslp->nrows, char);
03739
03740 B->nstruct = nstruct;
03741 B->nrows = nrows;
03742
03743 for (j = 0; j < nstruct; j++)
03744 {
03745 B->cstat[j] = QS_COL_BSTAT_LOWER;
03746 }
03747 for (i = 0; i < nrows; i++)
03748 {
03749 B->rstat[i] = QS_ROW_BSTAT_BASIC;
03750 }
03751
03752 file_in = EGioOpen (fname, "r");
03753 if (file_in == 0)
03754 {
03755 fprintf (stderr, "unable to open %s for reading\n", fname);
03756 rval = 1;
03757 ILL_CLEANUP;
03758 }
03759
03760 in = ILLline_reader_new ((qsread_line_fct) EGioGets, file_in);
03761 rval = ILLmps_state_init (&state, in, fname);
03762 CHECKRVALG (rval, CLEANUP);
03763
03764 while (ILLmps_next_line (&state) == 0)
03765 {
03766 if (ILLmps_empty_key (&state))
03767 {
03768
03769
03770
03771 if (!havename)
03772 {
03773 rval = ILLmps_error (&state, "BASIS data before NAME\n");
03774 ILL_CLEANUP;
03775 }
03776
03777 if (!strcmp (state.field, "XL"))
03778 {
03779 rowtype = READ_BASIS_XL;
03780 }
03781 else if (!strcmp (state.field, "XU"))
03782 {
03783 rowtype = READ_BASIS_XU;
03784 }
03785 else if (!strcmp (state.field, "LL"))
03786 {
03787 rowtype = READ_BASIS_LL;
03788 }
03789 else if (!strcmp (state.field, "UL"))
03790 {
03791 rowtype = READ_BASIS_UL;
03792 }
03793 else
03794 {
03795 rval = ILLmps_error (&state, "BASIS \"%s\" is invalid\n", state.field);
03796 ILL_CLEANUP;
03797 }
03798
03799 if (ILLmps_next_field (&state) == 0)
03800 {
03801
03802 rval = ILLlib_colindex (lp, (const char *) state.field, &col);
03803 CHECKRVALG (rval, CLEANUP);
03804 if (col == -1)
03805 {
03806 rval = ILLmps_error (&state, "BASIS col not in LP\n");
03807 ILL_CLEANUP;
03808 }
03809
03810 if (rowtype == READ_BASIS_XL || rowtype == READ_BASIS_XU)
03811 {
03812 if (ILLmps_next_field (&state) == 0)
03813 {
03814 rval = ILLlib_rowindex (lp, (const char *) state.field, &row);
03815 CHECKRVALG (rval, CLEANUP);
03816 if (row == -1)
03817 {
03818 rval = ILLmps_error (&state, "BASIS row not in LP\n");
03819 ILL_CLEANUP;
03820 }
03821 if (rowtype == READ_BASIS_XL)
03822 {
03823 B->cstat[col] = QS_COL_BSTAT_BASIC;
03824 B->rstat[row] = QS_ROW_BSTAT_LOWER;
03825
03826 }
03827 else
03828 {
03829 B->cstat[col] = QS_COL_BSTAT_BASIC;
03830 B->rstat[row] = QS_ROW_BSTAT_UPPER;
03831 }
03832 }
03833 else
03834 {
03835 rval = ILLmps_error (&state, "BASIS line needs row and column\n");
03836 ILL_CLEANUP;
03837 }
03838 }
03839 else
03840 {
03841 if (rowtype == READ_BASIS_LL)
03842 {
03843 B->cstat[col] = QS_COL_BSTAT_LOWER;
03844 }
03845 else
03846 {
03847 B->cstat[col] = QS_COL_BSTAT_UPPER;
03848 }
03849 }
03850 }
03851 else
03852 {
03853 rval = ILLmps_error (&state, "BASIS line has no row/column\n");
03854 ILL_CLEANUP;
03855 }
03856 }
03857 else
03858 {
03859
03860 if (!strcmp (state.key, ILLmps_section_name[ILL_MPS_ENDATA]))
03861 {
03862 end = 1;
03863 break;
03864 }
03865
03866 sec = ILLutil_index (ILLmps_section_name, state.key);
03867 if (sec < 0 || sec != ILL_MPS_NAME)
03868 {
03869 rval = ILLmps_error (&state, "BASIS \"%s\" is not a key\n", state.key);
03870 ILL_CLEANUP;
03871 }
03872
03873 if (havename)
03874 {
03875 rval = ILLmps_error (&state, "BASIS two name sections\n");
03876 ILL_CLEANUP;
03877 }
03878
03879 havename = 1;
03880
03881 if (ILLmps_empty_field (&state))
03882 {
03883 ILLmps_warn (&state, "BASIS blank NAME.");
03884 }
03885 else
03886 {
03887 ILL_UTIL_STR (bname, state.field);
03888 printf ("Basis Name: %s\n", bname);
03889 fflush (stdout);
03890 if (strcmp (bname, qslp->probname))
03891 {
03892 ILLmps_warn (&state, "BASIS name does not match LP.");
03893 }
03894 }
03895 }
03896 }
03897
03898 if (!end)
03899 {
03900 ILLmps_warn (&state, "Missing ENDATA in basis file.");
03901 }
03902 if (!ILLmps_next_line (&state))
03903 {
03904 ILLmps_warn (&state, "Ignoring text after ENDATA.");
03905 }
03906
03907 if (!havename)
03908 {
03909 rval = ILLmps_error (&state, "BASIS no name section\n");
03910 ILL_CLEANUP;
03911 }
03912
03913
03914
03915 for (j = 0; j < nstruct; j++)
03916 {
03917 col = lp->O->structmap[j];
03918 if (EGlpNumIsEqqual (qslp->lower[col], ILL_MINDOUBLE) &&
03919 EGlpNumIsEqqual (qslp->upper[col], ILL_MAXDOUBLE) &&
03920 B->cstat[j] == QS_COL_BSTAT_LOWER)
03921 {
03922 B->cstat[j] = QS_COL_BSTAT_FREE;
03923 }
03924 }
03925
03926 CLEANUP:
03927
03928 if (file_in)
03929 EGioClose (file_in);
03930 ILLline_reader_free (in);
03931
03932 if (rval)
03933 {
03934 ILLlp_basis_free (B);
03935 }
03936 ILL_IFFREE (bname, char);
03937
03938 EG_RETURN (rval);
03939 }
03940
03941 int ILLlib_writebasis (
03942 lpinfo * lp,
03943 ILLlp_basis * B,
03944 const char *fname)
03945 {
03946 int rval = 0;
03947 EGioFile_t *out = 0;
03948 char *cstat = 0;
03949 char *rstat = 0;
03950 ILLlpdata *qslp;
03951 int i, j, nstruct, nrows;
03952
03953
03954
03955 if (!lp)
03956 {
03957 fprintf (stderr, "ILLlib_writebasis called without an LP\n");
03958 rval = 1;
03959 ILL_CLEANUP;
03960 }
03961 if (!B && lp->basisid == -1)
03962 {
03963 fprintf (stderr, "ILLlib_writebasis called with unsolved LP\n");
03964 rval = 1;
03965 ILL_CLEANUP;
03966 }
03967
03968 qslp = lp->O;
03969 nstruct = qslp->nstruct;
03970 nrows = qslp->nrows;
03971
03972 out = EGioOpen (fname, "w");
03973 if (out == 0)
03974 {
03975 fprintf (stderr, "unable to open %s for writing\n", fname);
03976 rval = 1;
03977 ILL_CLEANUP;
03978 }
03979
03980 if (B)
03981 {
03982 cstat = B->cstat;
03983 rstat = B->rstat;
03984 }
03985 else
03986 {
03987 ILL_SAFE_MALLOC (cstat, nstruct, char);
03988 ILL_SAFE_MALLOC (rstat, nrows, char);
03989
03990 rval = ILLlib_getbasis (lp, cstat, rstat);
03991 CHECKRVALG (rval, CLEANUP);
03992 }
03993
03994 EGioPrintf (out, "NAME %s\n", qslp->probname);
03995
03996
03997
03998 i = 0;
03999 j = 0;
04000 do
04001 {
04002 while (i < nrows && rstat[i] == QS_ROW_BSTAT_BASIC)
04003 {
04004 i++;
04005 }
04006 if (i < nrows)
04007 {
04008 while (j < nstruct && cstat[j] != QS_COL_BSTAT_BASIC)
04009 {
04010 j++;
04011 }
04012 if (j == nstruct)
04013 {
04014
04015 fprintf (stderr, "No basic column to match non-basic row %d\n", i);
04016 rval = 1;
04017 goto CLEANUP;
04018 }
04019
04020 if (rstat[i] == QS_ROW_BSTAT_LOWER)
04021 {
04022 EGioPrintf (out, " XL %s %s\n", qslp->colnames[j], qslp->rownames[i]);
04023 }
04024 else
04025 {
04026 EGioPrintf (out, " XU %s %s\n", qslp->colnames[j], qslp->rownames[i]);
04027 }
04028 i++;
04029 j++;
04030 }
04031 } while (i < nrows);
04032
04033
04034
04035 for (j = 0; j < nstruct; j++)
04036 {
04037 if (cstat[j] == QS_COL_BSTAT_UPPER)
04038 {
04039 EGioPrintf (out, " UL %s\n", qslp->colnames[j]);
04040 }
04041 }
04042
04043 EGioPrintf (out, "ENDATA\n");
04044
04045 CLEANUP:
04046
04047 if (out)
04048 EGioClose (out);
04049 if (!B)
04050 {
04051 ILL_IFFREE (cstat, char);
04052 ILL_IFFREE (rstat, char);
04053 }
04054 EG_RETURN (rval);
04055 }
04056
04057 int ILLlib_getrownorms (
04058 lpinfo * lp,
04059 price_info * pinf,
04060 EGlpNum_t * rownorms)
04061 {
04062 int rval = 0;
04063 int i, j, basic = 0;
04064 ILLlpdata *qslp = lp->O;
04065 int nstruct = lp->O->nstruct;
04066 int nrows = lp->O->nrows;
04067
04068 check_pinf (pinf, &rval);
04069 if (rval)
04070 {
04071
04072
04073
04074 ILL_CLEANUP;
04075 }
04076
04077 for (i = 0; i < nstruct; i++)
04078 {
04079 j = qslp->structmap[i];
04080 if (lp->vstat[j] == STAT_BASIC)
04081 {
04082 EGlpNumCopy (rownorms[basic++], pinf->dsinfo.norms[lp->vindex[j]]);
04083 }
04084 }
04085 for (i = 0; i < nrows; i++)
04086 {
04087 j = qslp->rowmap[i];
04088 if (lp->vstat[j] == STAT_BASIC)
04089 {
04090 EGlpNumCopy (rownorms[basic++], pinf->dsinfo.norms[lp->vindex[j]]);
04091 }
04092 }
04093
04094 if (basic != nrows)
04095 {
04096 fprintf (stderr, "error in ILLlib_getrownorms\n");
04097 rval = 1;
04098 ILL_CLEANUP;
04099 }
04100
04101 CLEANUP:
04102
04103
04104
04105
04106 return rval;
04107 }
04108
04109 int ILLlib_loadrownorms (
04110 lpinfo * lp,
04111 price_info * pinf,
04112 EGlpNum_t * rownorms)
04113 {
04114 int rval = 0;
04115
04116 rval = ILLprice_load_rownorms (lp, rownorms, pinf);
04117 CHECKRVALG (rval, CLEANUP);
04118
04119 CLEANUP:
04120
04121 EG_RETURN (rval);
04122 }
04123
04124 int ILLlib_recompute_rownorms (
04125 lpinfo * lp,
04126 price_info * pinf)
04127 {
04128 int rval = 0;
04129
04130 rval = ILLprice_build_pricing_info (lp, pinf, DUAL_PHASEII);
04131 CHECKRVALG (rval, CLEANUP);
04132
04133 CLEANUP:
04134
04135 EG_RETURN (rval);
04136 }
04137
04138 int ILLlib_iter (
04139 lpinfo * lp)
04140 {
04141 int iter = 0;
04142
04143 if (lp && lp->cnts)
04144 {
04145 iter = lp->cnts->pI_iter + lp->cnts->pII_iter +
04146 lp->cnts->dI_iter + lp->cnts->dII_iter;
04147 }
04148
04149 return iter;
04150 }
04151
04152
04153 #define PRINT_TOL PFEAS_TOLER
04154
04155 int ILLlib_print_x (
04156 EGioFile_t * fd,
04157 lpinfo * lp,
04158 ILLlp_cache * C,
04159 EGlpNum_t * x,
04160 int nonZerosOnly)
04161 {
04162 int rval = 0;
04163 int j;
04164 ILLlpdata *qslp = lp->O;
04165 EGlpNum_t *dx, *myx = 0;
04166 char *strtmp;
04167
04168
04169
04170 if (!x)
04171 {
04172 myx = EGlpNumAllocArray (lp->ncols);
04173 rval = ILLlib_get_x (lp, C, myx);
04174 CHECKRVALG (rval, CLEANUP);
04175 dx = myx;
04176 }
04177 else
04178 {
04179 dx = x;
04180 }
04181
04182 EGioPrintf (fd, "Solution Values\n");
04183 for (j = 0; j < qslp->nstruct; j++)
04184 {
04185
04186 if (!nonZerosOnly || EGlpNumIsNeqZero (dx[j], PRINT_TOL))
04187 {
04188 strtmp = EGlpNumGetStr (dx[j]);
04189 ILL_FAILfalse (qslp->colnames[j] != NULL, "no NULL names PLEASE!");
04190 EGioPrintf (fd, "%s = %s\n", qslp->colnames[j], strtmp);
04191 EGioFlush (fd);
04192 EGfree (strtmp);
04193 }
04194 }
04195
04196 CLEANUP:
04197 EGlpNumFreeArray (myx);
04198 EG_RETURN (rval);
04199 }
04200
04201 int ILLlib_findName (
04202 ILLlpdata * qslp,
04203 int forRow,
04204 const char *name,
04205 int id,
04206 char buf[ILL_namebufsize])
04207 {
04208 ILLsymboltab *tab;
04209 const char *mode;
04210 const char *p1, *p2;
04211 int sind, rval = 0;
04212
04213 id++;
04214 tab = (forRow) ? &qslp->rowtab : &qslp->coltab;
04215 if (tab->tablesize == 0)
04216 ILLsymboltab_create (tab, 100);
04217 p1 = (forRow) ? "c" : "x";
04218 p2 = (forRow) ? "c_" : "x_";
04219 mode = (forRow) ? "row" : "column";
04220 if (name == 0)
04221 {
04222 ILLsymboltab_unique_name (tab, id, p1, buf);
04223
04224
04225
04226 }
04227 else
04228 {
04229 strcpy (buf, name);
04230 }
04231 if (!ILLsymboltab_lookup (tab, buf, &sind))
04232 {
04233 rval = ILLsymboltab_uname (&qslp->rowtab, buf, p1, p2);
04234 if (name != NULL)
04235 {
04236 fprintf (stderr, "Changing %s name \"%s\" to \"%s\".\n", mode, name, buf);
04237 }
04238 CHECKRVALG (rval, CLEANUP);
04239 }
04240 CLEANUP:
04241 EG_RETURN (rval);
04242 }
04243
04244 int ILLwrite_lp_file (
04245 ILLlpdata * lp,
04246 EGioFile_t * out,
04247 qserror_collector * c)
04248 {
04249 int rval = 0;
04250 qsstring_reporter rep;
04251
04252 ILLstring_reporter_copy (&rep, &lp->reporter);
04253 ILLstring_reporter_init (&lp->reporter, (qsreport_string_fct) EGioWrite, out);
04254 rval = ILLwrite_lp (lp, c);
04255 ILLstring_reporter_copy (&lp->reporter, &rep);
04256 return rval;
04257 }
04258
04259 static void check_pinf (
04260 price_info * pinf,
04261 int *it_exists)
04262 {
04263 if (!pinf || pinf->dI_price != QS_PRICE_DSTEEP ||
04264 pinf->dII_price != QS_PRICE_DSTEEP || pinf->dsinfo.norms == 0)
04265 {
04266 *it_exists = 1;
04267 }
04268 else
04269 {
04270 *it_exists = 0;
04271 }
04272 }
04273
04274 #if 0
04275 static int test_matrix (
04276 ILLmatrix * A)
04277 {
04278 int rval = 0;
04279 int i, j, k;
04280 int ncols = A->matcols;
04281 int nrows = A->matrows;
04282 int matsize = A->matsize;
04283 int *mbeg = A->matbeg;
04284 int *mcnt = A->matcnt;
04285 int *mind = A->matind;
04286 int *tempi = 0;
04287
04288
04289 if (matsize == 0)
04290 ILL_CLEANUP;
04291
04292 ILL_SAFE_MALLOC (tempi, matsize, int);
04293
04294 for (i = 0; i < matsize; i++)
04295 tempi[i] = 0;
04296
04297 for (i = 0; i < ncols; i++)
04298 {
04299 for (j = 0; j < mcnt[i]; j++)
04300 {
04301 k = mind[mbeg[i] + j];
04302 if (k < 0 || k >= nrows)
04303 {
04304 printf ("ERROR IN MATRIX: %d\n", k);
04305 printf ("ncols = %d, bad col = %d\n", ncols, i);
04306 printf ("bad cnt = %d, bad index = %d\n", mcnt[i], mbeg[i] + j);
04307 printf ("matcolsize = %d, matsize = %d\n", A->matcolsize, A->matsize);
04308 rval = 1;
04309 ILL_CLEANUP;
04310 }
04311 if (tempi[mbeg[i] + j] != 0)
04312 {
04313 printf ("ERROR: over written matrix\n");
04314 printf ("ncols = %d, bad col = %d\n", ncols, i);
04315 printf ("nrows = %d\n", nrows);
04316 printf ("bad cnt = %d, bad index = %d\n", mcnt[i], mbeg[i] + j);
04317 rval = 1;
04318 ILL_CLEANUP;
04319 }
04320 else
04321 {
04322 tempi[mbeg[i] + j] = 1;
04323 }
04324 }
04325 }
04326
04327 for (i = A->matsize - A->matfree; i < A->matsize; i++)
04328 {
04329 if (tempi[i] != 0)
04330 {
04331 printf ("ERROR: free space is being used\n");
04332 rval = 1;
04333 ILL_CLEANUP;
04334 }
04335 }
04336
04337 CLEANUP:
04338
04339 ILL_IFFREE (tempi, int);
04340
04341 EG_RETURN (rval);
04342 }
04343 #endif