00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 static int TRACE = 0;
00025
00026 #include <stdio.h>
00027 #include <stdlib.h>
00028 #include <math.h>
00029 #include "config.h"
00030 #include "dbl_sortrus.h"
00031 #include "dbl_iqsutil.h"
00032 #include "dbl_lpdefs.h"
00033 #include "dbl_qstruct.h"
00034 #include "dbl_qsopt.h"
00035 #include "dbl_basis.h"
00036 #include "dbl_fct.h"
00037 #include "dbl_lp.h"
00038 #include "dbl_lib.h"
00039 #ifdef USEDMALLOC
00040 #include "dmalloc.h"
00041 #endif
00042
00043
00044 #define dbl_BASIS_STATS 0
00045
00046 #define dbl_BASIS_DEBUG 0
00047
00048 void dbl_ILLbasis_init_vardata (
00049 dbl_var_data * vd)
00050 {
00051 memset (vd, 0, sizeof (dbl_var_data));
00052 dbl_EGlpNumInitVar (vd->cmax);
00053 }
00054
00055 void dbl_ILLbasis_clear_vardata (
00056 dbl_var_data * vd)
00057 {
00058 dbl_EGlpNumClearVar (vd->cmax);
00059 memset (vd, 0, sizeof (dbl_var_data));
00060 }
00061
00062 static void dbl_get_var_info (
00063 dbl_lpinfo * lp,
00064 dbl_var_data * v);
00065
00066 static int dbl_init_slack_basis (
00067 dbl_lpinfo * lp,
00068 int *vstat,
00069 int *irow,
00070 int *rrow,
00071 int *unitcol,
00072 int *icol,
00073 int *rcol),
00074 dbl_get_initial_basis1 (
00075 dbl_lpinfo * lp,
00076 int *vstat),
00077 dbl_get_initial_basis2 (
00078 dbl_lpinfo * lp,
00079 int *vstat),
00080 dbl_set_basis_indices (
00081 dbl_lpinfo * lp,
00082 int *vstat),
00083 dbl_choose_basis (
00084 int algorithm,
00085 double pinf1,
00086 double dinf1,
00087 double pinf2,
00088 double dinf2);
00089
00090 void dbl_ILLbasis_init_basisinfo (
00091 dbl_lpinfo * lp)
00092 {
00093 lp->baz = 0;
00094 lp->nbaz = 0;
00095 lp->vstat = 0;
00096 lp->vindex = 0;
00097 lp->f = 0;
00098 }
00099
00100 void dbl_ILLbasis_free_basisinfo (
00101 dbl_lpinfo * lp)
00102 {
00103 ILL_IFFREE (lp->baz, int);
00104 ILL_IFFREE (lp->nbaz, int);
00105 ILL_IFFREE (lp->vstat, int);
00106 ILL_IFFREE (lp->vindex, int);
00107
00108 if (lp->f)
00109 {
00110 dbl_ILLfactor_free_factor_work (lp->f);
00111 dbl_EGlpNumClearVar (lp->f->fzero_tol);
00112 dbl_EGlpNumClearVar (lp->f->szero_tol);
00113 dbl_EGlpNumClearVar (lp->f->partial_tol);
00114 dbl_EGlpNumClearVar (lp->f->maxelem_orig);
00115 dbl_EGlpNumClearVar (lp->f->maxelem_factor);
00116 dbl_EGlpNumClearVar (lp->f->maxelem_cur);
00117 dbl_EGlpNumClearVar (lp->f->partial_cur);
00118 ILL_IFFREE (lp->f, dbl_factor_work);
00119 }
00120 }
00121
00122 int dbl_ILLbasis_build_basisinfo (
00123 dbl_lpinfo * lp)
00124 {
00125 int rval = 0;
00126
00127 ILL_SAFE_MALLOC (lp->baz, lp->O->nrows, int);
00128 ILL_SAFE_MALLOC (lp->nbaz, lp->O->ncols, int);
00129 ILL_SAFE_MALLOC (lp->vstat, lp->O->ncols, int);
00130 ILL_SAFE_MALLOC (lp->vindex, lp->O->ncols, int);
00131
00132 lp->fbasisid = -1;
00133
00134 CLEANUP:
00135 if (rval)
00136 dbl_ILLbasis_free_basisinfo (lp);
00137 EG_RETURN (rval);
00138 }
00139
00140 int dbl_ILLbasis_load (
00141 dbl_lpinfo * lp,
00142 dbl_ILLlp_basis * B)
00143 {
00144 int rval = 0;
00145 char *cstat = B->cstat;
00146 char *rstat = B->rstat;
00147 int *structmap = lp->O->structmap;
00148 int *rowmap = lp->O->rowmap;
00149 char *sense = lp->O->sense;
00150 int i, j, ncols = lp->O->ncols, nrows = lp->O->nrows, nstruct = lp->O->nstruct;
00151 int basic = 0, nonbasic = 0;
00152
00153 dbl_ILLbasis_free_basisinfo (lp);
00154 dbl_ILLbasis_init_basisinfo (lp);
00155 rval = dbl_ILLbasis_build_basisinfo (lp);
00156 CHECKRVALG (rval, CLEANUP);
00157
00158 for (i = 0; i < nstruct; i++)
00159 {
00160 j = structmap[i];
00161 if (cstat[i] == QS_COL_BSTAT_BASIC)
00162 {
00163 lp->vstat[j] = STAT_BASIC;
00164 lp->baz[basic] = j;
00165 lp->vindex[j] = basic;
00166 basic++;
00167 }
00168 else
00169 {
00170 lp->nbaz[nonbasic] = j;
00171 lp->vindex[j] = nonbasic;
00172 nonbasic++;
00173 switch (cstat[i])
00174 {
00175 case QS_COL_BSTAT_LOWER:
00176 lp->vstat[j] = STAT_LOWER;
00177 break;
00178 case QS_COL_BSTAT_UPPER:
00179 lp->vstat[j] = STAT_UPPER;
00180 break;
00181 case QS_COL_BSTAT_FREE:
00182 lp->vstat[j] = STAT_ZERO;
00183 break;
00184 default:
00185 fprintf (stderr, "unknown col basis stat 1: %c\n", cstat[i]);
00186 rval = 1;
00187 goto CLEANUP;
00188 }
00189 }
00190 }
00191
00192 for (i = 0; i < nrows; i++)
00193 {
00194 j = rowmap[i];
00195 if (sense[i] == 'R')
00196 {
00197 if (rstat[i] == QS_ROW_BSTAT_BASIC)
00198 {
00199 lp->vstat[j] = STAT_BASIC;
00200 lp->baz[basic] = j;
00201 lp->vindex[j] = basic;
00202 basic++;
00203 }
00204 else
00205 {
00206 lp->nbaz[nonbasic] = j;
00207 lp->vindex[j] = nonbasic;
00208 nonbasic++;
00209 switch (rstat[i])
00210 {
00211 case QS_ROW_BSTAT_LOWER:
00212 lp->vstat[j] = STAT_LOWER;
00213 break;
00214 case QS_ROW_BSTAT_UPPER:
00215 lp->vstat[j] = STAT_UPPER;
00216 break;
00217 default:
00218 fprintf (stderr, "unknown range basis stat 2\n");
00219 rval = 1;
00220 goto CLEANUP;
00221 }
00222 }
00223 }
00224 else
00225 {
00226 switch (rstat[i])
00227 {
00228 case QS_ROW_BSTAT_BASIC:
00229 lp->vstat[j] = STAT_BASIC;
00230 lp->baz[basic] = j;
00231 lp->vindex[j] = basic;
00232 basic++;
00233 break;
00234 case QS_ROW_BSTAT_LOWER:
00235 lp->vstat[j] = STAT_LOWER;
00236 lp->nbaz[nonbasic] = j;
00237 lp->vindex[j] = nonbasic;
00238 nonbasic++;
00239 break;
00240 default:
00241 fprintf (stderr, "unknown row basis stat 3\n");
00242 rval = 1;
00243 goto CLEANUP;
00244 }
00245 }
00246 }
00247
00248 if (basic + nonbasic != ncols)
00249 {
00250 fprintf (stderr, "error in counts in ILLopt_load_basis\n");
00251 rval = 1;
00252 goto CLEANUP;
00253 }
00254
00255 if (lp->fbasisid != 0)
00256 lp->basisid = 0;
00257 else
00258 lp->basisid = 1;
00259
00260 CLEANUP:
00261
00262 EG_RETURN (rval);
00263 }
00264
00265 int dbl_ILLbasis_tableau_row (
00266 dbl_lpinfo * lp,
00267 int row,
00268 double * brow,
00269 double * trow,
00270 double * rhs,
00271 int strict)
00272 {
00273 int rval = 0;
00274 int i;
00275 int singular = 0;
00276 int indx;
00277 double coef;
00278 double sum;
00279 dbl_svector z, zA;
00280
00281 dbl_EGlpNumInitVar (coef);
00282 dbl_EGlpNumInitVar (sum);
00283 dbl_EGlpNumZero (sum);
00284
00285 dbl_ILLsvector_init (&z);
00286 dbl_ILLsvector_init (&zA);
00287
00288 if (lp->basisid == -1)
00289 {
00290 fprintf (stderr, "dbl_ILLbasis_tableau_row: no basis\n");
00291 rval = E_GENERAL_ERROR;
00292 ILL_CLEANUP;
00293 }
00294 if (lp->fbasisid != lp->basisid)
00295 {
00296 rval = dbl_ILLbasis_factor (lp, &singular);
00297 CHECKRVALG (rval, CLEANUP);
00298 if (singular)
00299 {
00300 MESSAGE (__QS_SB_VERB, "Singular Basis found!");
00301 rval = E_BASIS_SINGULAR;
00302 ILL_CLEANUP;
00303 }
00304 }
00305 if (brow == NULL)
00306 {
00307 fprintf (stderr, "No array for basis inverse row\n");
00308 rval = E_GENERAL_ERROR;
00309 ILL_CLEANUP;
00310 }
00311
00312 rval = dbl_ILLsvector_alloc (&z, lp->nrows);
00313 CHECKRVALG (rval, CLEANUP);
00314 dbl_ILLfct_compute_zz (lp, &z, row);
00315
00316 for (i = 0; i < lp->O->nrows; i++)
00317 dbl_EGlpNumZero (brow[i]);
00318 for (i = 0; i < z.nzcnt; i++)
00319 {
00320 indx = z.indx[i];
00321 dbl_EGlpNumCopy (coef, z.coef[i]);
00322 dbl_EGlpNumCopy (brow[indx], coef);
00323 dbl_EGlpNumAddInnProdTo (sum, coef, lp->bz[indx]);
00324 }
00325
00326 if (rhs != NULL)
00327 dbl_EGlpNumCopy (*rhs, sum);
00328 if (trow != NULL)
00329 {
00330 if (!strict)
00331 {
00332 rval = dbl_ILLsvector_alloc (&zA, lp->ncols);
00333 if (rval)
00334 ILL_CLEANUP;
00335 ILL_IFTRACE ("%s:\n", __func__);
00336 rval = dbl_ILLfct_compute_zA (lp, &z, &zA);
00337 CHECKRVALG (rval, CLEANUP);
00338
00339 for (i = 0; i < lp->ncols; i++)
00340 dbl_EGlpNumZero (trow[i]);
00341 for (i = 0; i < zA.nzcnt; i++)
00342 dbl_EGlpNumCopy (trow[lp->nbaz[zA.indx[i]]], zA.coef[i]);
00343 dbl_EGlpNumOne (trow[lp->baz[row]]);
00344 }
00345 else
00346 {
00347 dbl_ILLfct_compute_vA (lp, &z, trow);
00348 }
00349 }
00350
00351 #if dbl_BASIS_DEBUG > 0
00352 if (rhs != NULL && trow != NULL)
00353 {
00354 double *tr = NULL;
00355
00356 dbl_EGlpNumZero (sum);
00357 if (strict)
00358 tr = trow;
00359 else
00360 {
00361 tr = dbl_EGlpNumAllocArray (lp->ncols);
00362 dbl_ILLfct_compute_vA (lp, &z, tr);
00363 }
00364 for (i = 0; i < lp->nrows; i++)
00365 if (dbl_EGlpNumIsGreatZero (tr[lp->baz[i]]))
00366 dbl_EGlpNumAddTo (sum, tr[lp->baz[i]]);
00367 else
00368 dbl_EGlpNumSubTo (sum, tr[lp->baz[i]]);
00369 dbl_EGlpNumCopy (coef, dbl_oneLpNum);
00370 dbl_EGlpNumSubTo (coef, sum);
00371 if (dbl_EGlpNumIsLessZero (coef))
00372 dbl_EGlpNumSign (coef);
00373 if (dbl_EGlpNumIsLess (dbl_PIVZ_TOLER, coef))
00374 fprintf (stderr, "tableau: bas computed = %.12f\n", dbl_EGlpNumToLf (sum));
00375 if (!strict)
00376 dbl_EGlpNumFreeArray (tr);
00377 #if dbl_BASIS_DEBUG > 1
00378 dbl_EGlpNumZero (sum);
00379 for (i = 0; i < lp->ncols; i++)
00380 {
00381 if (lp->vstat[i] == STAT_BASIC)
00382 dbl_EGlpNumAddInnProdTo (sum, lp->xbz[lp->vindex[i]], trow[i]);
00383 else if (lp->vstat[i] == STAT_UPPER)
00384 dbl_EGlpNumAddInnProdTo (sum, lp->uz[i], trow[i]);
00385 else if (lp->vstat[i] == STAT_LOWER)
00386 dbl_EGlpNumAddInnProdTo (sum, lp->lz[i], trow[i]);
00387 }
00388 dbl_EGlpNumSet (coef, 1e-10);
00389 if (dbl_EGlpNumIsNeq (sum, *rhs, coef))
00390 fprintf (stderr, "tableau rhs = %.9f, computed = %.9f\n",
00391 dbl_EGlpNumToLf (*rhs), dbl_EGlpNumToLf (sum));
00392 #endif
00393 }
00394 #endif
00395
00396 CLEANUP:
00397 dbl_ILLsvector_free (&z);
00398 dbl_ILLsvector_free (&zA);
00399 dbl_EGlpNumClearVar (coef);
00400 dbl_EGlpNumClearVar (sum);
00401 return rval;
00402 }
00403
00404 static void dbl_get_var_info (
00405 dbl_lpinfo * lp,
00406 dbl_var_data * v)
00407 {
00408 int i = 0;
00409
00410 v->nartif = 0;
00411 v->nslacks = 0;
00412 v->nfree = 0;
00413 v->nbndone = 0;
00414 v->nbounded = 0;
00415 v->nfixed = 0;
00416 dbl_EGlpNumCopy (v->cmax, dbl_NINFTY);
00417
00418 for (i = 0; i < lp->ncols; i++)
00419 {
00420 switch (lp->vtype[i])
00421 {
00422 case VARTIFICIAL:
00423 v->nartif++;
00424 break;
00425 case VFREE:
00426 v->nfree++;
00427 break;
00428 case VLOWER:
00429 case VUPPER:
00430 if (lp->vclass[i] == CLASS_LOGICAL)
00431 v->nslacks++;
00432 else
00433 v->nbndone++;
00434 break;
00435
00436 case VFIXED:
00437 v->nfixed++;
00438 case VBOUNDED:
00439 if (lp->vclass[i] == CLASS_LOGICAL)
00440 v->nslacks++;
00441 else
00442 v->nbounded++;
00443 break;
00444 }
00445 dbl_EGlpNumSetToMaxAbs (v->cmax, lp->cz[i]);
00446 }
00447
00448 #if dbl_BASIS_STATS > 0
00449 printf ("cols = %d, acols = %d, total = %d, nrows = %d, nlog = %d\n",
00450 lp->ncols, lp->ncols - lp->nrows,
00451 v->nartif + v->nfree + v->nslacks + v->nbndone + v->nbounded,
00452 lp->nrows, v->nartif + v->nslacks);
00453 #endif
00454 }
00455
00456 static int dbl_init_slack_basis (
00457 dbl_lpinfo * lp,
00458 int *vstat,
00459 int *irow,
00460 int *rrow,
00461 int *unitcol,
00462 int *icol,
00463 int *rcol)
00464 {
00465 int j, r, vt;
00466 int nslacks = 0;
00467
00468 for (j = 0; j < lp->ncols; j++)
00469 {
00470 r = lp->matind[lp->matbeg[j]];
00471 vt = lp->vtype[j];
00472
00473 if ((vt == VUPPER || vt == VLOWER || vt == VBOUNDED || vt == VFIXED) &&
00474 lp->vclass[j] == CLASS_LOGICAL)
00475 {
00476
00477 vstat[j] = STAT_BASIC;
00478 irow[r] = 1;
00479 rrow[r] = 1;
00480 unitcol[r] = j;
00481 if (icol != NULL)
00482 {
00483 icol[j] = 1;
00484 rcol[j] = 1;
00485 }
00486 nslacks++;
00487 }
00488 else if (vt == VARTIFICIAL)
00489 {
00490 unitcol[r] = j;
00491 vstat[j] = STAT_UPPER;
00492 }
00493 else if (vt == VFREE)
00494 vstat[j] = STAT_ZERO;
00495 else if (vt == VFIXED || vt == VUPPER)
00496 vstat[j] = STAT_UPPER;
00497 else if (vt == VLOWER)
00498 vstat[j] = STAT_LOWER;
00499 else if (vt == VBOUNDED)
00500 {
00501 if (fabs (dbl_EGlpNumToLf (lp->lz[j])) < fabs (dbl_EGlpNumToLf (lp->uz[j])))
00502 vstat[j] = STAT_LOWER;
00503 else
00504 vstat[j] = STAT_UPPER;
00505 }
00506 }
00507 return nslacks;
00508 }
00509
00510 static int dbl_primal_col_select (
00511 dbl_lpinfo * lp,
00512 int *vstat,
00513 int *irow,
00514 int *rrow,
00515 int *unitcol,
00516 double * v,
00517 int *perm,
00518 int *porder,
00519 int nbelem,
00520 int pcols)
00521 {
00522 int i, j, k, tr, r = 0;
00523 int mcnt, mbeg;
00524 int *matbeg = lp->matbeg;
00525 int *matcnt = lp->matcnt;
00526 int *matind = lp->matind;
00527 double *matval = lp->matval;
00528 double alpha, val, maxelem;
00529
00530 dbl_EGlpNumInitVar (alpha);
00531 dbl_EGlpNumInitVar (val);
00532 dbl_EGlpNumInitVar (maxelem);
00533
00534 for (k = 0; k < pcols; k++)
00535 {
00536 j = porder[perm[k]];
00537 mcnt = matcnt[j];
00538 mbeg = matbeg[j];
00539
00540 dbl_EGlpNumCopy (alpha, dbl_NINFTY);
00541 dbl_EGlpNumCopy (maxelem, dbl_NINFTY);
00542
00543 for (i = 0; i < mcnt; i++)
00544 {
00545 dbl_EGlpNumCopyAbs (val, matval[mbeg + i]);
00546 if (dbl_EGlpNumIsLess (maxelem, val))
00547 dbl_EGlpNumCopy (maxelem, val);
00548 if (rrow[matind[mbeg + i]] == 0 && dbl_EGlpNumIsLess (alpha, val))
00549 {
00550 dbl_EGlpNumCopy (alpha, val);
00551 r = matind[mbeg + i];
00552 }
00553 }
00554 dbl_EGlpNumCopy (val, maxelem);
00555 dbl_EGlpNumMultTo (val, dbl_PARAM_IBASIS_RPIVOT);
00556 if (dbl_EGlpNumIsLess (val, alpha))
00557 {
00558 vstat[j] = STAT_BASIC;
00559 nbelem++;
00560 irow[r] = 1;
00561 dbl_EGlpNumCopy (v[r], alpha);
00562 for (i = 0; i < mcnt; i++)
00563 if (dbl_EGlpNumIsNeqqZero (matval[mbeg + i]))
00564 rrow[matind[mbeg + i]]++;
00565 }
00566 else
00567 {
00568 dbl_EGlpNumCopy (alpha, dbl_NINFTY);
00569 for (i = 0; i < mcnt; i++)
00570 {
00571 tr = matind[mbeg + i];
00572 dbl_EGlpNumCopyAbs (val, matval[mbeg + i]);
00573 dbl_EGlpNumDivTo (val, dbl_PARAM_IBASIS_RTRIANG);
00574 if (dbl_EGlpNumIsNeqq (v[tr], dbl_INFTY) && dbl_EGlpNumIsLess (v[tr], val))
00575 {
00576 dbl_EGlpNumZero (alpha);
00577 break;
00578 }
00579 dbl_EGlpNumCopyAbs (val, matval[mbeg + i]);
00580 if (irow[tr] == 0 && dbl_EGlpNumIsLess (alpha, val))
00581 {
00582 dbl_EGlpNumCopy (alpha, val);
00583 r = tr;
00584 }
00585 }
00586 if (dbl_EGlpNumIsNeqqZero (alpha) && dbl_EGlpNumIsNeqq (alpha, dbl_NINFTY))
00587 {
00588 vstat[j] = STAT_BASIC;
00589 nbelem++;
00590 irow[r] = 1;
00591 dbl_EGlpNumCopy (v[r], alpha);
00592 for (i = 0; i < mcnt; i++)
00593 if (dbl_EGlpNumIsNeqqZero (matval[mbeg + i]))
00594 rrow[matind[mbeg + i]]++;
00595 }
00596 }
00597 }
00598 #if dbl_BASIS_STATS > 0
00599 printf ("nartifs = %d\n", lp->nrows - nbelem);
00600 #endif
00601
00602 if (nbelem < lp->nrows)
00603 {
00604 for (i = 0; i < lp->nrows; i++)
00605 {
00606 if (irow[i] == 0)
00607 {
00608 if (unitcol[i] != -1)
00609 {
00610 vstat[unitcol[i]] = STAT_BASIC;
00611 nbelem++;
00612 }
00613 else
00614 {
00615 fprintf (stderr, "Error: Not enough artificials\n");
00616 return -1;
00617 }
00618 }
00619 }
00620 }
00621 dbl_EGlpNumClearVar (alpha);
00622 dbl_EGlpNumClearVar (val);
00623 dbl_EGlpNumClearVar (maxelem);
00624 return nbelem;
00625 }
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635 static int dbl_get_initial_basis1 (
00636 dbl_lpinfo * lp,
00637 int *vstat)
00638 {
00639 int rval = 0;
00640 int i, j, tot1 = 0, tot2 = 0;
00641 int nbelem = 0, nslacks = 0;
00642 int tfree = 0, tbndone = 0;
00643 int tbounded = 0;
00644 int *irow = NULL, *rrow = NULL;
00645 int *perm = NULL, *porder = NULL;
00646 int *unitcol = NULL;
00647 double cmax;
00648 double *v = NULL;
00649 double *qpenalty = NULL;
00650 dbl_var_data vd;
00651
00652 dbl_ILLbasis_init_vardata (&vd);
00653 dbl_EGlpNumInitVar (cmax);
00654
00655 dbl_get_var_info (lp, &vd);
00656 if (!dbl_EGlpNumIsNeqqZero (vd.cmax))
00657 dbl_EGlpNumOne (cmax);
00658 else
00659 {
00660 dbl_EGlpNumCopy (cmax, vd.cmax);
00661 dbl_EGlpNumMultUiTo (cmax, 1000);
00662 }
00663
00664 ILL_SAFE_MALLOC (irow, lp->nrows, int);
00665 ILL_SAFE_MALLOC (rrow, lp->nrows, int);
00666
00667 v = dbl_EGlpNumAllocArray (lp->nrows);
00668 ILL_SAFE_MALLOC (unitcol, lp->nrows, int);
00669
00670 for (i = 0; i < lp->nrows; i++)
00671 {
00672 unitcol[i] = -1;
00673 dbl_EGlpNumCopy (v[i], dbl_INFTY);
00674 irow[i] = 0;
00675 rrow[i] = 0;
00676 }
00677
00678 nslacks = dbl_init_slack_basis (lp, vstat, irow, rrow, unitcol, NULL, NULL);
00679 if (nslacks != vd.nslacks)
00680 {
00681 printf ("complain: incorrect basis info(slacks)\n");
00682 rval = E_SIMPLEX_ERROR;
00683 ILL_CLEANUP;
00684 }
00685 if (nslacks == lp->nrows)
00686 ILL_CLEANUP;
00687 nbelem = nslacks;
00688 if (nbelem < lp->nrows)
00689 {
00690 for (i = 0; i < lp->nrows; i++)
00691 {
00692 if (irow[i] == 0)
00693 {
00694 if (unitcol[i] != -1)
00695 {
00696 vstat[unitcol[i]] = STAT_BASIC;
00697 nbelem++;
00698 }
00699 else
00700 {
00701 fprintf (stderr, "Error: Not enough artificials\n");
00702 return -1;
00703 }
00704 }
00705 }
00706 }
00707 ILL_CLEANUP;
00708
00709 tot1 = vd.nfree + vd.nbndone;
00710 tot2 = vd.nfree + vd.nbndone + vd.nbounded;
00711 ILL_SAFE_MALLOC (perm, tot2, int);
00712 ILL_SAFE_MALLOC (porder, tot2, int);
00713
00714 qpenalty = dbl_EGlpNumAllocArray (tot2);
00715
00716 for (j = 0; j < lp->ncols; j++)
00717 {
00718 if (vstat[j] == STAT_BASIC)
00719 continue;
00720
00721 switch (lp->vtype[j])
00722 {
00723 case VFREE:
00724 porder[tfree] = j;
00725 perm[tfree] = tfree;
00726 dbl_EGlpNumCopyFrac (qpenalty[tfree], lp->cz[j], cmax);
00727 tfree++;
00728 break;
00729
00730 case VLOWER:
00731 case VUPPER:
00732 porder[vd.nfree + tbndone] = j;
00733 perm[vd.nfree + tbndone] = tbndone;
00734 dbl_EGlpNumCopyFrac (qpenalty[vd.nfree + tbndone], lp->cz[j], cmax);
00735 if (lp->vtype[j] == VLOWER)
00736 dbl_EGlpNumAddTo (qpenalty[vd.nfree + tbndone], lp->lz[j]);
00737 else
00738 dbl_EGlpNumSubTo (qpenalty[vd.nfree + tbndone], lp->uz[j]);
00739 tbndone++;
00740 break;
00741
00742 case VFIXED:
00743 case VBOUNDED:
00744 porder[tot1 + tbounded] = j;
00745 perm[tot1 + tbounded] = tbounded;
00746 dbl_EGlpNumCopyFrac (qpenalty[tot1 + tbndone], lp->cz[j], cmax);
00747 dbl_EGlpNumAddTo (qpenalty[tot1 + tbndone], lp->lz[j]);
00748 dbl_EGlpNumSubTo (qpenalty[tot1 + tbndone], lp->uz[j]);
00749 tbounded++;
00750 break;
00751 }
00752 }
00753 if (tfree != vd.nfree || tbndone != vd.nbndone || tbounded != vd.nbounded)
00754 {
00755 printf ("complain: incorrect basis info \n");
00756 rval = E_SIMPLEX_ERROR;
00757 ILL_CLEANUP;
00758 }
00759
00760 dbl_ILLutil_EGlpNum_perm_quicksort (perm, qpenalty, vd.nfree);
00761 dbl_ILLutil_EGlpNum_perm_quicksort (perm + vd.nfree, qpenalty + vd.nfree,
00762 vd.nbndone);
00763 dbl_ILLutil_EGlpNum_perm_quicksort (perm + tot1, qpenalty + tot1, vd.nbounded);
00764
00765 for (i = 0; i < vd.nbndone; i++)
00766 perm[vd.nfree + i] += vd.nfree;
00767 for (i = 0; i < vd.nbounded; i++)
00768 perm[tot1 + i] += tot1;
00769
00770 nbelem =
00771 dbl_primal_col_select (lp, vstat, irow, rrow, unitcol, v, perm, porder, nbelem,
00772 tot2);
00773 if (nbelem != lp->nrows)
00774 {
00775 printf ("complain: incorrect final basis size\n");
00776 rval = E_SIMPLEX_ERROR;
00777 ILL_CLEANUP;
00778 }
00779
00780 CLEANUP:
00781 dbl_EGlpNumClearVar (cmax);
00782 if (rval)
00783 dbl_ILLbasis_free_basisinfo (lp);
00784 ILL_IFFREE (irow, int);
00785 ILL_IFFREE (rrow, int);
00786
00787 dbl_EGlpNumFreeArray (v);
00788 ILL_IFFREE (perm, int);
00789 ILL_IFFREE (porder, int);
00790 ILL_IFFREE (unitcol, int);
00791
00792 dbl_EGlpNumFreeArray (qpenalty);
00793 dbl_ILLbasis_clear_vardata (&vd);
00794 EG_RETURN (rval);
00795 }
00796
00797 static int dbl_get_initial_basis2 (
00798 dbl_lpinfo * lp,
00799 int *vstat)
00800 {
00801 int rval = 0;
00802 int i, j, k, tot1, tot2;
00803 int rbeg, rcnt, mcnt;
00804 int nbelem = 0, nslacks = 0;
00805 int tfree = 0, tbndone = 0;
00806 int tbounded = 0;
00807 int *irow = NULL, *rrow = NULL;
00808 int *perm = NULL, *porder = NULL;
00809 int *unitcol = NULL;
00810 double *v = NULL;
00811 double *qpenalty = NULL;
00812 int col = 0, s_i = 0, selc = 0;
00813 int *icol = NULL, *rcol = NULL;
00814 int *plen = NULL;
00815 double *dj = NULL;
00816 dbl_var_data vd;
00817 double seldj;
00818 double selv;
00819 double c_dj;
00820 double cmax;
00821
00822 dbl_EGlpNumInitVar (seldj);
00823 dbl_EGlpNumInitVar (selv);
00824 dbl_EGlpNumInitVar (c_dj);
00825 dbl_EGlpNumInitVar (cmax);
00826 dbl_EGlpNumZero (c_dj);
00827 dbl_EGlpNumZero (selv);
00828 dbl_EGlpNumZero (seldj);
00829 dbl_ILLbasis_init_vardata (&vd);
00830
00831 dbl_get_var_info (lp, &vd);
00832
00833 ILL_SAFE_MALLOC (irow, lp->nrows, int);
00834 ILL_SAFE_MALLOC (rrow, lp->nrows, int);
00835
00836 v = dbl_EGlpNumAllocArray (lp->nrows);
00837 ILL_SAFE_MALLOC (unitcol, lp->nrows, int);
00838 ILL_SAFE_MALLOC (icol, lp->ncols, int);
00839 ILL_SAFE_MALLOC (rcol, lp->ncols, int);
00840
00841 dj = dbl_EGlpNumAllocArray (lp->ncols);
00842
00843 for (i = 0; i < lp->nrows; i++)
00844 {
00845 unitcol[i] = -1;
00846 dbl_EGlpNumCopy (v[i], dbl_INFTY);
00847 irow[i] = 0;
00848 rrow[i] = 0;
00849 }
00850
00851 for (i = 0; i < lp->ncols; i++)
00852 {
00853 icol[i] = 0;
00854 rcol[i] = 0;
00855 dbl_EGlpNumCopy (dj[i], lp->cz[i]);
00856 }
00857
00858 nslacks = dbl_init_slack_basis (lp, vstat, irow, rrow, unitcol, icol, rcol);
00859 if (nslacks != vd.nslacks)
00860 {
00861 printf ("complain: incorrect basis info\n");
00862 rval = E_SIMPLEX_ERROR;
00863 ILL_CLEANUP;
00864 }
00865 if (nslacks == lp->nrows)
00866 ILL_CLEANUP;
00867 nbelem = nslacks;
00868
00869
00870 ILL_SAFE_MALLOC (perm, lp->ncols, int);
00871 ILL_SAFE_MALLOC (porder, lp->ncols, int);
00872 ILL_SAFE_MALLOC (plen, lp->nrows, int);
00873
00874 qpenalty = dbl_EGlpNumAllocArray (lp->ncols);
00875
00876
00877 for (i = 0; i < lp->nrows; i++)
00878 {
00879 if (irow[i] != 1)
00880 {
00881 rbeg = lp->rowbeg[i];
00882 rcnt = lp->rowcnt[i];
00883 for (j = 0; j < rcnt; j++)
00884 {
00885 dbl_EGlpNumCopyAbs (cmax, lp->rowval[rbeg + j]);
00886 if (dbl_EGlpNumIsNeqq (cmax, dbl_oneLpNum))
00887 break;
00888 }
00889 if (j == rcnt)
00890 {
00891 perm[s_i] = s_i;
00892 porder[s_i] = i;
00893 plen[s_i] = rcnt;
00894 s_i++;
00895 }
00896 }
00897 }
00898
00899
00900 dbl_ILLutil_int_perm_quicksort (perm, plen, s_i);
00901
00902
00903 for (k = 0; k < s_i; k++)
00904 {
00905 i = porder[perm[k]];
00906 rbeg = lp->rowbeg[i];
00907 rcnt = lp->rowcnt[i];
00908 selc = -1;
00909 dbl_EGlpNumCopy (seldj, dbl_INFTY);
00910 dbl_EGlpNumZero (selv);
00911
00912
00913 for (j = 0; j < rcnt; j++)
00914 {
00915 col = lp->rowind[rbeg + j];
00916 if (rcol[col] == 1)
00917 break;
00918 if (dbl_EGlpNumIsLessZero (dj[col]))
00919 {
00920 if (dbl_EGlpNumIsLess (dj[col], seldj))
00921 {
00922 selc = col;
00923 dbl_EGlpNumCopy (seldj, dj[col]);
00924 dbl_EGlpNumCopy (selv, lp->rowval[rbeg + j]);
00925 }
00926 }
00927 }
00928
00929 if (selc != -1)
00930 {
00931 nbelem++;
00932 irow[i] = 1;
00933 rrow[i] = 1;
00934 icol[selc] = 1;
00935 dbl_EGlpNumCopyFrac (c_dj, dj[selc], selv);
00936 vstat[selc] = STAT_BASIC;
00937 for (j = 0; j < rcnt; j++)
00938 {
00939 col = lp->rowind[rbeg + j];
00940 dbl_EGlpNumSubInnProdTo (dj[col], lp->rowval[rbeg + j], c_dj);
00941 rcol[col] = 1;
00942 }
00943 }
00944 }
00945 #if dbl_BASIS_STATS > 0
00946 printf ("unit rows = %d\n", s_i);
00947 printf ("nslacks %d, unit rows selected = %d\n", nslacks, nbelem - nslacks);
00948 #endif
00949
00950 tot1 = vd.nfree + vd.nbndone;
00951
00952 if (!dbl_EGlpNumIsNeqqZero (vd.cmax))
00953 dbl_EGlpNumOne (cmax);
00954 else
00955 {
00956 dbl_EGlpNumCopy (cmax, vd.cmax);
00957 dbl_EGlpNumMultUiTo (cmax, 1000);
00958 }
00959 for (j = 0; j < lp->ncols; j++)
00960 {
00961 if (vstat[j] == STAT_BASIC)
00962 continue;
00963 if (icol[j] == 1 || dbl_EGlpNumIsNeqZero (dj[j], dbl_BD_TOLER))
00964 continue;
00965 mcnt = lp->matcnt[j];
00966
00967 dbl_EGlpNumSet (c_dj, (double) mcnt);
00968 switch (lp->vtype[j])
00969 {
00970 case VFREE:
00971 porder[tfree] = j;
00972 perm[tfree] = tfree;
00973 dbl_EGlpNumCopyFrac (qpenalty[tfree], lp->cz[j], cmax);
00974 dbl_EGlpNumAddTo (qpenalty[tfree], c_dj);
00975 tfree++;
00976 break;
00977
00978 case VLOWER:
00979 case VUPPER:
00980 porder[vd.nfree + tbndone] = j;
00981 perm[vd.nfree + tbndone] = tbndone;
00982 dbl_EGlpNumCopyFrac (qpenalty[vd.nfree + tbndone], lp->cz[j], cmax);
00983 dbl_EGlpNumAddTo (qpenalty[vd.nfree + tbndone], c_dj);
00984 if (lp->vtype[j] == VLOWER)
00985 dbl_EGlpNumAddTo (qpenalty[vd.nfree + tbndone], lp->lz[j]);
00986 else
00987 dbl_EGlpNumSubTo (qpenalty[vd.nfree + tbndone], lp->uz[j]);
00988 tbndone++;
00989 break;
00990
00991 case VFIXED:
00992 case VBOUNDED:
00993 porder[tot1 + tbounded] = j;
00994 perm[tot1 + tbounded] = tbounded;
00995 dbl_EGlpNumCopyFrac (qpenalty[tot1 + tbounded], lp->cz[j], cmax);
00996 dbl_EGlpNumAddTo (qpenalty[tot1 + tbounded], lp->lz[j]);
00997 dbl_EGlpNumSubTo (qpenalty[tot1 + tbounded], lp->uz[j]);
00998 dbl_EGlpNumAddTo (qpenalty[tot1 + tbounded], c_dj);
00999 tbounded++;
01000 break;
01001 }
01002 }
01003 #if dbl_BASIS_STATS > 0
01004 printf ("bfree %d, bone %d, bbnd %d\n", tfree, tbndone, tbounded);
01005 #endif
01006
01007 dbl_ILLutil_EGlpNum_perm_quicksort (perm, qpenalty, tfree);
01008 dbl_ILLutil_EGlpNum_perm_quicksort (perm + vd.nfree, qpenalty + vd.nfree,
01009 tbndone);
01010 dbl_ILLutil_EGlpNum_perm_quicksort (perm + tot1, qpenalty + tot1, tbounded);
01011
01012 tot2 = tfree + tbndone;
01013 for (i = 0; i < tbndone; i++)
01014 {
01015 perm[tfree + i] = perm[vd.nfree + i] + tfree;
01016 porder[tfree + i] = porder[vd.nfree + i];
01017 }
01018 for (i = 0; i < tbounded; i++)
01019 {
01020 perm[tot2 + i] = perm[tot1 + i] + tot2;
01021 porder[tot2 + i] = porder[tot1 + i];
01022 }
01023 tot2 += tbounded;
01024
01025 nbelem =
01026 dbl_primal_col_select (lp, vstat, irow, rrow, unitcol, v, perm, porder, nbelem,
01027 tot2);
01028 if (nbelem != lp->nrows)
01029 {
01030 printf ("complain: incorrect final basis size\n");
01031 rval = E_SIMPLEX_ERROR;
01032 ILL_CLEANUP;
01033 }
01034
01035 CLEANUP:
01036 if (rval)
01037 dbl_ILLbasis_free_basisinfo (lp);
01038
01039 ILL_IFFREE (irow, int);
01040 ILL_IFFREE (rrow, int);
01041
01042 dbl_EGlpNumFreeArray (v);
01043 ILL_IFFREE (unitcol, int);
01044 ILL_IFFREE (icol, int);
01045 ILL_IFFREE (rcol, int);
01046
01047 dbl_EGlpNumFreeArray (dj);
01048 ILL_IFFREE (perm, int);
01049 ILL_IFFREE (porder, int);
01050 ILL_IFFREE (plen, int);
01051
01052 dbl_EGlpNumFreeArray (qpenalty);
01053 dbl_EGlpNumClearVar (seldj);
01054 dbl_EGlpNumClearVar (selv);
01055 dbl_EGlpNumClearVar (c_dj);
01056 dbl_EGlpNumClearVar (cmax);
01057 dbl_ILLbasis_clear_vardata (&vd);
01058 EG_RETURN (rval);
01059 }
01060
01061 static int dbl_set_basis_indices (
01062 dbl_lpinfo * lp,
01063 int *vstat)
01064 {
01065 int i, b = 0, nb = 0;
01066 int vs;
01067
01068 for (i = 0; i < lp->ncols; i++)
01069 {
01070 vs = vstat[i];
01071 lp->vstat[i] = vs;
01072
01073 if (vs == STAT_BASIC)
01074 {
01075 lp->baz[b] = i;
01076 lp->vindex[i] = b;
01077 b++;
01078 }
01079 else if (vs == STAT_UPPER || vs == STAT_LOWER || vs == STAT_ZERO)
01080 {
01081 lp->nbaz[nb] = i;
01082 lp->vindex[i] = nb;
01083 nb++;
01084 }
01085 else
01086 {
01087 fprintf (stderr, "Error in basis creation\n");
01088 return E_SIMPLEX_ERROR;
01089 }
01090 }
01091 if (b != lp->nrows)
01092 {
01093 fprintf (stderr, "Error 2 in basis creation\n");
01094 return E_SIMPLEX_ERROR;
01095 }
01096 else if (nb != lp->nnbasic)
01097 {
01098 fprintf (stderr, "Error 3 in basis creation\n");
01099 return E_SIMPLEX_ERROR;
01100 }
01101 return 0;
01102 }
01103
01104 int dbl_ILLbasis_get_initial (
01105 dbl_lpinfo * lp,
01106 int algorithm)
01107 {
01108 int rval = 0;
01109 int *vstat = NULL;
01110
01111 dbl_ILLbasis_free_basisinfo (lp);
01112 dbl_ILLbasis_init_basisinfo (lp);
01113 rval = dbl_ILLbasis_build_basisinfo (lp);
01114 CHECKRVALG (rval, CLEANUP);
01115
01116 ILL_SAFE_MALLOC (vstat, lp->ncols, int);
01117
01118 if (algorithm == PRIMAL_SIMPLEX)
01119 rval = dbl_get_initial_basis1 (lp, vstat);
01120 else
01121 rval = dbl_get_initial_basis2 (lp, vstat);
01122
01123 if (rval == E_SIMPLEX_ERROR)
01124 {
01125 FILE *f = fopen ("bad.lp", "w");
01126 int tval = dbl_ILLwrite_lp_file (lp->O, f, NULL);
01127
01128 if (tval)
01129 {
01130 fprintf (stderr, "Error writing bad lp\n");
01131 }
01132 if (f != NULL)
01133 fclose (f);
01134 }
01135 CHECKRVALG (rval, CLEANUP);
01136
01137 rval = dbl_set_basis_indices (lp, vstat);
01138 CHECKRVALG (rval, CLEANUP);
01139 lp->basisid = 0;
01140
01141 CLEANUP:
01142 ILL_IFFREE (vstat, int);
01143
01144 EG_RETURN (rval);
01145 }
01146
01147 static int dbl_choose_basis (
01148 int algorithm,
01149 double pinf1,
01150 double dinf1,
01151 double pinf2,
01152 double dinf2)
01153 {
01154
01155
01156
01157
01158
01159
01160 int choice = 1;
01161 double rp, rd;
01162
01163 if (algorithm == PRIMAL_SIMPLEX)
01164 {
01165 dbl_EGlpNumInitVar (rp);
01166 dbl_EGlpNumInitVar (rd);
01167 dbl_EGlpNumCopyDiff (rp, pinf1, pinf2);
01168 dbl_EGlpNumCopyDiff (rd, dinf1, dinf2);
01169 if (dbl_EGlpNumIsLeq (rp, dbl_CB_EPS) && dbl_EGlpNumIsLeq (rd, dbl_CB_EPS))
01170 choice = 1;
01171 else
01172 {
01173 dbl_EGlpNumSign (rp);
01174 dbl_EGlpNumSign (rd);
01175 if (dbl_EGlpNumIsLeq (rp, dbl_CB_EPS) && dbl_EGlpNumIsLeq (rd, dbl_CB_EPS))
01176 choice = 2;
01177 else if (dbl_EGlpNumIsLess (pinf1, pinf2) && dbl_EGlpNumIsLess (dinf2, dinf1))
01178 {
01179 choice = 1;
01180 dbl_EGlpNumCopyFrac (rp, pinf1, pinf2);
01181 dbl_EGlpNumCopyFrac (rd, dinf2, dinf1);
01182 dbl_EGlpNumMultTo (rd, dbl_CB_INF_RATIO);
01183 if (dbl_EGlpNumIsLess (dbl_CB_PRI_RLIMIT, rp) && (dbl_EGlpNumIsLess (rd, rp)))
01184 choice = 2;
01185 }
01186 else if (dbl_EGlpNumIsLess (pinf2, pinf1) && dbl_EGlpNumIsLess (dinf1, dinf2))
01187 {
01188 choice = 2;
01189 dbl_EGlpNumCopyFrac (rp, pinf2, pinf1);
01190 dbl_EGlpNumCopyFrac (rd, dinf1, dinf2);
01191 dbl_EGlpNumMultTo (rd, dbl_CB_INF_RATIO);
01192 if (dbl_EGlpNumIsLess (dbl_CB_PRI_RLIMIT, rp) && dbl_EGlpNumIsLess (rd, rp))
01193 choice = 1;
01194 }
01195 else
01196 choice = 1;
01197 }
01198 dbl_EGlpNumClearVar (rp);
01199 dbl_EGlpNumClearVar (rd);
01200 }
01201 ILL_IFTRACE ("%s:%d\n", __func__, choice);
01202 return choice;
01203 }
01204
01205 int dbl_ILLbasis_get_cinitial (
01206 dbl_lpinfo * lp,
01207 int algorithm)
01208 {
01209 int rval = 0;
01210 int *vstat1 = NULL;
01211 int *vstat2 = NULL;
01212 int singular;
01213 int choice = 0;
01214
01215 #if dbl_BASIS_STATS > 0
01216 int i, nz1 = 0, nz2 = 0;
01217 #endif
01218 double pinf1, pinf2, dinf1, dinf2;
01219 dbl_feas_info fi;
01220
01221 dbl_EGlpNumInitVar (pinf1);
01222 dbl_EGlpNumInitVar (pinf2);
01223 dbl_EGlpNumInitVar (dinf1);
01224 dbl_EGlpNumInitVar (dinf2);
01225 dbl_EGlpNumInitVar (fi.totinfeas);
01226
01227 dbl_ILLbasis_free_basisinfo (lp);
01228 dbl_ILLbasis_init_basisinfo (lp);
01229 rval = dbl_ILLbasis_build_basisinfo (lp);
01230 CHECKRVALG (rval, CLEANUP);
01231
01232 ILL_SAFE_MALLOC (vstat1, lp->ncols, int);
01233 ILL_SAFE_MALLOC (vstat2, lp->ncols, int);
01234
01235 if (algorithm != PRIMAL_SIMPLEX)
01236 {
01237 rval = dbl_get_initial_basis2 (lp, vstat2);
01238 CHECKRVALG (rval, CLEANUP);
01239 rval = dbl_set_basis_indices (lp, vstat2);
01240 lp->basisid = 0;
01241 ILL_CLEANUP;
01242 }
01243
01244 rval = dbl_get_initial_basis1 (lp, vstat1);
01245 CHECKRVALG (rval, CLEANUP);
01246 rval = dbl_get_initial_basis2 (lp, vstat2);
01247 CHECKRVALG (rval, CLEANUP);
01248 lp->basisid = 0;
01249
01250
01251 rval = dbl_set_basis_indices (lp, vstat1);
01252 CHECKRVALG (rval, CLEANUP);
01253 #if dbl_BASIS_STATS > 0
01254 for (i = 0; i < lp->nrows; i++)
01255 nz1 += lp->matcnt[lp->baz[i]];
01256 #endif
01257 rval = dbl_ILLbasis_factor (lp, &singular);
01258 if (singular)
01259 MESSAGE (__QS_SB_VERB, "Singular Basis found!");
01260 CHECKRVALG (rval, CLEANUP);
01261
01262 dbl_ILLfct_compute_piz (lp);
01263 dbl_ILLfct_compute_dz (lp);
01264 dbl_ILLfct_dual_adjust (lp, dbl_zeroLpNum);
01265 dbl_ILLfct_compute_xbz (lp);
01266
01267 dbl_ILLfct_check_pfeasible (lp, &fi, lp->tol->pfeas_tol);
01268 dbl_ILLfct_check_dfeasible (lp, &fi, lp->tol->dfeas_tol);
01269 dbl_EGlpNumCopy (pinf1, lp->pinfeas);
01270 dbl_EGlpNumCopy (dinf1, lp->dinfeas);
01271
01272
01273
01274
01275
01276
01277 rval = dbl_set_basis_indices (lp, vstat2);
01278 CHECKRVALG (rval, CLEANUP);
01279 #if dbl_BASIS_STATS > 0
01280 for (i = 0; i < lp->nrows; i++)
01281 nz2 += lp->matcnt[lp->baz[i]];
01282 #endif
01283 rval = dbl_ILLbasis_factor (lp, &singular);
01284 if (singular)
01285 MESSAGE (__QS_SB_VERB, "Singular Basis found!");
01286 CHECKRVALG (rval, CLEANUP);
01287
01288 dbl_ILLfct_compute_piz (lp);
01289 dbl_ILLfct_compute_dz (lp);
01290 dbl_ILLfct_dual_adjust (lp, dbl_zeroLpNum);
01291 dbl_ILLfct_compute_xbz (lp);
01292
01293 dbl_ILLfct_check_pfeasible (lp, &fi, lp->tol->pfeas_tol);
01294 dbl_ILLfct_check_dfeasible (lp, &fi, lp->tol->dfeas_tol);
01295 dbl_EGlpNumCopy (pinf2, lp->pinfeas);
01296 dbl_EGlpNumCopy (dinf2, lp->dinfeas);
01297
01298 #if dbl_BASIS_STATS > 0
01299 printf ("b1: nz %d pinf %.2f dinf %.2f\n", nz1, dbl_EGlpNumToLf (pinf1),
01300 dbl_EGlpNumToLf (dinf1));
01301 printf ("b2: nz %d pinf %.2f dinf %.2f\n", nz2, dbl_EGlpNumToLf (pinf2),
01302 dbl_EGlpNumToLf (dinf2));
01303 #endif
01304 choice = dbl_choose_basis (algorithm, pinf1, dinf1, pinf2, dinf2);
01305 if (choice == 1)
01306 {
01307 lp->fbasisid = -1;
01308 rval = dbl_set_basis_indices (lp, vstat1);
01309 CHECKRVALG (rval, CLEANUP);
01310 }
01311
01312 CLEANUP:
01313 if (rval == E_SIMPLEX_ERROR)
01314 {
01315 FILE *fil = fopen ("bad.lp", "w");
01316 int tval = dbl_ILLwrite_lp_file (lp->O, fil, NULL);
01317
01318 if (tval)
01319 {
01320 fprintf (stderr, "Error writing bad lp\n");
01321 }
01322 if (fil != NULL)
01323 fclose (fil);
01324 }
01325 ILL_IFFREE (vstat1, int);
01326 ILL_IFFREE (vstat2, int);
01327
01328 dbl_EGlpNumClearVar (pinf1);
01329 dbl_EGlpNumClearVar (pinf2);
01330 dbl_EGlpNumClearVar (dinf1);
01331 dbl_EGlpNumClearVar (dinf2);
01332 dbl_EGlpNumClearVar (fi.totinfeas);
01333 EG_RETURN (rval);
01334 }
01335
01336 int dbl_ILLbasis_factor (
01337 dbl_lpinfo * lp,
01338 int *singular)
01339 {
01340 int rval = 0;
01341 int i;
01342 int eindex;
01343 int lindex;
01344 int ltype;
01345 int lvstat;
01346 int nsing = 0;
01347 int *singr = 0;
01348 int *singc = 0;
01349
01350 *singular = 0;
01351 do
01352 {
01353 if (lp->f)
01354 {
01355 dbl_ILLfactor_free_factor_work (lp->f);
01356 }
01357 else
01358 {
01359 ILL_SAFE_MALLOC (lp->f, 1, dbl_factor_work);
01360 dbl_EGlpNumInitVar (lp->f->fzero_tol);
01361 dbl_EGlpNumInitVar (lp->f->szero_tol);
01362 dbl_EGlpNumInitVar (lp->f->partial_tol);
01363 dbl_EGlpNumInitVar (lp->f->maxelem_orig);
01364 dbl_EGlpNumInitVar (lp->f->maxelem_factor);
01365 dbl_EGlpNumInitVar (lp->f->maxelem_cur);
01366 dbl_EGlpNumInitVar (lp->f->partial_cur);
01367 dbl_ILLfactor_init_factor_work (lp->f);
01368 }
01369 rval = dbl_ILLfactor_create_factor_work (lp->f, lp->O->nrows);
01370 CHECKRVALG (rval, CLEANUP);
01371
01372 rval = dbl_ILLfactor (lp->f, lp->baz, lp->matbeg, lp->matcnt,
01373 lp->matind, lp->matval, &nsing, &singr, &singc);
01374 CHECKRVALG (rval, CLEANUP);
01375
01376 if (nsing != 0)
01377 {
01378 *singular = 1;
01379 MESSAGE (__QS_SB_VERB, "Found singular basis!");
01380 for (i = 0; i < nsing; i++)
01381 {
01382 eindex = lp->vindex[lp->O->rowmap[singr[i]]];
01383 lindex = singc[i];
01384 ltype = lp->vtype[lp->baz[lindex]];
01385
01386 if (ltype == VBOUNDED || ltype == VLOWER || ltype == VARTIFICIAL)
01387 lvstat = STAT_LOWER;
01388 else if (ltype == VUPPER)
01389 lvstat = STAT_UPPER;
01390 else
01391 lvstat = STAT_ZERO;
01392
01393 dbl_ILLfct_update_basis_info (lp, eindex, lindex, lvstat);
01394 lp->basisid++;
01395 }
01396 ILL_IFFREE (singr, int);
01397 ILL_IFFREE (singc, int);
01398 }
01399
01400 } while (nsing != 0);
01401
01402 lp->fbasisid = lp->basisid;
01403
01404 CLEANUP:
01405 ILL_IFFREE (singr, int);
01406 ILL_IFFREE (singc, int);
01407
01408 if (rval)
01409 fprintf (stderr, "Error: unknown in %s\n", __func__);
01410 EG_RETURN (rval);
01411 }
01412
01413 int dbl_ILLbasis_refactor (
01414 dbl_lpinfo * lp)
01415 {
01416 int sing = 0;
01417 int rval = 0;
01418
01419 rval = dbl_ILLbasis_factor (lp, &sing);
01420 if (sing)
01421 {
01422 MESSAGE (__QS_SB_VERB, "Singular Basis found!");
01423 rval = QS_LP_CHANGE_PREC;
01424 return rval;
01425 }
01426 EG_RETURN (rval);
01427 }
01428
01429 void dbl_ILLbasis_column_solve (
01430 dbl_lpinfo * lp,
01431 dbl_svector * rhs,
01432 dbl_svector * soln)
01433 {
01434 dbl_ILLfactor_ftran (lp->f, rhs, soln);
01435 }
01436
01437 void dbl_ILLbasis_column_solve_update (
01438 dbl_lpinfo * lp,
01439 dbl_svector * rhs,
01440 dbl_svector * upd,
01441 dbl_svector * soln)
01442 {
01443 dbl_ILLfactor_ftran_update (lp->f, rhs, upd, soln);
01444 }
01445
01446 void dbl_ILLbasis_row_solve (
01447 dbl_lpinfo * lp,
01448 dbl_svector * rhs,
01449 dbl_svector * soln)
01450 {
01451 dbl_ILLfactor_btran (lp->f, rhs, soln);
01452 }
01453
01454 int dbl_ILLbasis_update (
01455 dbl_lpinfo * lp,
01456 dbl_svector * y,
01457 int lindex,
01458 int *refactor,
01459 int *singular)
01460 {
01461 #if 0
01462 *refactor = 1;
01463 return dbl_ILLbasis_factor (lp, singular);
01464 #else
01465
01466 int rval = 0;
01467
01468 *refactor = 0;
01469 rval = dbl_ILLfactor_update (lp->f, y, lindex, refactor);
01470 if (rval == E_FACTOR_BLOWUP || rval == E_UPDATE_SINGULAR_ROW
01471 || rval == E_UPDATE_SINGULAR_COL)
01472 {
01473
01474
01475
01476 *refactor = 1;
01477 rval = 0;
01478 }
01479 if (rval == E_UPDATE_NOSPACE)
01480 {
01481 *refactor = 1;
01482 rval = 0;
01483 }
01484
01485 if (*refactor)
01486 {
01487 rval = dbl_ILLbasis_factor (lp, singular);
01488 if (*singular)
01489 MESSAGE (__QS_SB_VERB, "Singular Basis found!");
01490 }
01491 if (rval)
01492 {
01493 FILE *eout = 0;
01494 int tval;
01495
01496 printf ("write bad lp to factor.lp\n");
01497 fflush (stdout);
01498 eout = fopen ("factor.lp", "w");
01499 if (!eout)
01500 {
01501 fprintf (stderr, "could not open file to write bad factor lp\n");
01502 }
01503 else
01504 {
01505 tval = dbl_ILLwrite_lp_file (lp->O, eout, NULL);
01506 if (tval)
01507 {
01508 fprintf (stderr, "error while writing bad factor lp\n");
01509 }
01510 fclose (eout);
01511 }
01512
01513 printf ("write bad basis to factor.bas\n");
01514 fflush (stdout);
01515 tval = dbl_ILLlib_writebasis (lp, 0, "factor.bas");
01516 if (tval)
01517 {
01518 fprintf (stderr, "error while writing factor basis\n");
01519 }
01520 }
01521
01522 EG_RETURN (rval);
01523 #endif
01524 }