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