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
00027 #define FCT_DEBUG 0
00028
00029 #include "qs_config.h"
00030 #include "iqsutil.h"
00031 #include "lpdefs.h"
00032 #include "stddefs.h"
00033 #include "basis.h"
00034 #include "fct.h"
00035 #include "price.h"
00036 #include "ratio.h"
00037 #include "dstruct.h"
00038
00039 bndinfo *ILLfct_new_bndinfo (
00040 void)
00041 {
00042 bndinfo *nbnd = (bndinfo *) malloc (sizeof (bndinfo));
00043
00044 if (!nbnd)
00045 {
00046 fprintf (stderr, "not enough memory, in %s\n", __func__);
00047 exit (1);
00048 }
00049 EGlpNumInitVar ((nbnd->pbound));
00050 EGlpNumInitVar ((nbnd->cbound));
00051 return nbnd;
00052 }
00053
00054 void ILLfct_free_bndinfo (
00055 bndinfo * binfo)
00056 {
00057 EGlpNumClearVar ((binfo->pbound));
00058 EGlpNumClearVar ((binfo->cbound));
00059 ILL_IFFREE (binfo, bndinfo);
00060 return;
00061 }
00062
00063 static int compute_zA1 (
00064 lpinfo * lp,
00065 svector * z,
00066 svector * zA,
00067 EGlpNum_t ztoler),
00068
00069
00070
00071
00072
00073 compute_zA3 (
00074 lpinfo * lp,
00075 svector * z,
00076 svector * zA,
00077 EGlpNum_t ztoler),
00078 expand_var_bounds (
00079 lpinfo * lp,
00080 EGlpNum_t ftol,
00081 int *chgb),
00082 expand_var_coefs (
00083 lpinfo * lp,
00084 EGlpNum_t ftol,
00085 int *chgc);
00086
00087 static void update_piv_values (
00088 count_struct * c,
00089 int phase,
00090 const EGlpNum_t piv),
00091
00092
00093 add_vectors (
00094 lpinfo * lp,
00095 svector * a,
00096 svector * b,
00097 svector * c,
00098 const EGlpNum_t t);
00099
00100 static double my_rand (
00101 int bound,
00102 ILLrandstate * r);
00103
00104
00105 void ILLfct_load_workvector (
00106 lpinfo * lp,
00107 svector * s)
00108 {
00109 int i;
00110
00111 for (i = 0; i < s->nzcnt; i++)
00112 {
00113 lp->work.indx[i] = s->indx[i];
00114 EGlpNumCopy (lp->work.coef[s->indx[i]], s->coef[i]);
00115 }
00116 lp->work.nzcnt = s->nzcnt;
00117 }
00118
00119 void ILLfct_zero_workvector (
00120 lpinfo * lp)
00121 {
00122 int i;
00123
00124 for (i = 0; i < lp->work.nzcnt; i++)
00125 EGlpNumZero (lp->work.coef[lp->work.indx[i]]);
00126 lp->work.nzcnt = 0;
00127 }
00128
00129 void ILLfct_set_variable_type (
00130 lpinfo * lp)
00131 {
00132 int j;
00133
00134 for (j = 0; j < lp->ncols; j++)
00135 {
00136
00137 if (lp->matcnt[j] == 1 && lp->O->rowmap[lp->matind[lp->matbeg[j]]] == j)
00138 lp->vclass[j] = CLASS_LOGICAL;
00139 else
00140 lp->vclass[j] = CLASS_STRUCT;
00141 switch ((EGlpNumIsEqqual (lp->uz[j], INFTY) ? 1U : 0U) |
00142 (EGlpNumIsEqqual (lp->lz[j], NINFTY) ? 2U : 0U))
00143 {
00144 case 0:
00145 if (EGlpNumIsLess (lp->lz[j], lp->uz[j]))
00146 lp->vtype[j] = VBOUNDED;
00147 else if (!EGlpNumIsNeqqZero (lp->lz[j]) &&
00148 (lp->vclass[j] == CLASS_LOGICAL))
00149 lp->vtype[j] = VARTIFICIAL;
00150 else
00151 lp->vtype[j] = VFIXED;
00152 break;
00153 case 3:
00154 lp->vtype[j] = VFREE;
00155 break;
00156 case 1:
00157 lp->vtype[j] = VLOWER;
00158 break;
00159 case 2:
00160 lp->vtype[j] = VUPPER;
00161 break;
00162 }
00163 }
00164 }
00165
00166
00167
00168 void ILLfct_compute_pobj (
00169 lpinfo * lp)
00170 {
00171 int i, j;
00172 int col;
00173 EGlpNum_t sum;
00174
00175 EGlpNumInitVar (sum);
00176 EGlpNumZero (sum);
00177
00178 for (i = 0; i < lp->nrows; i++)
00179 EGlpNumAddInnProdTo (sum, lp->cz[lp->baz[i]], lp->xbz[i]);
00180
00181 for (j = 0; j < lp->nnbasic; j++)
00182 {
00183 col = lp->nbaz[j];
00184 if (lp->vstat[col] == STAT_UPPER)
00185 EGlpNumAddInnProdTo (sum, lp->cz[col], lp->uz[col]);
00186 else if (lp->vstat[col] == STAT_LOWER)
00187 EGlpNumAddInnProdTo (sum, lp->cz[col], lp->lz[col]);
00188 }
00189 EGlpNumCopy (lp->pobjval, sum);
00190 EGlpNumCopy (lp->objval, sum);
00191 EGlpNumClearVar (sum);
00192 }
00193
00194 void ILLfct_compute_dobj (
00195 lpinfo * lp)
00196 {
00197 int i, j;
00198 int col;
00199 EGlpNum_t sum;
00200
00201 EGlpNumInitVar (sum);
00202 EGlpNumZero (sum);
00203
00204 for (i = 0; i < lp->nrows; i++)
00205 EGlpNumAddInnProdTo (sum, lp->piz[i], lp->bz[i]);
00206
00207 for (j = 0; j < lp->nnbasic; j++)
00208 {
00209 col = lp->nbaz[j];
00210 if (lp->vstat[col] == STAT_UPPER)
00211 EGlpNumAddInnProdTo (sum, lp->dz[j], lp->uz[col]);
00212 else if (lp->vstat[col] == STAT_LOWER)
00213 EGlpNumAddInnProdTo (sum, lp->dz[j], lp->lz[col]);
00214 }
00215 EGlpNumCopy (lp->dobjval, sum);
00216 EGlpNumCopy (lp->objval, sum);
00217 EGlpNumClearVar (sum);
00218 }
00219
00220 void ILLfct_compute_xbz (
00221 lpinfo * lp)
00222 {
00223 int i, j, r;
00224 int col, mcnt, mbeg;
00225 svector *srhs = &(lp->srhs);
00226 svector *ssoln = &(lp->ssoln);
00227 EGlpNum_t xval;
00228
00229 EGlpNumInitVar (xval);
00230
00231 for (i = 0; i < lp->nrows; i++)
00232 {
00233 EGlpNumZero (lp->xbz[i]);
00234 EGlpNumCopy (srhs->coef[i], lp->bz[i]);
00235 }
00236 for (j = 0; j < lp->nnbasic; j++)
00237 {
00238 col = lp->nbaz[j];
00239 EGlpNumZero (xval);
00240 if (lp->vstat[col] == STAT_UPPER && EGlpNumIsNeqqZero (lp->uz[col]))
00241 EGlpNumCopy (xval, lp->uz[col]);
00242 else if (lp->vstat[col] == STAT_LOWER && EGlpNumIsNeqqZero (lp->lz[col]))
00243 EGlpNumCopy (xval, lp->lz[col]);
00244
00245 if (EGlpNumIsNeqqZero (xval))
00246 {
00247 mcnt = lp->matcnt[col];
00248 mbeg = lp->matbeg[col];
00249 for (i = 0; i < mcnt; i++)
00250 EGlpNumSubInnProdTo (srhs->coef[lp->matind[mbeg + i]], xval,
00251 lp->matval[mbeg + i]);
00252 }
00253 }
00254 for (i = 0, r = 0; i < lp->nrows; i++)
00255 if (EGlpNumIsNeqqZero (srhs->coef[i]))
00256 {
00257 EGlpNumCopy (srhs->coef[r], srhs->coef[i]);
00258 srhs->indx[r] = i;
00259 r++;
00260 }
00261 srhs->nzcnt = r;
00262
00263 ILLbasis_column_solve (lp, srhs, ssoln);
00264 for (i = 0; i < ssoln->nzcnt; i++)
00265 EGlpNumCopy (lp->xbz[ssoln->indx[i]], ssoln->coef[i]);
00266 EGlpNumClearVar (xval);
00267 }
00268
00269 void ILLfct_compute_piz (
00270 lpinfo * lp)
00271 {
00272 int i, r;
00273 svector *srhs = &(lp->srhs);
00274 svector *ssoln = &(lp->ssoln);
00275
00276 for (i = 0, r = 0; i < lp->nrows; i++)
00277 {
00278 EGlpNumZero (lp->piz[i]);
00279 if (EGlpNumIsNeqqZero (lp->cz[lp->baz[i]]))
00280 {
00281 srhs->indx[r] = i;
00282 EGlpNumCopy (srhs->coef[r], lp->cz[lp->baz[i]]);
00283 r++;
00284 }
00285 }
00286 srhs->nzcnt = r;
00287
00288 ILLbasis_row_solve (lp, srhs, ssoln);
00289 for (i = 0; i < ssoln->nzcnt; i++)
00290 EGlpNumCopy (lp->piz[ssoln->indx[i]], ssoln->coef[i]);
00291 }
00292
00293 void ILLfct_compute_dz (
00294 lpinfo * lp)
00295 {
00296 int i, j;
00297 int col;
00298 int mcnt, mbeg;
00299 EGlpNum_t sum;
00300
00301 EGlpNumInitVar (sum);
00302
00303 for (j = 0; j < lp->nnbasic; j++)
00304 {
00305 EGlpNumZero (sum);
00306 col = lp->nbaz[j];
00307 mcnt = lp->matcnt[col];
00308 mbeg = lp->matbeg[col];
00309 for (i = 0; i < mcnt; i++)
00310 EGlpNumAddInnProdTo (sum, lp->piz[lp->matind[mbeg + i]],
00311 lp->matval[mbeg + i]);
00312 EGlpNumCopyDiff (lp->dz[j], lp->cz[col], sum);
00313 }
00314 EGlpNumClearVar (sum);
00315 }
00316
00317 void ILLfct_compute_phaseI_xbz (
00318 lpinfo * lp)
00319 {
00320 int i, j, r;
00321 int col, mcnt, mbeg;
00322 svector *srhs = &(lp->srhs);
00323 svector *ssoln = &(lp->ssoln);
00324
00325 for (i = 0; i < lp->nrows; i++)
00326 {
00327 EGlpNumZero (lp->xbz[i]);
00328 EGlpNumZero (srhs->coef[i]);
00329 }
00330 for (j = 0; j < lp->nnbasic; j++)
00331 {
00332 col = lp->nbaz[j];
00333
00334 if (lp->dfeas[j])
00335 {
00336 mcnt = lp->matcnt[col];
00337 mbeg = lp->matbeg[col];
00338 if (lp->dfeas[j] == -1)
00339 for (i = 0; i < mcnt; i++)
00340 EGlpNumSubTo (srhs->coef[lp->matind[mbeg + i]], lp->matval[mbeg + i]);
00341 else
00342 for (i = 0; i < mcnt; i++)
00343 EGlpNumAddTo (srhs->coef[lp->matind[mbeg + i]], lp->matval[mbeg + i]);
00344 }
00345 }
00346 for (i = 0, r = 0; i < lp->nrows; i++)
00347 if (EGlpNumIsNeqqZero (srhs->coef[i]))
00348 {
00349 EGlpNumCopy (srhs->coef[r], srhs->coef[i]);
00350 srhs->indx[r] = i;
00351 r++;
00352 }
00353 srhs->nzcnt = r;
00354
00355 ILLbasis_column_solve (lp, srhs, ssoln);
00356 for (i = 0; i < ssoln->nzcnt; i++)
00357 EGlpNumCopy (lp->xbz[ssoln->indx[i]], ssoln->coef[i]);
00358 }
00359
00360 void ILLfct_compute_phaseI_piz (
00361 lpinfo * lp)
00362 {
00363 int i, r;
00364 svector *srhs = &(lp->srhs);
00365 svector *ssoln = &(lp->ssoln);
00366
00367 for (i = 0, r = 0; i < lp->nrows; i++)
00368 {
00369 EGlpNumZero (lp->pIpiz[i]);
00370 if (lp->bfeas[i] != 0)
00371 {
00372 srhs->indx[r] = i;
00373 EGlpNumSet (srhs->coef[r], (double) lp->bfeas[i]);
00374 r++;
00375 }
00376 }
00377 srhs->nzcnt = r;
00378
00379 ILLbasis_row_solve (lp, srhs, ssoln);
00380 for (i = 0; i < ssoln->nzcnt; i++)
00381 EGlpNumCopy (lp->pIpiz[ssoln->indx[i]], ssoln->coef[i]);
00382 ILLfct_update_counts (lp, CNT_P1PINZ, ssoln->nzcnt, zeroLpNum);
00383 }
00384
00385 void ILLfct_compute_phaseI_dz (
00386 lpinfo * lp)
00387 {
00388 int i, j;
00389 int col;
00390 int mcnt, mbeg;
00391 EGlpNum_t sum;
00392
00393 EGlpNumInitVar (sum);
00394 ILL_IFTRACE ("%s\n", __func__);
00395
00396 for (j = 0; j < lp->nnbasic; j++)
00397 {
00398 EGlpNumZero (sum);
00399 col = lp->nbaz[j];
00400 mcnt = lp->matcnt[col];
00401 mbeg = lp->matbeg[col];
00402 for (i = 0; i < mcnt; i++)
00403 EGlpNumAddInnProdTo (sum, lp->pIpiz[lp->matind[mbeg + i]],
00404 lp->matval[mbeg + i]);
00405 EGlpNumCopyNeg (lp->pIdz[j], sum);
00406 ILL_IFTRACE ("%d:%d:%lf:%la\n", j, col, EGlpNumToLf (sum),
00407 EGlpNumToLf (sum));
00408 }
00409 EGlpNumClearVar (sum);
00410 }
00411
00412 void ILLfct_compute_yz (
00413 lpinfo * lp,
00414 svector * yz,
00415 svector * updz,
00416 int col)
00417 {
00418 svector a;
00419
00420 a.nzcnt = lp->matcnt[col];
00421 a.indx = &(lp->matind[lp->matbeg[col]]);
00422 a.coef = &(lp->matval[lp->matbeg[col]]);
00423
00424 ILLfactor_set_factor_dparam (lp->f, QS_FACTOR_SZERO_TOL, PIVZ_TOLER);
00425 if (updz)
00426 ILLbasis_column_solve_update (lp, &a, updz, yz);
00427 else
00428 ILLbasis_column_solve (lp, &a, yz);
00429 ILLfactor_set_factor_dparam (lp->f, QS_FACTOR_SZERO_TOL, SZERO_TOLER);
00430 }
00431
00432 void ILLfct_compute_zz (
00433 lpinfo * lp,
00434 svector * zz,
00435 int row)
00436 {
00437 ILLfct_compute_binvrow (lp, zz, row, PIVZ_TOLER);
00438 }
00439
00440 void ILLfct_compute_binvrow (
00441 lpinfo * lp,
00442 svector * zz,
00443 int row,
00444 EGlpNum_t ztoler)
00445 {
00446 svector a;
00447 EGlpNum_t e;
00448
00449 EGlpNumInitVar (e);
00450 EGlpNumOne (e);
00451
00452 a.nzcnt = 1;
00453 a.coef = &e;
00454 a.indx = &row;
00455
00456 if (EGlpNumIsGreatZero (ztoler))
00457 ILLfactor_set_factor_dparam (lp->f, QS_FACTOR_SZERO_TOL, ztoler);
00458 ILLbasis_row_solve (lp, &a, zz);
00459 if (EGlpNumIsGreatZero (ztoler))
00460 ILLfactor_set_factor_dparam (lp->f, QS_FACTOR_SZERO_TOL, SZERO_TOLER);
00461 EGlpNumClearVar (e);
00462 }
00463
00464 void ILLfct_compute_psteep_upv (
00465 lpinfo * lp,
00466 svector * swz)
00467 {
00468 ILLbasis_row_solve (lp, &(lp->yjz), swz);
00469 }
00470
00471 void ILLfct_compute_dsteep_upv (
00472 lpinfo * lp,
00473 svector * swz)
00474 {
00475 ILLbasis_column_solve (lp, &(lp->zz), swz);
00476 }
00477
00478 static int compute_zA1 (
00479 lpinfo * lp,
00480 svector * z,
00481 svector * zA,
00482 EGlpNum_t ztoler)
00483 {
00484 int rval = 0;
00485 int i, j, nz = 0;
00486 int col, mcnt, mbeg;
00487 EGlpNum_t sum;
00488 EGlpNum_t *v = 0;
00489
00490 EGlpNumInitVar (sum);
00491 v = EGlpNumAllocArray (lp->nrows);
00492
00493 for (i = 0; i < lp->nrows; i++)
00494 EGlpNumZero (v[i]);
00495 for (i = 0; i < z->nzcnt; i++)
00496 EGlpNumCopy (v[z->indx[i]], z->coef[i]);
00497
00498 for (j = 0; j < lp->nnbasic; j++)
00499 {
00500 EGlpNumZero (sum);
00501 col = lp->nbaz[j];
00502 mcnt = lp->matcnt[col];
00503 mbeg = lp->matbeg[col];
00504 for (i = 0; i < mcnt; i++)
00505 EGlpNumAddInnProdTo (sum, v[lp->matind[mbeg + i]], lp->matval[mbeg + i]);
00506
00507 if (EGlpNumIsNeqZero (sum, ztoler))
00508 {
00509 EGlpNumCopy (zA->coef[nz], sum);
00510 zA->indx[nz] = j;
00511 nz++;
00512 }
00513 }
00514 zA->nzcnt = nz;
00515
00516 EGlpNumClearVar (sum);
00517 EGlpNumFreeArray (v);
00518 EG_RETURN (rval);
00519 }
00520
00521
00522 static int compute_zA3 (
00523 lpinfo * lp,
00524 svector * z,
00525 svector * zA,
00526 EGlpNum_t ztoler)
00527 {
00528 int rval = 0;
00529 int i, j, k, ix;
00530 int nz = 0;
00531 int row, col;
00532 int rcnt, rbeg;
00533 EGlpNum_t val;
00534
00535 EGlpNumInitVar (val);
00536 k = 0;
00537 for (i = 0; i < z->nzcnt; i++)
00538 {
00539 row = z->indx[i];
00540 EGlpNumCopy (val, z->coef[i]);
00541 rcnt = lp->rowcnt[row];
00542 rbeg = lp->rowbeg[row];
00543 for (j = 0; j < rcnt; j++)
00544 {
00545 col = lp->rowind[rbeg + j];
00546 if (lp->vstat[col] != STAT_BASIC)
00547 {
00548 ix = lp->vindex[col];
00549 if (lp->iwork[ix] == 0)
00550 {
00551 lp->iwork[ix] = 1;
00552 lp->work.indx[k++] = ix;
00553 }
00554 EGlpNumAddInnProdTo (lp->work.coef[ix], val, lp->rowval[rbeg + j]);
00555 }
00556 }
00557 }
00558 for (j = 0; j < k; j++)
00559 {
00560 ix = lp->work.indx[j];
00561 EGlpNumCopy (val, lp->work.coef[ix]);
00562 EGlpNumZero (lp->work.coef[ix]);
00563 lp->iwork[ix] = 0;
00564 if (EGlpNumIsNeqZero (val, ztoler))
00565 {
00566 EGlpNumCopy (zA->coef[nz], val);
00567 zA->indx[nz] = ix;
00568 nz++;
00569 }
00570 }
00571 zA->nzcnt = nz;
00572 EGlpNumClearVar (val);
00573 EG_RETURN (rval);
00574 }
00575
00576 int ILLfct_compute_zA (
00577 lpinfo * lp,
00578 svector * z,
00579 svector * zA)
00580 {
00581 if (z->nzcnt < lp->nrows / 2)
00582 return compute_zA3 (lp, z, zA, PIVZ_TOLER);
00583 else
00584 return compute_zA1 (lp, z, zA, PIVZ_TOLER);
00585 }
00586
00587
00588 void ILLfct_compute_vA (
00589 lpinfo * lp,
00590 svector * v,
00591 EGlpNum_t * vA)
00592 {
00593 int i, j;
00594 int row, col;
00595 int rcnt, rbeg;
00596 EGlpNum_t val;
00597
00598 EGlpNumInitVar (val);
00599
00600 for (j = 0; j < lp->ncols; j++)
00601 EGlpNumZero (vA[j]);
00602
00603 for (i = 0; i < v->nzcnt; i++)
00604 {
00605 row = v->indx[i];
00606 EGlpNumCopy (val, v->coef[i]);
00607 rcnt = lp->rowcnt[row];
00608 rbeg = lp->rowbeg[row];
00609 for (j = 0; j < rcnt; j++)
00610 {
00611 col = lp->rowind[rbeg + j];
00612 EGlpNumAddInnProdTo (vA[col], val, lp->rowval[rbeg + j]);
00613 }
00614 }
00615
00616 for (j = 0; j < lp->ncols; j++)
00617 if (!EGlpNumIsNeqZero (vA[j], SZERO_TOLER))
00618 EGlpNumZero (vA[j]);
00619
00620 EGlpNumClearVar (val);
00621 return;
00622 }
00623
00624
00625
00626
00627
00628
00629 void ILLfct_update_basis_info (
00630 lpinfo * lp,
00631 int eindex,
00632 int lindex,
00633 int lvstat)
00634 {
00635 int evar;
00636 int lvar;
00637
00638 evar = lp->nbaz[eindex];
00639
00640 if (lindex >= 0)
00641 {
00642 lvar = lp->baz[lindex];
00643 lp->vstat[evar] = STAT_BASIC;
00644 lp->vstat[lvar] = lvstat;
00645 lp->vindex[evar] = lindex;
00646 lp->vindex[lvar] = eindex;
00647 lp->baz[lindex] = evar;
00648 lp->nbaz[eindex] = lvar;
00649 (lp->basisid)++;
00650 }
00651 else
00652 {
00653 lp->vstat[evar] = (lp->vstat[evar] == STAT_LOWER) ? STAT_UPPER : STAT_LOWER;
00654 }
00655 }
00656
00657 void ILLfct_update_xz (
00658 lpinfo * lp,
00659 EGlpNum_t tz,
00660 int eindex,
00661 int lindex)
00662 {
00663 int i, evar, estat;
00664
00665 ILL_IFTRACE ("%s:%la:%d:%d:%d\n", __func__, EGlpNumToLf (tz), eindex,
00666 lindex, lp->yjz.nzcnt);
00667
00668 if (EGlpNumIsNeqqZero (tz))
00669 for (i = 0; i < lp->yjz.nzcnt; i++)
00670 EGlpNumSubInnProdTo (lp->xbz[lp->yjz.indx[i]], tz, lp->yjz.coef[i]);
00671
00672 if (lindex >= 0)
00673 {
00674 evar = lp->nbaz[eindex];
00675 estat = lp->vstat[evar];
00676 if (estat == STAT_LOWER)
00677 EGlpNumCopySum (lp->xbz[lindex], lp->lz[evar], tz);
00678 else if (estat == STAT_UPPER)
00679 EGlpNumCopySum (lp->xbz[lindex], lp->uz[evar], tz);
00680 else if (estat == STAT_ZERO)
00681 EGlpNumCopy (lp->xbz[lindex], tz);
00682 }
00683 }
00684
00685 void ILLfct_update_piz (
00686 lpinfo * lp,
00687 EGlpNum_t alpha)
00688 {
00689 int i;
00690
00691 for (i = 0; i < lp->zz.nzcnt; i++)
00692 EGlpNumAddInnProdTo (lp->piz[lp->zz.indx[i]], alpha, lp->zz.coef[i]);
00693 }
00694
00695 void ILLfct_update_pIpiz (
00696 lpinfo * lp,
00697 svector * z,
00698 const EGlpNum_t alpha)
00699 {
00700 int i;
00701
00702 if (!EGlpNumIsNeqqZero (alpha))
00703 return;
00704 if (EGlpNumIsEqqual (alpha, oneLpNum))
00705 {
00706 for (i = 0; i < z->nzcnt; i++)
00707 EGlpNumAddTo (lp->pIpiz[z->indx[i]], z->coef[i]);
00708 }
00709 else
00710 {
00711 for (i = 0; i < z->nzcnt; i++)
00712 EGlpNumAddInnProdTo (lp->pIpiz[z->indx[i]], alpha, z->coef[i]);
00713 }
00714 }
00715
00716 void ILLfct_update_dz (
00717 lpinfo * lp,
00718 int eindex,
00719 EGlpNum_t alpha)
00720 {
00721 int i;
00722
00723 for (i = 0; i < lp->zA.nzcnt; i++)
00724 EGlpNumSubInnProdTo (lp->dz[lp->zA.indx[i]], alpha, lp->zA.coef[i]);
00725 EGlpNumCopyNeg (lp->dz[eindex], alpha);
00726 }
00727
00728 void ILLfct_update_pIdz (
00729 lpinfo * lp,
00730 svector * zA,
00731 int eindex,
00732 const EGlpNum_t alpha)
00733 {
00734 int i;
00735
00736 if (!EGlpNumIsNeqqZero (alpha))
00737 return;
00738
00739 if (EGlpNumIsEqqual (alpha, oneLpNum))
00740 {
00741 for (i = 0; i < zA->nzcnt; i++)
00742 EGlpNumSubTo (lp->pIdz[zA->indx[i]], zA->coef[i]);
00743 }
00744 else
00745 {
00746 for (i = 0; i < zA->nzcnt; i++)
00747 EGlpNumSubInnProdTo (lp->pIdz[zA->indx[i]], alpha, zA->coef[i]);
00748 }
00749 if (eindex > -1)
00750 EGlpNumCopyNeg (lp->pIdz[eindex], alpha);
00751 }
00752
00753
00754
00755
00756 static double my_rand (
00757 int bound,
00758 ILLrandstate * r)
00759 {
00760 int k = bound, scale = 1;
00761 double v = 0.0;
00762
00763 if (bound < 100000)
00764 {
00765 k = 20000 * bound;
00766 scale = 20000;
00767 }
00768 v = 1 + (ILLutil_lprand (r) % (k));
00769 return v / (double) scale;
00770 }
00771
00772 static int expand_var_bounds (
00773 lpinfo * lp,
00774 EGlpNum_t ftol,
00775 int *chgb)
00776 {
00777 int rval = 0;
00778 int i, col, nchg = 0;
00779 EGlpNum_t newb, cftol;
00780 EGlpNum_t *x, *l, *u;
00781 ILLrandstate r;
00782
00783 EGlpNumInitVar (newb);
00784 EGlpNumInitVar (cftol);
00785 EGlpNumCopyAbs (cftol, ftol);
00786 EGlpNumDivUiTo (cftol, 10);
00787
00788 ILLutil_sprand (1, &r);
00789
00790 for (i = 0; i < lp->nrows; i++)
00791 {
00792 col = lp->baz[i];
00793 if (lp->vtype[col] == VARTIFICIAL || lp->vtype[col] == VFREE)
00794 continue;
00795 x = &(lp->xbz[i]);
00796 l = &(lp->lz[col]);
00797 u = &(lp->uz[col]);
00798
00799 EGlpNumCopyDiff (newb, *x, ftol);
00800 if (EGlpNumIsNeqq (*l, NINFTY) && EGlpNumIsLess (newb, *l))
00801 {
00802 EGlpNumSet (newb, -1.0 * (my_rand (50, &(lp->rstate)) + 1.0));
00803 EGlpNumMultTo (newb, cftol);
00804 if (EGlpNumIsLess (*x, *l))
00805 EGlpNumAddTo (newb, *x);
00806 else
00807 EGlpNumAddTo (newb, *l);
00808 rval = ILLfct_bound_shift (lp, col, BOUND_LOWER, newb);
00809 CHECKRVALG (rval, CLEANUP);
00810 nchg++;
00811 }
00812 EGlpNumCopySum (newb, *x, ftol);
00813 if (EGlpNumIsNeqq (*u, INFTY) && EGlpNumIsLess (*u, newb))
00814 {
00815 EGlpNumSet (newb, my_rand (50, &(lp->rstate)) + 1.0);
00816 EGlpNumMultTo (newb, cftol);
00817 if (EGlpNumIsLess (*x, *u))
00818 EGlpNumAddTo (newb, *u);
00819 else
00820 EGlpNumAddTo (newb, *x);
00821 rval = ILLfct_bound_shift (lp, col, BOUND_UPPER, newb);
00822 CHECKRVALG (rval, CLEANUP);
00823 nchg++;
00824 }
00825 }
00826 *chgb = nchg;
00827
00828 CLEANUP:
00829 EGlpNumClearVar (newb);
00830 EGlpNumClearVar (cftol);
00831 EG_RETURN (rval);
00832 }
00833
00834 static int expand_phaseI_bounds (
00835 lpinfo * lp,
00836 int *chgb)
00837 {
00838 int rval = 0;
00839 int i, col, nchg = 0;
00840 EGlpNum_t newb, cftol;
00841 EGlpNum_t *u, *l, *x;
00842 ILLrandstate r;
00843
00844 EGlpNumInitVar (newb);
00845 EGlpNumInitVar (cftol);
00846 EGlpNumCopyAbs (cftol, lp->tol->ip_tol);
00847 EGlpNumDivUiTo (cftol, 10);
00848 ILLutil_sprand (1, &r);
00849
00850 for (i = 0; i < lp->nrows; i++)
00851 {
00852 col = lp->baz[i];
00853 if (lp->vtype[col] == VARTIFICIAL || lp->vtype[col] == VFREE)
00854 continue;
00855 x = &(lp->xbz[i]);
00856 l = &(lp->lz[col]);
00857 u = &(lp->uz[col]);
00858
00859 if (EGlpNumIsNeqq (*l, NINFTY) && EGlpNumIsEqual (*x, *l, cftol))
00860 {
00861 EGlpNumSet (newb, my_rand (50, &(lp->rstate)) + 1.0);
00862 EGlpNumMultTo (newb, cftol);
00863 EGlpNumSign (newb);
00864 EGlpNumAddTo (newb, *l);
00865 rval = ILLfct_bound_shift (lp, col, BOUND_LOWER, newb);
00866 CHECKRVALG (rval, CLEANUP);
00867 nchg++;
00868 }
00869 if (EGlpNumIsNeqq (*u, INFTY) && EGlpNumIsEqual (*x, *u, cftol))
00870 {
00871 EGlpNumSet (newb, my_rand (50, &(lp->rstate)) + 1.0);
00872 EGlpNumMultTo (newb, cftol);
00873 EGlpNumAddTo (newb, *u);
00874 rval = ILLfct_bound_shift (lp, col, BOUND_UPPER, newb);
00875 CHECKRVALG (rval, CLEANUP);
00876 nchg++;
00877 }
00878 }
00879 *chgb = nchg;
00880
00881 CLEANUP:
00882 EGlpNumClearVar (newb);
00883 EGlpNumClearVar (cftol);
00884 EG_RETURN (rval);
00885 }
00886
00887 int ILLfct_adjust_viol_bounds (
00888 lpinfo * lp)
00889 {
00890 int rval = 0;
00891 int chgb = 0;
00892 EGlpNum_t tol;
00893
00894 EGlpNumInitVar (tol);
00895 EGlpNumCopyNeg (tol, lp->tol->pfeas_tol);
00896 rval = expand_var_bounds (lp, tol, &chgb);
00897 #if FCT_DEBUG > 0
00898 if (rval == 0)
00899 printf ("adjusting %d bounds\n", chgb);
00900 #endif
00901 EGlpNumClearVar (tol);
00902 EG_RETURN (rval);
00903 }
00904
00905 int ILLfct_perturb_bounds (
00906 lpinfo * lp)
00907 {
00908 int rval = 0;
00909 int chgb = 0;
00910
00911 rval = expand_var_bounds (lp, lp->tol->ip_tol, &chgb);
00912 #if FCT_DEBUG > 0
00913 if (rval == 0)
00914 printf ("perturbing %d bounds\n", chgb);
00915 #endif
00916 EG_RETURN (rval);
00917 }
00918
00919 int ILLfct_perturb_phaseI_bounds (
00920 lpinfo * lp)
00921 {
00922 int rval = 0;
00923 int chgb = 0;
00924
00925 rval = expand_phaseI_bounds (lp, &chgb);
00926 #if FCT_DEBUG > 0
00927 if (rval == 0)
00928 printf ("perturbing %d phase I bounds\n", chgb);
00929 #endif
00930 EG_RETURN (rval);
00931 }
00932
00933 int ILLfct_bound_shift (
00934 lpinfo * lp,
00935 int col,
00936 int bndtype,
00937 EGlpNum_t newbnd)
00938 {
00939 int rval = 0;
00940 bndinfo *nbnd = 0;
00941
00942 ILL_IFTRACE ("\n%s:%d:%d:%la", __func__, col, bndtype, EGlpNumToLf (newbnd));
00943 nbnd = ILLfct_new_bndinfo ();
00944
00945 nbnd->varnum = col;
00946 nbnd->btype = bndtype;
00947 if (bndtype == BOUND_LOWER)
00948 {
00949 EGlpNumCopy (nbnd->pbound, lp->lz[col]);
00950 EGlpNumCopy (nbnd->cbound, newbnd);
00951 EGlpNumCopy (lp->lz[col], newbnd);
00952 }
00953 else
00954 {
00955 EGlpNumCopy (nbnd->pbound, lp->uz[col]);
00956 EGlpNumCopy (nbnd->cbound, newbnd);
00957 EGlpNumCopy (lp->uz[col], newbnd);
00958 }
00959 ILL_IFTRACE (":%la", EGlpNumToLf (nbnd->pbound));
00960 if (lp->vtype[col] == VFIXED || lp->vtype[col] == VARTIFICIAL)
00961 {
00962
00963 if (EGlpNumIsLess (lp->lz[col], lp->uz[col]))
00964 lp->vtype[col] = VBOUNDED;
00965 }
00966
00967 nbnd->next = lp->bchanges;
00968 lp->bchanges = nbnd;
00969 lp->nbchange++;
00970
00971
00972 if (rval)
00973 ILLfct_free_bndinfo (nbnd);
00974 ILL_IFTRACE ("\n");
00975 EG_RETURN (rval);
00976 }
00977
00978 void ILLfct_unroll_bound_change (
00979 lpinfo * lp)
00980 {
00981 int col;
00982 int changex = 0;
00983 bndinfo *bptr = lp->bchanges;
00984 bndinfo *nptr = 0;
00985
00986 ILL_IFTRACE ("%s:", __func__);
00987
00988 while (lp->nbchange != 0)
00989 {
00990 col = bptr->varnum;
00991 ILL_IFTRACE (":%d", col);
00992
00993 if (bptr->btype == BOUND_UPPER)
00994 EGlpNumCopy (lp->uz[col], bptr->pbound);
00995 else
00996 EGlpNumCopy (lp->lz[col], bptr->pbound);
00997
00998 if (lp->vtype[col] == VBOUNDED)
00999 {
01000 if (EGlpNumIsEqqual (lp->lz[col], lp->uz[col]))
01001 lp->vtype[col] = (!EGlpNumIsNeqqZero (lp->lz[col])) ?
01002 VARTIFICIAL : VFIXED;
01003 }
01004
01005 if (lp->vstat[col] != STAT_BASIC)
01006 {
01007 if ((bptr->btype == BOUND_UPPER && lp->vstat[col] == STAT_UPPER) ||
01008 (bptr->btype == BOUND_LOWER && lp->vstat[col] == STAT_LOWER))
01009 changex++;
01010 }
01011 nptr = bptr->next;
01012 EGlpNumClearVar ((bptr->cbound));
01013 EGlpNumClearVar ((bptr->pbound));
01014 ILL_IFFREE (bptr, bndinfo);
01015 bptr = nptr;
01016 lp->nbchange--;
01017 }
01018 lp->bchanges = bptr;
01019 ILL_IFTRACE ("\n");
01020 if (changex)
01021 ILLfct_compute_xbz (lp);
01022 }
01023
01024 static int expand_var_coefs (
01025 lpinfo * lp,
01026 EGlpNum_t ftol,
01027 int *chgc)
01028 {
01029 int rval = 0;
01030 int i, col, vs, vt;
01031 int nchg = 0;
01032 EGlpNum_t newc, cftol, mftol[1];
01033 EGlpNum_t *c, *dj;
01034 ILLrandstate r;
01035
01036 EGlpNumInitVar (newc);
01037 EGlpNumInitVar (cftol);
01038 EGlpNumInitVar (mftol[0]);
01039 EGlpNumCopyAbs (cftol, ftol);
01040 EGlpNumDivUiTo (cftol, 10);
01041 EGlpNumCopyNeg (mftol[0], ftol);
01042 ILLutil_sprand (1, &r);
01043
01044 for (i = 0; i < lp->nnbasic; i++)
01045 {
01046 dj = &(lp->dz[i]);
01047 col = lp->nbaz[i];
01048 c = &(lp->cz[col]);
01049 vs = lp->vstat[col];
01050 vt = lp->vtype[col];
01051
01052 if (vt == VARTIFICIAL || vt == VFIXED)
01053 continue;
01054 switch (vs)
01055 {
01056 case STAT_ZERO:
01057 EGlpNumCopyDiff (newc, *c, *dj);
01058 rval = ILLfct_coef_shift (lp, col, newc);
01059 CHECKRVALG (rval, CLEANUP);
01060 nchg++;
01061 break;
01062 case STAT_LOWER:
01063 if (EGlpNumIsLess (*dj, ftol))
01064 {
01065 EGlpNumSet (newc, my_rand (50, &(lp->rstate)) + 1.0);
01066 EGlpNumMultTo (newc, cftol);
01067 EGlpNumAddTo (newc, *c);
01068 if (EGlpNumIsLessZero (*dj))
01069 EGlpNumSubTo (newc, *dj);
01070 rval = ILLfct_coef_shift (lp, col, newc);
01071 CHECKRVALG (rval, CLEANUP);
01072 nchg++;
01073 }
01074 break;
01075 case STAT_UPPER:
01076 if (EGlpNumIsLess (mftol[0], *dj))
01077 {
01078 EGlpNumSet (newc, my_rand (50, &(lp->rstate)) + 1.0);
01079 EGlpNumMultTo (newc, cftol);
01080 EGlpNumSign (newc);
01081 EGlpNumAddTo (newc, *c);
01082 if (EGlpNumIsGreatZero (*dj))
01083 EGlpNumSubTo (newc, *dj);
01084 rval = ILLfct_coef_shift (lp, col, newc);
01085 CHECKRVALG (rval, CLEANUP);
01086 nchg++;
01087 }
01088 break;
01089 default:
01090 break;
01091 }
01092 }
01093 *chgc = nchg;
01094
01095 CLEANUP:
01096 EGlpNumClearVar (mftol[0]);
01097 EGlpNumClearVar (newc);
01098 EGlpNumClearVar (cftol);
01099 EG_RETURN (rval);
01100 }
01101
01102 int ILLfct_adjust_viol_coefs (
01103 lpinfo * lp)
01104 {
01105 int rval = 0;
01106 int chgc = 0;
01107 EGlpNum_t tol;
01108
01109 EGlpNumInitVar (tol);
01110 EGlpNumCopyNeg (tol, lp->tol->dfeas_tol);
01111
01112 rval = expand_var_coefs (lp, tol, &chgc);
01113 #if FCT_DEBUG > 0
01114 if (rval == 0)
01115 printf ("perturbing %d coefs\n", chgc);
01116 #endif
01117 EGlpNumClearVar (tol);
01118 EG_RETURN (rval);
01119 }
01120
01121 int ILLfct_perturb_coefs (
01122 lpinfo * lp)
01123 {
01124 int rval = 0;
01125 int chgc = 0;
01126
01127 rval = expand_var_coefs (lp, lp->tol->id_tol, &chgc);
01128 #if FCT_DEBUG > 0
01129 if (rval == 0)
01130 printf ("perturbing %d coefs\n", chgc);
01131 #endif
01132 EG_RETURN (rval);
01133 }
01134
01135 int ILLfct_coef_shift (
01136 lpinfo * lp,
01137 int col,
01138 EGlpNum_t newcoef)
01139 {
01140 int rval = 0;
01141 coefinfo *ncoef = 0;
01142
01143 ILL_SAFE_MALLOC (ncoef, 1, coefinfo);
01144 EGlpNumInitVar ((ncoef->pcoef));
01145 EGlpNumInitVar ((ncoef->ccoef));
01146
01147 ncoef->varnum = col;
01148 EGlpNumCopy (ncoef->pcoef, lp->cz[col]);
01149 EGlpNumCopy (ncoef->ccoef, newcoef);
01150 EGlpNumCopy (lp->cz[col], newcoef);
01151 ncoef->next = lp->cchanges;
01152 lp->cchanges = ncoef;
01153 EGlpNumAddTo (lp->dz[lp->vindex[col]], ncoef->ccoef);
01154 EGlpNumSubTo (lp->dz[lp->vindex[col]], ncoef->pcoef);
01155 lp->ncchange++;
01156
01157 CLEANUP:
01158 if (rval)
01159 {
01160 EGlpNumClearVar ((ncoef->pcoef));
01161 EGlpNumClearVar ((ncoef->ccoef));
01162 ILL_IFFREE (ncoef, coefinfo);
01163 }
01164 EG_RETURN (rval);
01165 }
01166
01167 void ILLfct_unroll_coef_change (
01168 lpinfo * lp)
01169 {
01170 int bascoef = 0;
01171 coefinfo *cptr = (coefinfo *) lp->cchanges;
01172 coefinfo *nptr = 0;
01173
01174 while (lp->ncchange != 0)
01175 {
01176 EGlpNumCopy (lp->cz[cptr->varnum], cptr->pcoef);
01177 if (lp->vstat[cptr->varnum] != STAT_BASIC)
01178 {
01179 EGlpNumAddTo (lp->dz[lp->vindex[cptr->varnum]], cptr->pcoef);
01180 EGlpNumSubTo (lp->dz[lp->vindex[cptr->varnum]], cptr->ccoef);
01181 }
01182 else
01183 bascoef++;
01184
01185 nptr = cptr->next;
01186 EGlpNumClearVar ((cptr->pcoef));
01187 EGlpNumClearVar ((cptr->ccoef));
01188 ILL_IFFREE (cptr, coefinfo);
01189 cptr = nptr;
01190 lp->ncchange--;
01191 }
01192 lp->cchanges = cptr;
01193 if (bascoef)
01194 {
01195 ILLfct_compute_piz (lp);
01196 ILLfct_compute_dz (lp);
01197 }
01198 }
01199
01200
01201 void ILLfct_check_pfeasible (
01202 lpinfo * lp,
01203 feas_info * fs,
01204 const EGlpNum_t ftol)
01205 {
01206 int i, col;
01207 EGlpNum_t infeas, err1, err2;
01208
01209 EGlpNumInitVar (infeas);
01210 EGlpNumInitVar (err1);
01211 EGlpNumInitVar (err2);
01212 EGlpNumZero (infeas);
01213 fs->pstatus = PRIMAL_FEASIBLE;
01214 EGlpNumZero (fs->totinfeas);
01215 ILL_IFTRACE ("%s:tol %la\n", __func__, EGlpNumToLf (ftol));
01216
01217 for (i = 0; i < lp->nrows; i++)
01218 {
01219 col = lp->baz[i];
01220 EGlpNumCopyDiff (err1, lp->xbz[i], lp->uz[col]);
01221 EGlpNumCopyDiff (err2, lp->lz[col], lp->xbz[i]);
01222 if (EGlpNumIsLess (ftol, err1)
01223 && EGlpNumIsNeq (lp->uz[col], INFTY, oneLpNum))
01224 {
01225 EGlpNumAddTo (infeas, err1);
01226 WARNINGL (QSE_WLVL, EGlpNumIsLess (INFTY, err1),
01227 "This is imposible lu = %15lg xbz = %15lg" " INFTY = %15lg",
01228 EGlpNumToLf (lp->uz[col]), EGlpNumToLf (lp->xbz[i]),
01229 EGlpNumToLf (INFTY));
01230 lp->bfeas[i] = 1;
01231 }
01232 else if (EGlpNumIsLess (ftol, err2)
01233 && EGlpNumIsNeq (lp->lz[col], NINFTY, oneLpNum))
01234 {
01235 EGlpNumAddTo (infeas, err2);
01236 WARNINGL (QSE_WLVL, EGlpNumIsLess (INFTY, err2),
01237 "This is imposible lz = %15lg xbz = %15lg" " NINFTY = %15lg",
01238 EGlpNumToLf (lp->lz[col]), EGlpNumToLf (lp->xbz[i]),
01239 EGlpNumToLf (NINFTY));
01240 lp->bfeas[i] = -1;
01241 }
01242 else
01243 lp->bfeas[i] = 0;
01244 }
01245 if (EGlpNumIsNeqqZero (infeas))
01246 {
01247 fs->pstatus = PRIMAL_INFEASIBLE;
01248 EGlpNumCopy (fs->totinfeas, infeas);
01249 ILL_IFTRACE ("%s:inf %la\n", __func__, EGlpNumToLf (infeas));
01250 if (EGlpNumIsLessZero (fs->totinfeas))
01251 {
01252 printf ("Negative infeasibility, Imposible! %lf %la\n",
01253 EGlpNumToLf (infeas), EGlpNumToLf (infeas));
01254 }
01255 }
01256 EGlpNumCopy (lp->pinfeas, infeas);
01257 EGlpNumClearVar (infeas);
01258 EGlpNumClearVar (err1);
01259 EGlpNumClearVar (err2);
01260 }
01261
01262
01263 void ILLfct_check_pIpfeasible (
01264 lpinfo * lp,
01265 feas_info * fs,
01266 EGlpNum_t ftol)
01267 {
01268 int i, col;
01269 int ninf = 0;
01270
01271 fs->pstatus = PRIMAL_FEASIBLE;
01272 EGlpNumZero (fs->totinfeas);
01273
01274 for (i = 0; i < lp->nrows; i++)
01275 {
01276 if (!EGlpNumIsNeqZero (lp->xbz[i], ftol))
01277 continue;
01278 col = lp->baz[i];
01279 if (EGlpNumIsGreatZero(lp->xbz[i]) &&
01280 EGlpNumIsNeqq (lp->uz[col], INFTY))
01281 {
01282 ninf++;
01283 }
01284 else if (EGlpNumIsLessZero (lp->xbz[i]) &&
01285 EGlpNumIsNeqq (lp->lz[col], NINFTY))
01286 {
01287 ninf++;
01288 }
01289 }
01290 if (ninf != 0)
01291 fs->pstatus = PRIMAL_INFEASIBLE;
01292 }
01293
01294 void ILLfct_check_dfeasible (
01295 lpinfo * lp,
01296 feas_info * fs,
01297 const EGlpNum_t ftol)
01298 {
01299 int j, col;
01300 EGlpNum_t infeas;
01301
01302 EGlpNumInitVar (infeas);
01303 EGlpNumZero (infeas);
01304 fs->dstatus = DUAL_FEASIBLE;
01305 EGlpNumZero (fs->totinfeas);
01306
01307 for (j = 0; j < lp->nnbasic; j++)
01308 {
01309 lp->dfeas[j] = 0;
01310 if (!EGlpNumIsNeqZero (lp->dz[j], ftol))
01311 continue;
01312 col = lp->nbaz[j];
01313
01314 if (lp->vtype[col] == VARTIFICIAL || lp->vtype[col] == VFIXED)
01315 continue;
01316
01317 if (EGlpNumIsLessZero (lp->dz[j]) &&
01318 (lp->vstat[col] == STAT_LOWER || lp->vstat[col] == STAT_ZERO))
01319 {
01320 EGlpNumSubTo (infeas, lp->dz[j]);
01321 lp->dfeas[j] = -1;
01322 }
01323 else if (EGlpNumIsGreatZero (lp->dz[j]) &&
01324 (lp->vstat[col] == STAT_UPPER || lp->vstat[col] == STAT_ZERO))
01325 {
01326 EGlpNumAddTo (infeas, lp->dz[j]);
01327 lp->dfeas[j] = 1;
01328 }
01329 }
01330
01331 if (EGlpNumIsNeqqZero (infeas))
01332 {
01333 EGlpNumCopy (fs->totinfeas, infeas);
01334 fs->dstatus = DUAL_INFEASIBLE;
01335 ILL_IFTRACE ("%s:inf %la\n", __func__, EGlpNumToLf (infeas));
01336 if (EGlpNumIsLessZero (fs->totinfeas))
01337 {
01338 printf ("Negative infeasibility, Imposible! %lf %la\n",
01339 EGlpNumToLf (infeas), EGlpNumToLf (infeas));
01340 }
01341 }
01342 EGlpNumCopy (lp->dinfeas, infeas);
01343 EGlpNumClearVar (infeas);
01344 }
01345
01346 void ILLfct_check_pIdfeasible (
01347 lpinfo * lp,
01348 feas_info * fs,
01349 EGlpNum_t ftol)
01350 {
01351 int j, col;
01352 int ninf = 0;
01353 EGlpNum_t *dz = lp->pIdz;
01354
01355 fs->dstatus = DUAL_FEASIBLE;
01356
01357 for (j = 0; j < lp->nnbasic; j++)
01358 {
01359 if (!EGlpNumIsNeqZero (dz[j], ftol))
01360 continue;
01361 col = lp->nbaz[j];
01362 if (lp->vtype[col] == VARTIFICIAL || lp->vtype[col] == VFIXED)
01363 continue;
01364
01365 if (EGlpNumIsLessZero (dz[j]) &&
01366 (lp->vstat[col] == STAT_LOWER || lp->vstat[col] == STAT_ZERO))
01367 ninf++;
01368 else if (EGlpNumIsGreatZero (dz[j]) &&
01369 (lp->vstat[col] == STAT_UPPER || lp->vstat[col] == STAT_ZERO))
01370 ninf++;
01371 }
01372
01373 if (ninf != 0)
01374 fs->dstatus = DUAL_INFEASIBLE;
01375 }
01376
01377 void ILLfct_dual_adjust (
01378 lpinfo * lp,
01379 const EGlpNum_t ftol)
01380 {
01381 int j, col;
01382
01383 for (j = 0; j < lp->nnbasic; j++)
01384 {
01385 if (!EGlpNumIsNeqZero (lp->dz[j], ftol))
01386 continue;
01387 col = lp->nbaz[j];
01388 if (EGlpNumIsLessZero (lp->dz[j]) &&
01389 EGlpNumIsNeqq (lp->uz[col], INFTY))
01390 lp->vstat[col] = STAT_UPPER;
01391 else if (EGlpNumIsGreatZero (lp->dz[j]) &&
01392 EGlpNumIsNeqq (lp->lz[col], NINFTY))
01393 lp->vstat[col] = STAT_LOWER;
01394 }
01395 }
01396
01397 void ILLfct_dphaseI_simple_update (
01398 lpinfo * lp,
01399 EGlpNum_t ftol)
01400 {
01401 int j, col;
01402
01403 for (j = 0; j < lp->nnbasic; j++)
01404 {
01405 if (!EGlpNumIsNeqZero (lp->dz[j], ftol))
01406 continue;
01407 col = lp->nbaz[j];
01408 if (EGlpNumIsLessZero (lp->dz[j] ) && lp->vtype[col] == VBOUNDED)
01409 lp->vstat[col] = STAT_UPPER;
01410 else if (EGlpNumIsGreatZero (lp->dz[j]) && lp->vtype[col] == VBOUNDED)
01411 lp->vstat[col] = STAT_LOWER;
01412 }
01413 }
01414
01415
01416 void ILLfct_set_status_values (
01417 lpinfo * lp,
01418 int pstatus,
01419 int dstatus,
01420 int ptype,
01421 int dtype)
01422 {
01423 if (dstatus == DUAL_FEASIBLE && dtype == PHASEII)
01424 {
01425 if (!lp->ncchange)
01426 {
01427 lp->probstat.dual_feasible = 1;
01428 lp->basisstat.dual_feasible = 1;
01429 lp->basisstat.dual_infeasible = 0;
01430 }
01431 }
01432 if (dstatus == DUAL_INFEASIBLE && dtype == PHASEII)
01433 {
01434 if (!lp->ncchange)
01435 {
01436 lp->basisstat.dual_feasible = 0;
01437 lp->basisstat.dual_infeasible = 1;
01438 }
01439 if (pstatus == PRIMAL_FEASIBLE && ptype == PHASEI)
01440 if (!lp->ncchange)
01441 lp->probstat.dual_infeasible = 1;
01442 }
01443 if (pstatus == PRIMAL_FEASIBLE && ptype == PHASEII)
01444 {
01445 if (!lp->nbchange)
01446 {
01447 lp->probstat.primal_feasible = 1;
01448 lp->basisstat.primal_feasible = 1;
01449 lp->basisstat.primal_infeasible = 0;
01450 }
01451 }
01452 if (pstatus == PRIMAL_INFEASIBLE && ptype == PHASEII)
01453 {
01454 lp->basisstat.primal_feasible = 0;
01455 lp->basisstat.primal_infeasible = 1;
01456
01457 if (dstatus == DUAL_FEASIBLE && dtype == PHASEI)
01458 lp->probstat.primal_infeasible = 1;
01459 }
01460 if (pstatus == PRIMAL_UNBOUNDED)
01461 {
01462 if (!lp->nbchange)
01463 {
01464 lp->probstat.primal_unbounded = 1;
01465 lp->basisstat.primal_unbounded = 1;
01466 lp->probstat.dual_infeasible = 1;
01467 lp->basisstat.dual_infeasible = 1;
01468 lp->basisstat.dual_feasible = 0;
01469 }
01470 }
01471 if (dstatus == DUAL_UNBOUNDED)
01472 {
01473 if (!lp->ncchange)
01474 {
01475 lp->probstat.dual_unbounded = 1;
01476 lp->basisstat.dual_unbounded = 1;
01477 lp->probstat.primal_infeasible = 1;
01478 lp->basisstat.primal_infeasible = 1;
01479 lp->basisstat.primal_feasible = 0;
01480 }
01481 }
01482 if (lp->probstat.primal_feasible && lp->probstat.dual_feasible)
01483 lp->probstat.optimal = 1;
01484
01485 if (lp->basisstat.primal_feasible && lp->basisstat.dual_feasible)
01486 lp->basisstat.optimal = 1;
01487 else
01488 lp->basisstat.optimal = 0;
01489 }
01490
01491 void ILLfct_init_counts (
01492 lpinfo * lp)
01493 {
01494 int i;
01495 count_struct *c = lp->cnts;
01496
01497 #define C_VALUE(a) (1.0+(double)(a)/(PARAM_HEAP_RATIO*ILLutil_our_log2(a)))
01498 EGlpNumSet (c->y_ravg, C_VALUE (lp->nrows));
01499 EGlpNumSet (c->za_ravg, C_VALUE (lp->nnbasic));
01500 ILL_IFTRACE ("%s:%la\n", __func__, EGlpNumToLf (c->za_ravg));
01501 #undef C_VALUE
01502 c->ynz_cnt = 0;
01503 c->num_y = 0;
01504 c->znz_cnt = 0;
01505 c->num_z = 0;
01506 c->zanz_cnt = 0;
01507 c->num_za = 0;
01508 c->pnorm_cnt = 0;
01509 c->dnorm_cnt = 0;
01510 c->pinz_cnt = 0;
01511 c->num_pi = 0;
01512 c->pi1nz_cnt = 0;
01513 c->num_pi1 = 0;
01514 c->upnz_cnt = 0;
01515 c->num_up = 0;
01516 c->pupv_cnt = 0;
01517 c->dupv_cnt = 0;
01518 c->pI_iter = 0;
01519 c->pII_iter = 0;
01520 c->dI_iter = 0;
01521 c->dII_iter = 0;
01522 c->tot_iter = 0;
01523 for (i = 0; i < 10; i++)
01524 {
01525 c->pivpI[i] = 0;
01526 c->pivpII[i] = 0;
01527 c->pivdI[i] = 0;
01528 c->pivdII[i] = 0;
01529 }
01530 }
01531
01532 static void update_piv_values (
01533 count_struct * c,
01534 int phase,
01535 const EGlpNum_t piv2)
01536 {
01537 int i = 0;
01538 EGlpNum_t v, piv;
01539
01540 if (!EGlpNumIsNeqqZero(piv2))
01541 return;
01542 EGlpNumInitVar (v);
01543 EGlpNumInitVar (piv);
01544 EGlpNumCopyAbs (piv, piv2);
01545 EGlpNumOne (v);
01546 while (EGlpNumIsLess (piv, v) && i < 9)
01547 {
01548 EGlpNumDivUiTo (v, 10);
01549 i++;
01550 }
01551 switch (phase)
01552 {
01553 case PRIMAL_PHASEI:
01554 c->pivpI[i]++;
01555 break;
01556 case PRIMAL_PHASEII:
01557 c->pivpII[i]++;
01558 break;
01559 case DUAL_PHASEI:
01560 c->pivdI[i]++;
01561 break;
01562 case DUAL_PHASEII:
01563 c->pivdII[i]++;
01564 break;
01565 default:
01566 break;
01567 }
01568 EGlpNumClearVar (v);
01569 EGlpNumClearVar (piv);
01570 }
01571
01572 void ILLfct_update_counts (
01573 lpinfo * lp,
01574 int f,
01575 int upi,
01576 const EGlpNum_t upd)
01577 {
01578 count_struct *c = lp->cnts;
01579
01580 switch (f)
01581 {
01582 case CNT_PPHASE1ITER:
01583 c->pI_iter++;
01584 c->tot_iter++;
01585 break;
01586 case CNT_PPHASE2ITER:
01587 c->pII_iter++;
01588 c->tot_iter++;
01589 break;
01590 case CNT_DPHASE1ITER:
01591 c->dI_iter++;
01592 c->tot_iter++;
01593 break;
01594 case CNT_DPHASE2ITER:
01595 c->dII_iter++;
01596 c->tot_iter++;
01597 break;
01598 case CNT_YNZ:
01599 c->ynz_cnt += upi;
01600 c->num_y++;
01601 break;
01602 case CNT_ZANZ:
01603 c->zanz_cnt += upi;
01604 c->num_za++;
01605 break;
01606 case CNT_PINZ:
01607 c->pinz_cnt += upi;
01608 c->num_pi++;
01609 break;
01610 case CNT_P1PINZ:
01611 c->pi1nz_cnt += upi;
01612 c->num_pi1++;
01613 break;
01614 case CNT_UPNZ:
01615 c->upnz_cnt += upi;
01616 c->num_up++;
01617 break;
01618 case CNT_PIPIV:
01619 update_piv_values (c, PRIMAL_PHASEI, upd);
01620 break;
01621 case CNT_PIIPIV:
01622 update_piv_values (c, PRIMAL_PHASEII, upd);
01623 break;
01624 case CNT_DIPIV:
01625 update_piv_values (c, DUAL_PHASEI, upd);
01626 break;
01627 case CNT_DIIPIV:
01628 update_piv_values (c, DUAL_PHASEII, upd);
01629 break;
01630 case CNT_YRAVG:
01631 EGlpNumMultUiTo (c->y_ravg, c->tot_iter);
01632 EGlpNumAddUiTo (c->y_ravg, upi);
01633 EGlpNumDivUiTo (c->y_ravg, c->tot_iter + 1);
01634 break;
01635 case CNT_ZARAVG:
01636 ILL_IFTRACE ("%s:%d:%d:%d:%la:%la", __func__, f, c->tot_iter, upi,
01637 EGlpNumToLf (upd), EGlpNumToLf (c->za_ravg));
01638 EGlpNumMultUiTo (c->za_ravg, c->tot_iter);
01639 EGlpNumAddUiTo (c->za_ravg, upi);
01640 EGlpNumDivUiTo (c->za_ravg, c->tot_iter + 1);
01641 ILL_IFTRACE (":%la\n", EGlpNumToLf (c->za_ravg));
01642 break;
01643 }
01644 }
01645
01646 void ILLfct_print_counts (
01647 lpinfo * lp)
01648 {
01649 int i, niter;
01650 count_struct *c = lp->cnts;
01651
01652 c->tot_iter = c->pI_iter + c->pII_iter + c->dI_iter + c->dII_iter;
01653 niter = (c->tot_iter == 0) ? 1 : c->tot_iter;
01654 printf ("Counts for problem %s\n", lp->O->probname);
01655 if (c->num_y != 0)
01656 printf ("avg ynz = %.2f\n", (double) c->ynz_cnt / c->num_y);
01657 if (c->num_z != 0)
01658 printf ("avg znz = %.2f\n", (double) c->znz_cnt / c->num_z);
01659 if (c->num_za != 0)
01660 printf ("avg zanz = %.2f\n", (double) c->zanz_cnt / c->num_za);
01661 printf ("avg pnorm = %.2f\n", (double) c->pnorm_cnt / lp->nnbasic);
01662 printf ("avg dnorm = %.2f\n", (double) c->dnorm_cnt / lp->nrows);
01663 if (c->num_pi != 0)
01664 printf ("avg pinz = %.2f\n", (double) c->pinz_cnt / c->num_pi);
01665 if (c->num_pi1 != 0)
01666 printf ("avg piInz = %.2f\n", (double) c->pi1nz_cnt / c->num_pi1);
01667 if (c->num_up != 0)
01668 printf ("avg upnz = %.2f\n", (double) c->upnz_cnt / c->num_up);
01669
01670 for (i = 0; i < 10; i++)
01671 printf ("piv 1.0e-%d : %d %d %d %d\n",
01672 i, c->pivpI[i], c->pivpII[i], c->pivdI[i], c->pivdII[i]);
01673 }
01674
01675
01676
01677 static void add_vectors (
01678 lpinfo * lp,
01679 svector * a,
01680 svector * b,
01681 svector * c,
01682 const EGlpNum_t t)
01683 {
01684 int i, r, l;
01685 svector *w = &(lp->work);
01686
01687 for (i = 0; i < b->nzcnt; i++)
01688 {
01689 r = b->indx[i];
01690 w->indx[i] = r;
01691 EGlpNumCopy (w->coef[r], t);
01692 EGlpNumMultTo (w->coef[r], b->coef[i]);
01693 lp->iwork[r] = 1;
01694 }
01695 l = b->nzcnt;
01696
01697 for (i = 0; i < a->nzcnt; i++)
01698 {
01699 r = a->indx[i];
01700 if (lp->iwork[r] == 0)
01701 w->indx[l++] = r;
01702 EGlpNumAddTo (w->coef[r], a->coef[i]);
01703 }
01704 for (i = 0; i < l; i++)
01705 {
01706 r = w->indx[i];
01707 c->indx[i] = r;
01708 EGlpNumCopy (c->coef[i], w->coef[r]);
01709 EGlpNumZero (w->coef[r]);
01710 lp->iwork[r] = 0;
01711 }
01712 w->nzcnt = 0;
01713 c->nzcnt = l;
01714 }
01715
01716 void ILLfct_update_pfeas (
01717 lpinfo * lp,
01718 int lindex,
01719 svector * srhs)
01720 {
01721 int i, k, r;
01722 int col, nz = 0;
01723 int cbnd, f;
01724 int *perm = lp->upd.perm;
01725 int *ix = lp->upd.ix;
01726 int tctr = lp->upd.tctr;
01727 EGlpNum_t *t = lp->upd.t;
01728 EGlpNum_t tz, *dty, ntmp;
01729 EGlpNum_t *l, *x, *u, *pftol = &(lp->tol->ip_tol);
01730
01731 EGlpNumInitVar (tz);
01732 EGlpNumInitVar (ntmp);
01733 dty = &(lp->upd.dty);
01734 EGlpNumZero (*dty);
01735 EGlpNumCopyAbs (tz, lp->upd.tz);
01736 EGlpNumDivUiTo (tz, 100);
01737 EGlpNumAddTo (tz, lp->upd.tz);
01738 ILL_IFTRACE ("%s:%d", __func__, tctr);
01739 for (i = 0; i < tctr && EGlpNumIsLeq (t[perm[i]], tz); i++)
01740 {
01741 cbnd = ix[perm[i]] % 10;
01742 ILL_IFTRACE (":%d", cbnd);
01743 if (cbnd == BBOUND)
01744 continue;
01745 k = ix[perm[i]] / 10;
01746 r = lp->yjz.indx[k];
01747 ILL_IFTRACE (":%d:%d:%d", k, r, lp->iwork[r]);
01748
01749 if (lp->iwork[r] != 1)
01750 {
01751 lp->iwork[r] = 1;
01752 x = &(lp->xbz[r]);
01753 col = lp->baz[r];
01754 l = &(lp->lz[col]);
01755 u = &(lp->uz[col]);
01756
01757 if (r != lindex)
01758 {
01759 f = 0;
01760 EGlpNumCopyDiff (ntmp, *l, *x);
01761 if (EGlpNumIsNeqq (*l, NINFTY) && EGlpNumIsLess (*pftol, ntmp))
01762 f = -1;
01763 else
01764 {
01765 EGlpNumCopyDiff (ntmp, *x, *u);
01766 if (EGlpNumIsNeqq (*u, INFTY) && EGlpNumIsLess (*pftol, ntmp))
01767 f = 1;
01768 }
01769
01770 ILL_IFTRACE (":%d:%d", f, lp->bfeas[r]);
01771 if (f != lp->bfeas[r])
01772 {
01773 srhs->indx[nz] = r;
01774 EGlpNumSet (srhs->coef[nz], (double) (f - lp->bfeas[r]));
01775 EGlpNumAddInnProdTo (*dty, srhs->coef[nz], lp->yjz.coef[k]);
01776 nz++;
01777 lp->bfeas[r] = f;
01778 }
01779 }
01780 else
01781 {
01782 lp->bfeas[r] = 0;
01783 }
01784 }
01785 }
01786 while (--i >= 0)
01787 {
01788 cbnd = ix[perm[i]] % 10;
01789 if (cbnd == BBOUND)
01790 continue;
01791 k = ix[perm[i]] / 10;
01792 r = lp->yjz.indx[k];
01793 lp->iwork[r] = 0;
01794 }
01795 srhs->nzcnt = nz;
01796 ILL_IFTRACE (":%d\n", nz);
01797 EGlpNumClearVar (tz);
01798 EGlpNumClearVar (ntmp);
01799 }
01800
01801 void ILLfct_compute_ppIzz (
01802 lpinfo * lp,
01803 svector * srhs,
01804 svector * ssoln)
01805 {
01806 if (srhs->nzcnt != 0)
01807 {
01808 ILL_IFTRACE ("%s:\n", __func__);
01809 ILLbasis_row_solve (lp, srhs, ssoln);
01810 }
01811 }
01812
01813 void ILLfct_update_ppI_prices (
01814 lpinfo * lp,
01815 price_info * pinf,
01816 svector * srhs,
01817 svector * ssoln,
01818 int eindex,
01819 int lindex,
01820 const EGlpNum_t alpha)
01821 {
01822 EGlpNum_t ntmp;
01823
01824 EGlpNumInitVar (ntmp);
01825 EGlpNumCopy (ntmp, alpha);
01826 ILL_IFTRACE ("%s:\n", __func__);
01827 if (lindex == -1)
01828 {
01829 if (srhs->nzcnt != 0)
01830 {
01831 ILLfct_update_pIpiz (lp, ssoln, oneLpNum);
01832 if (pinf->p_strategy == COMPLETE_PRICING)
01833 {
01834 ILLfct_compute_zA (lp, ssoln, &(lp->zA));
01835 ILLfct_update_pIdz (lp, &(lp->zA), -1, oneLpNum);
01836 }
01837 }
01838 else
01839 {
01840 if (pinf->p_strategy == COMPLETE_PRICING)
01841 ILLprice_compute_dual_inf (lp, pinf, &eindex, 1, PRIMAL_PHASEI);
01842 else
01843 ILLprice_update_mpartial_price (lp, pinf, PRIMAL_PHASEI, COL_PRICING);
01844 EGlpNumClearVar (ntmp);
01845 return;
01846 }
01847 }
01848 else
01849 {
01850 if (srhs->nzcnt == 0)
01851 {
01852 ILLfct_update_pIpiz (lp, &(lp->zz), ntmp);
01853 if (pinf->p_strategy == COMPLETE_PRICING)
01854 ILLfct_update_pIdz (lp, &(lp->zA), eindex, ntmp);
01855 }
01856 else
01857 {
01858 EGlpNumCopyFrac (ntmp, lp->upd.dty, lp->upd.piv);
01859 EGlpNumSubTo (ntmp, alpha);
01860 EGlpNumSign (ntmp);
01861 add_vectors (lp, ssoln, &(lp->zz), &(lp->zz), ntmp);
01862 ILLfct_update_pIpiz (lp, &(lp->zz), oneLpNum);
01863 if (pinf->p_strategy == COMPLETE_PRICING)
01864 {
01865 ILLfct_compute_zA (lp, &(lp->zz), &(lp->zA));
01866 ILLfct_update_pIdz (lp, &(lp->zA), eindex, oneLpNum);
01867 }
01868 }
01869 EGlpNumSet (lp->pIdz[eindex], (double) (lp->upd.fs));
01870 EGlpNumAddTo (lp->pIdz[eindex], ntmp);
01871 EGlpNumSign (lp->pIdz[eindex]);
01872 }
01873 if (pinf->p_strategy == COMPLETE_PRICING)
01874 {
01875 ILLprice_compute_dual_inf (lp, pinf, lp->zA.indx, lp->zA.nzcnt,
01876 PRIMAL_PHASEI);
01877 if (eindex > -1)
01878 ILLprice_compute_dual_inf (lp, pinf, &eindex, 1, PRIMAL_PHASEI);
01879 ILLfct_update_counts (lp, CNT_ZARAVG, lp->zA.nzcnt, zeroLpNum);
01880 }
01881 else
01882 ILLprice_update_mpartial_price (lp, pinf, PRIMAL_PHASEI, COL_PRICING);
01883 EGlpNumClearVar (ntmp);
01884 return;
01885 }
01886
01887 void ILLfct_update_dfeas (
01888 lpinfo * lp,
01889 int eindex,
01890 svector * srhs)
01891 {
01892 int i, j, k, c;
01893 int cbnd, col, nz = 0;
01894 int vs, vt, f;
01895 int delta;
01896 int *perm = lp->upd.perm;
01897 int *ix = lp->upd.ix;
01898 int tctr = lp->upd.tctr;
01899 int mcnt, mbeg;
01900 EGlpNum_t *t = lp->upd.t;
01901 EGlpNum_t *w = lp->work.coef;
01902 EGlpNum_t tz;
01903 EGlpNum_t *dty = &(lp->upd.dty);
01904 EGlpNum_t *dftol = &(lp->tol->id_tol);
01905 EGlpNum_t dj;
01906
01907 EGlpNumInitVar (dj);
01908 EGlpNumInitVar (tz);
01909 EGlpNumZero (*dty);
01910 EGlpNumCopy (tz, lp->upd.tz);
01911 EGlpNumMultUiTo (tz, 101);
01912 EGlpNumDivUiTo (tz, 100);
01913
01914 for (j = 0; j < tctr && EGlpNumIsLeq (t[perm[j]], tz); j++)
01915 {
01916 k = ix[perm[j]] / 10;
01917 c = lp->zA.indx[k];
01918
01919 if (lp->iwork[c] != 1)
01920 {
01921 lp->iwork[c] = 1;
01922 cbnd = ix[perm[j]] % 10;
01923 col = lp->nbaz[c];
01924 EGlpNumCopy (dj, lp->dz[c]);
01925 vs = lp->vstat[col];
01926 vt = lp->vtype[col];
01927
01928 if (cbnd == BSKIP)
01929 {
01930 if (!EGlpNumIsNeqZero (dj, *dftol));
01931 else if (EGlpNumIsLessZero (dj) && vs == STAT_LOWER)
01932 lp->vstat[col] = STAT_UPPER;
01933 else if (EGlpNumIsGreatZero (dj) && vs == STAT_UPPER)
01934 lp->vstat[col] = STAT_LOWER;
01935 }
01936 else if (c != eindex)
01937 {
01938 if (!EGlpNumIsNeqZero (dj, *dftol))
01939 f = 0;
01940 else if (EGlpNumIsLessZero (dj) &&
01941 (vs == STAT_LOWER || vs == STAT_ZERO))
01942 f = -1;
01943 else if (EGlpNumIsGreatZero (dj) &&
01944 (vs == STAT_UPPER || vs == STAT_ZERO))
01945 f = 1;
01946 else
01947 f = 0;
01948
01949 if (f != lp->dfeas[c])
01950 {
01951 delta = f - lp->dfeas[c];
01952 mcnt = lp->matcnt[col];
01953 mbeg = lp->matbeg[col];
01954 EGlpNumSet (dj, (double) (delta));
01955 for (i = 0; i < mcnt; i++)
01956 EGlpNumAddInnProdTo (w[lp->matind[mbeg + i]], dj,
01957 lp->matval[mbeg + i]);
01958 EGlpNumAddInnProdTo (*dty, dj, lp->zA.coef[k]);
01959 nz = 1;
01960 lp->dfeas[c] = f;
01961 }
01962 }
01963 else
01964 {
01965 lp->dfeas[c] = 0;
01966 }
01967 }
01968 }
01969 while (--j >= 0)
01970 {
01971 k = ix[perm[j]] / 10;
01972 c = lp->zA.indx[k];
01973 lp->iwork[c] = 0;
01974 }
01975
01976 if (nz)
01977 {
01978 for (i = 0, nz = 0; i < lp->nrows; i++)
01979 if (EGlpNumIsNeqqZero (w[i]))
01980 {
01981 EGlpNumCopy (srhs->coef[nz], w[i]);
01982 srhs->indx[nz] = i;
01983 nz++;
01984 EGlpNumZero (w[i]);
01985 }
01986 }
01987
01988 srhs->nzcnt = nz;
01989 EGlpNumClearVar (dj);
01990 EGlpNumClearVar (tz);
01991 }
01992
01993 void ILLfct_compute_dpIy (
01994 lpinfo * lp,
01995 svector * srhs,
01996 svector * ssoln)
01997 {
01998 if (srhs->nzcnt != 0)
01999 {
02000 ILLbasis_column_solve (lp, srhs, ssoln);
02001 }
02002 }
02003
02004 void ILLfct_update_dpI_prices (
02005 lpinfo * lp,
02006 price_info * pinf,
02007 svector * srhs,
02008 svector * ssoln,
02009 int lindex,
02010 EGlpNum_t alpha)
02011 {
02012 int i;
02013 EGlpNum_t ntmp;
02014
02015 EGlpNumInitVar (ntmp);
02016 EGlpNumZero (ntmp);
02017
02018 if (srhs->nzcnt == 0)
02019 {
02020 ILLfct_update_xz (lp, alpha, -1, -1);
02021 }
02022 else
02023 {
02024 EGlpNumCopyFrac (ntmp, lp->upd.dty, lp->upd.piv);
02025 EGlpNumAddTo (ntmp, alpha);
02026 EGlpNumSign (ntmp);
02027 add_vectors (lp, ssoln, &(lp->yjz), &(lp->yjz), ntmp);
02028 EGlpNumSign (ntmp);
02029 for (i = 0; i < lp->yjz.nzcnt; i++)
02030 EGlpNumAddTo (lp->xbz[lp->yjz.indx[i]], lp->yjz.coef[i]);
02031 }
02032 EGlpNumSet (lp->xbz[lindex], ((double) (-lp->upd.fs)));
02033 EGlpNumAddTo (lp->xbz[lindex], ntmp);
02034
02035 if (pinf->d_strategy == COMPLETE_PRICING)
02036 {
02037 ILLprice_compute_primal_inf (lp, pinf, lp->yjz.indx, lp->yjz.nzcnt,
02038 DUAL_PHASEI);
02039 ILLprice_compute_primal_inf (lp, pinf, &lindex, 1, DUAL_PHASEI);
02040 ILLfct_update_counts (lp, CNT_YRAVG, lp->yjz.nzcnt, zeroLpNum);
02041 }
02042 else
02043 ILLprice_update_mpartial_price (lp, pinf, DUAL_PHASEI, ROW_PRICING);
02044 EGlpNumClearVar (ntmp);
02045 }
02046
02047 void ILLfct_update_dIIfeas (
02048 lpinfo * lp,
02049 int eindex,
02050 svector * srhs)
02051 {
02052 int j, k;
02053 int col, indx, vs;
02054 int *perm = lp->upd.perm;
02055 int *ix = lp->upd.ix;
02056 int tctr = lp->upd.tctr;
02057 EGlpNum_t *zAj, *l, *u;
02058 EGlpNum_t *dty = &(lp->upd.dty);
02059 EGlpNum_t *t_max = &(lp->upd.tz);
02060 EGlpNum_t *t = lp->upd.t;
02061 EGlpNum_t delta;
02062 svector a;
02063
02064 EGlpNumInitVar (delta);
02065 EGlpNumZero (delta);
02066 EGlpNumZero (*dty);
02067
02068 srhs->nzcnt = 0;
02069 for (j = 0; j < tctr && EGlpNumIsLeq (t[perm[j]], *t_max); j++)
02070 {
02071 k = ix[perm[j]];
02072 indx = lp->zA.indx[k];
02073
02074 if (indx != eindex)
02075 {
02076 zAj = &(lp->zA.coef[k]);
02077 col = lp->nbaz[indx];
02078 l = &(lp->lz[col]);
02079 u = &(lp->uz[col]);
02080 vs = lp->vstat[col];
02081 if (vs == STAT_UPPER)
02082 EGlpNumCopyDiff (delta, *l, *u);
02083 else
02084 EGlpNumCopyDiff (delta, *u, *l);
02085 EGlpNumAddInnProdTo (*dty, delta, *zAj);
02086 lp->vstat[col] = (vs == STAT_UPPER) ? STAT_LOWER : STAT_UPPER;
02087
02088 a.nzcnt = lp->matcnt[col];
02089 a.indx = &(lp->matind[lp->matbeg[col]]);
02090 a.coef = &(lp->matval[lp->matbeg[col]]);
02091 add_vectors (lp, srhs, &a, srhs, delta);
02092 }
02093 }
02094 EGlpNumClearVar (delta);
02095 }
02096
02097 void ILLfct_compute_dpIIy (
02098 lpinfo * lp,
02099 svector * srhs,
02100 svector * ssoln)
02101 {
02102 if (srhs->nzcnt != 0)
02103 {
02104 ILLbasis_column_solve (lp, srhs, ssoln);
02105 }
02106 }
02107
02108 void ILLfct_update_dpII_prices (
02109 lpinfo * lp,
02110 price_info * pinf,
02111 svector * srhs,
02112 svector * ssoln,
02113
02114 int lindex,
02115 EGlpNum_t eval,
02116 EGlpNum_t alpha)
02117 {
02118 int i;
02119 svector *u;
02120
02121 if (srhs->nzcnt == 0)
02122 {
02123 ILLfct_update_xz (lp, alpha, -1, -1);
02124 u = &(lp->yjz);
02125 }
02126 else
02127 {
02128 if (ssoln->nzcnt != 0)
02129 for (i = 0; i < ssoln->nzcnt; i++)
02130 EGlpNumSubTo (lp->xbz[ssoln->indx[i]], ssoln->coef[i]);
02131 ILLfct_update_xz (lp, alpha, -1, -1);
02132 add_vectors (lp, ssoln, &(lp->yjz), ssoln, oneLpNum);
02133 u = ssoln;
02134 }
02135 EGlpNumCopySum (lp->xbz[lindex], eval, alpha);
02136
02137 if (pinf->d_strategy == COMPLETE_PRICING)
02138 {
02139 ILLprice_compute_primal_inf (lp, pinf, u->indx, u->nzcnt, DUAL_PHASEII);
02140 ILLprice_compute_primal_inf (lp, pinf, &lindex, 1, DUAL_PHASEII);
02141 ILLfct_update_counts (lp, CNT_YRAVG, u->nzcnt, zeroLpNum);
02142 }
02143 else
02144 ILLprice_update_mpartial_price (lp, pinf, DUAL_PHASEII, ROW_PRICING);
02145 }
02146
02147 int ILLfct_test_pivot (
02148 lpinfo * lp,
02149 int indx,
02150 int indxtype,
02151 EGlpNum_t piv_val)
02152 {
02153 int i;
02154 EGlpNum_t pval, ntmp;
02155
02156 EGlpNumInitVar (pval);
02157 EGlpNumInitVar (ntmp);
02158 EGlpNumZero (pval);
02159
02160 if (indxtype == ROW_PIVOT)
02161 {
02162 for (i = 0; i < lp->yjz.nzcnt; i++)
02163 if (lp->yjz.indx[i] == indx)
02164 {
02165 EGlpNumCopy (pval, lp->yjz.coef[i]);
02166 break;
02167 }
02168 }
02169 else
02170 {
02171 for (i = 0; i < lp->zA.nzcnt; i++)
02172 if (lp->zA.indx[i] == indx)
02173 {
02174 EGlpNumCopy (pval, lp->zA.coef[i]);
02175 break;
02176 }
02177 }
02178 EGlpNumCopyDiff (ntmp, pval, piv_val);
02179 EGlpNumDivTo (ntmp, piv_val);
02180 if (EGlpNumIsLessZero (ntmp))
02181 EGlpNumSign (ntmp);
02182 if (EGlpNumIsLess (ALTPIV_TOLER, ntmp))
02183 {
02184 #if FCT_DEBUG > 1
02185 if (indxtype == ROW_PIVOT)
02186 printf ("y_i = %.8f, z_j = %.8f %la %la\n", EGlpNumToLf (pval),
02187 EGlpNumToLf (piv_val), EGlpNumToLf (ALTPIV_TOLER),
02188 EGlpNumToLf (ntmp));
02189 else
02190 printf ("z_j = %.8f, y_i = %.8f\n", EGlpNumToLf (pval),
02191 EGlpNumToLf (piv_val));
02192 #endif
02193 EGlpNumClearVar (ntmp);
02194 EGlpNumClearVar (pval);
02195 return 1;
02196 }
02197 EGlpNumClearVar (pval);
02198 EGlpNumClearVar (ntmp);
02199 return 0;
02200 }
02201
02202 #if FCT_DEBUG > 0
02203
02204 void fct_test_workvector (
02205 lpinfo * lp)
02206 {
02207 int i, err = 0;
02208
02209 for (i = 0; i < lp->ncols; i++)
02210 {
02211 if (EGlpNumIsNeqqZero (lp->work.coef[i]))
02212 {
02213 err++;
02214 EGlpNumZero (lp->work.coef[i]);
02215 }
02216 if (lp->iwork[i] != 0)
02217 {
02218 err++;
02219 lp->iwork[i] = 0;
02220 }
02221 }
02222 if (err)
02223 printf ("bad work vector, err=%d\n", err);
02224 }
02225
02226 void fct_test_pfeasible (
02227 lpinfo * lp)
02228 {
02229 int i, col;
02230 int err = 0;
02231 EGlpNum_t *ftol = &(lp->tol->pfeas_tol);
02232
02233 for (i = 0; i < lp->nrows; i++)
02234 {
02235 col = lp->baz[i];
02236
02237 if (EGlpNumIsNeqq (lp->uz[col], INFTY)
02238 && EGlpNumIsSumLess (*ftol, lp->uz[col], lp->xbz[i]))
02239 {
02240 if (lp->bfeas[i] != 1)
02241 {
02242 err++;
02243 lp->bfeas[i] = 1;
02244 }
02245 }
02246 else if (EGlpNumIsNeqq (lp->lz[col], NINFTY)
02247 && EGlpNumIsSumLess (lp->xbz[i], *ftol, lp->lz[col]))
02248 {
02249 if (lp->bfeas[i] != -1)
02250 {
02251 err++;
02252 lp->bfeas[i] = -1;
02253 }
02254 }
02255
02256 }
02257 if (err != 0)
02258 printf ("test_pfeas err =%d\n", err);
02259 }
02260
02261 void fct_test_dfeasible (
02262 lpinfo * lp)
02263 {
02264 int j, col;
02265 int err = 0;
02266 EGlpNum_t *ftol = &(lp->tol->dfeas_tol);
02267 EGlpNum_t mftol[1];
02268
02269 EGlpNumInitVar (mftol[0]);
02270 EGlpNumCopyNeg (mftol[0], *ftol);
02271
02272 for (j = 0; j < lp->nnbasic; j++)
02273 {
02274 col = lp->nbaz[j];
02275
02276 if (lp->vtype[col] == VARTIFICIAL || lp->vtype[col] == VFIXED)
02277 continue;
02278 if (EGlpNumIsLess (lp->dz[j], mftol[0]) &&
02279 (lp->vstat[col] == STAT_LOWER || lp->vstat[col] == STAT_ZERO))
02280 {
02281 if (lp->dfeas[j] != -1)
02282 {
02283 err++;
02284 lp->dfeas[j] = -1;
02285 }
02286 }
02287 if (EGlpNumIsLess (*ftol, lp->dz[j]) &&
02288 (lp->vstat[col] == STAT_UPPER || lp->vstat[col] == STAT_ZERO))
02289 {
02290 if (lp->dfeas[j] != 1)
02291 {
02292 err++;
02293 lp->dfeas[j] = 1;
02294 }
02295 }
02296
02297 }
02298 if (err != 0)
02299 printf ("test_dfeas err =%d\n", err);
02300 }
02301
02302 void fct_test_pI_x (
02303 lpinfo * lp,
02304 price_info * p)
02305 {
02306 int i;
02307 int ern = 0;
02308 EGlpNum_t *x;
02309 EGlpNum_t err, diff;
02310
02311 EGlpNumInitVar (err);
02312 EGlpNumInitVar (diff);
02313 EGlpNumZero (err);
02314 x = EGlpNumAllocArray (lp->nrows);
02315
02316 for (i = 0; i < lp->nrows; i++)
02317 EGlpNumCopy (x[i], lp->xbz[i]);
02318 ILLfct_compute_phaseI_xbz (lp);
02319 for (i = 0; i < lp->nrows; i++)
02320 {
02321 EGlpNumCopyDiff (diff, x[i], lp->xbz[i]);
02322 if (EGlpNumIsLessZero (diff))
02323 EGlpNumSign (diff);
02324 if (EGlpNumIsLess (PFEAS_TOLER, diff))
02325 {
02326 EGlpNumAddTo (err, diff);
02327 ern++;
02328 printf ("bad i = %d\n", i);
02329 }
02330 }
02331 if (EGlpNumIsNeqqZero (err))
02332 printf ("dI x err = %.7f, ern = %d\n", EGlpNumToLf (err), ern);
02333 ILLprice_compute_primal_inf (lp, p, NULL, 0, DUAL_PHASEI);
02334 EGlpNumFreeArray (x);
02335 EGlpNumClearVar (diff);
02336 EGlpNumClearVar (err);
02337 }
02338
02339 void fct_test_pII_x (
02340 lpinfo * lp,
02341 price_info * p)
02342 {
02343 int i;
02344 int ern = 0;
02345 EGlpNum_t *x;
02346 EGlpNum_t err, diff;
02347
02348 EGlpNumInitVar (err);
02349 EGlpNumInitVar (diff);
02350 EGlpNumZero (err);
02351 x = EGlpNumAllocArray (lp->nrows);
02352
02353 for (i = 0; i < lp->nrows; i++)
02354 EGlpNumCopy (x[i], lp->xbz[i]);
02355 ILLfct_compute_xbz (lp);
02356 for (i = 0; i < lp->nrows; i++)
02357 {
02358 EGlpNumCopyDiff (diff, x[i], lp->xbz[i]);
02359 if (EGlpNumIsLessZero (diff ))
02360 EGlpNumSign (diff);
02361 if (EGlpNumIsLess (PFEAS_TOLER, diff))
02362 {
02363 EGlpNumAddTo (err, diff);
02364 ern++;
02365 printf ("bad i = %d\n", i);
02366 }
02367 }
02368 if (EGlpNumIsNeqqZero (err))
02369 printf ("dII x err = %.7f, ern = %d\n", EGlpNumToLf (err), ern);
02370 ILLprice_compute_primal_inf (lp, p, NULL, 0, DUAL_PHASEII);
02371 EGlpNumFreeArray (x);
02372 EGlpNumClearVar (diff);
02373 EGlpNumClearVar (err);
02374 }
02375
02376 void fct_test_pI_pi_dz (
02377 lpinfo * lp,
02378 price_info * p)
02379 {
02380 int i;
02381 int ern = 0;
02382 EGlpNum_t *pidz;
02383 EGlpNum_t err, diff;
02384
02385 EGlpNumInitVar (err);
02386 EGlpNumInitVar (diff);
02387 pidz = EGlpNumAllocArray (lp->ncols);
02388 EGlpNumZero (err);
02389
02390 for (i = 0; i < lp->nrows; i++)
02391 EGlpNumCopy (pidz[i], lp->pIpiz[i]);
02392 ILLfct_compute_phaseI_piz (lp);
02393 for (i = 0; i < lp->nrows; i++)
02394 {
02395 EGlpNumCopyDiff (diff, pidz[i], lp->pIpiz[i]);
02396 if (EGlpNumIsLessZero (diff))
02397 EGlpNumSign (diff);
02398 if (EGlpNumIsLess (DFEAS_TOLER, diff))
02399 {
02400 EGlpNumAddTo (err, diff);
02401 ern++;
02402 }
02403 }
02404 if (EGlpNumIsNeqqZero (err))
02405 printf ("pI pi err = %.7f, ern = %d\n", EGlpNumToLf (err), ern);
02406
02407 EGlpNumZero (err);
02408 ern = 0;
02409 for (i = 0; i < lp->nnbasic; i++)
02410 EGlpNumCopy (pidz[i], lp->pIdz[i]);
02411 ILLfct_compute_phaseI_dz (lp);
02412 for (i = 0; i < lp->nnbasic; i++)
02413 {
02414 EGlpNumCopyDiff (diff, pidz[i], lp->pIdz[i]);
02415 if (EGlpNumIsLessZero (diff))
02416 EGlpNumSign (diff);
02417 if (EGlpNumIsLess (DFEAS_TOLER, diff))
02418 {
02419 EGlpNumAddTo (err, diff);
02420 ern++;
02421 }
02422 }
02423 if (EGlpNumIsNeqqZero (err))
02424 printf ("pI dz err = %.7f, ern = %d\n", EGlpNumToLf (err), ern);
02425 ILLprice_compute_dual_inf (lp, p, NULL, 0, PRIMAL_PHASEI);
02426 EGlpNumClearVar (err);
02427 EGlpNumClearVar (diff);
02428 EGlpNumFreeArray (pidz);
02429 }
02430
02431 void fct_test_pII_pi_dz (
02432 lpinfo * lp,
02433 price_info * p)
02434 {
02435 int i;
02436 int ern = 0;
02437 EGlpNum_t *pidz;
02438 EGlpNum_t err, diff;
02439
02440 EGlpNumInitVar (err);
02441 EGlpNumInitVar (diff);
02442 EGlpNumZero (err);
02443 pidz = EGlpNumAllocArray (lp->ncols);
02444
02445 for (i = 0; i < lp->nrows; i++)
02446 EGlpNumCopy (pidz[i], lp->piz[i]);
02447 ILLfct_compute_piz (lp);
02448 for (i = 0; i < lp->nrows; i++)
02449 {
02450 EGlpNumCopyDiff (diff, pidz[i], lp->piz[i]);
02451 if (EGlpNumIsLessZero (diff))
02452 EGlpNumSign (diff);
02453 if (EGlpNumIsLess (DFEAS_TOLER, diff))
02454 {
02455 EGlpNumAddTo (err, diff);
02456 ern++;
02457 }
02458 }
02459 if (EGlpNumIsNeqqZero (err))
02460 printf ("pII pi err = %.7f, ern = %d\n", EGlpNumToLf (err), ern);
02461
02462 EGlpNumZero (err);
02463 ern = 0;
02464 for (i = 0; i < lp->nnbasic; i++)
02465 EGlpNumCopy (pidz[i], lp->dz[i]);
02466 ILLfct_compute_dz (lp);
02467 for (i = 0; i < lp->nnbasic; i++)
02468 {
02469 EGlpNumCopyDiff (diff, pidz[i], lp->dz[i]);
02470 if (EGlpNumIsLessZero (diff))
02471 EGlpNumSign (diff);
02472 if (EGlpNumIsLess (DFEAS_TOLER, diff))
02473 {
02474 EGlpNumAddTo (err, diff);
02475 ern++;
02476 }
02477 }
02478 if (EGlpNumIsNeqqZero (err))
02479 printf ("pII dz err = %.7f, ern = %d\n", EGlpNumToLf (err), ern);
02480
02481
02482
02483 EGlpNumClearVar (err);
02484 EGlpNumClearVar (diff);
02485 EGlpNumFreeArray (pidz);
02486 }
02487
02488 #endif