00001
00002
00003
00004 #include "CoinPragma.hpp"
00005 #include "ClpSimplex.hpp"
00006 #include "ClpDualRowSteepest.hpp"
00007 #include "CoinIndexedVector.hpp"
00008 #include "ClpFactorization.hpp"
00009 #include "CoinHelperFunctions.hpp"
00010 #include <cstdio>
00011
00012
00013
00014
00015
00016
00017
00018
00019 ClpDualRowSteepest::ClpDualRowSteepest (int mode)
00020 : ClpDualRowPivot(),
00021 state_(-1),
00022 mode_(mode),
00023 weights_(NULL),
00024 infeasible_(NULL),
00025 alternateWeights_(NULL),
00026 savedWeights_(NULL),
00027 dubiousWeights_(NULL)
00028 {
00029 type_=2+64*mode;
00030 }
00031
00032
00033
00034
00035 ClpDualRowSteepest::ClpDualRowSteepest (const ClpDualRowSteepest & rhs)
00036 : ClpDualRowPivot(rhs)
00037 {
00038 state_=rhs.state_;
00039 mode_ = rhs.mode_;
00040 model_ = rhs.model_;
00041 if (rhs.infeasible_) {
00042 infeasible_= new CoinIndexedVector(rhs.infeasible_);
00043 } else {
00044 infeasible_=NULL;
00045 }
00046 if (rhs.weights_) {
00047 assert(model_);
00048 int number = model_->numberRows();
00049 weights_= new double[number];
00050 ClpDisjointCopyN(rhs.weights_,number,weights_);
00051 } else {
00052 weights_=NULL;
00053 }
00054 if (rhs.alternateWeights_) {
00055 alternateWeights_= new CoinIndexedVector(rhs.alternateWeights_);
00056 } else {
00057 alternateWeights_=NULL;
00058 }
00059 if (rhs.savedWeights_) {
00060 savedWeights_= new CoinIndexedVector(rhs.savedWeights_);
00061 } else {
00062 savedWeights_=NULL;
00063 }
00064 if (rhs.dubiousWeights_) {
00065 assert(model_);
00066 int number = model_->numberRows();
00067 dubiousWeights_= new int[number];
00068 ClpDisjointCopyN(rhs.dubiousWeights_,number,dubiousWeights_);
00069 } else {
00070 dubiousWeights_=NULL;
00071 }
00072 }
00073
00074
00075
00076
00077 ClpDualRowSteepest::~ClpDualRowSteepest ()
00078 {
00079 delete [] weights_;
00080 delete [] dubiousWeights_;
00081 delete infeasible_;
00082 delete alternateWeights_;
00083 delete savedWeights_;
00084 }
00085
00086
00087
00088
00089 ClpDualRowSteepest &
00090 ClpDualRowSteepest::operator=(const ClpDualRowSteepest& rhs)
00091 {
00092 if (this != &rhs) {
00093 ClpDualRowPivot::operator=(rhs);
00094 state_=rhs.state_;
00095 mode_ = rhs.mode_;
00096 model_ = rhs.model_;
00097 delete [] weights_;
00098 delete [] dubiousWeights_;
00099 delete infeasible_;
00100 delete alternateWeights_;
00101 delete savedWeights_;
00102 if (rhs.infeasible_!=NULL) {
00103 infeasible_= new CoinIndexedVector(rhs.infeasible_);
00104 } else {
00105 infeasible_=NULL;
00106 }
00107 if (rhs.weights_!=NULL) {
00108 assert(model_);
00109 int number = model_->numberRows();
00110 weights_= new double[number];
00111 ClpDisjointCopyN(rhs.weights_,number,weights_);
00112 } else {
00113 weights_=NULL;
00114 }
00115 if (rhs.alternateWeights_!=NULL) {
00116 alternateWeights_= new CoinIndexedVector(rhs.alternateWeights_);
00117 } else {
00118 alternateWeights_=NULL;
00119 }
00120 if (rhs.savedWeights_!=NULL) {
00121 savedWeights_= new CoinIndexedVector(rhs.savedWeights_);
00122 } else {
00123 savedWeights_=NULL;
00124 }
00125 if (rhs.dubiousWeights_) {
00126 assert(model_);
00127 int number = model_->numberRows();
00128 dubiousWeights_= new int[number];
00129 ClpDisjointCopyN(rhs.dubiousWeights_,number,dubiousWeights_);
00130 } else {
00131 dubiousWeights_=NULL;
00132 }
00133 }
00134 return *this;
00135 }
00136
00137
00138 int
00139 ClpDualRowSteepest::pivotRow()
00140 {
00141 assert(model_);
00142 int i,iRow;
00143 double * infeas = infeasible_->denseVector();
00144 double largest=1.0e-50;
00145 int * index = infeasible_->getIndices();
00146 int number = infeasible_->getNumElements();
00147 const int * pivotVariable =model_->pivotVariable();
00148 int chosenRow=-1;
00149 int lastPivotRow = model_->pivotRow();
00150 double tolerance=model_->currentPrimalTolerance();
00151
00152
00153 double error = min(1.0e-3,model_->largestPrimalError());
00154
00155 tolerance = tolerance + error;
00156
00157 tolerance = min(1000.0,tolerance);
00158 tolerance *= tolerance;
00159 double * solution = model_->solutionRegion();
00160 double * lower = model_->lowerRegion();
00161 double * upper = model_->upperRegion();
00162
00163
00164
00165 if (lastPivotRow>=0) {
00166 #ifdef COLUMN_BIAS
00167 int numberColumns = model_->numberColumns();
00168 #endif
00169 int iPivot=pivotVariable[lastPivotRow];
00170 double value = solution[iPivot];
00171 double lower = model_->lower(iPivot);
00172 double upper = model_->upper(iPivot);
00173 if (value>upper+tolerance) {
00174 value -= upper;
00175 value *= value;
00176 #ifdef COLUMN_BIAS
00177 if (iPivot<numberColumns)
00178 value *= COLUMN_BIAS;
00179 k
00180 #endif
00181
00182 if (infeas[lastPivotRow])
00183 infeas[lastPivotRow] = value;
00184 else
00185 infeasible_->quickAdd(lastPivotRow,value);
00186 } else if (value<lower-tolerance) {
00187 value -= lower;
00188 value *= value;
00189 #ifdef COLUMN_BIAS
00190 if (iPivot<numberColumns)
00191 value *= COLUMN_BIAS;
00192 #endif
00193
00194 if (infeas[lastPivotRow])
00195 infeas[lastPivotRow] = value;
00196 else
00197 infeasible_->add(lastPivotRow,value);
00198 } else {
00199
00200 if (infeas[lastPivotRow])
00201 infeas[lastPivotRow] = 1.0e-100;
00202 }
00203 number = infeasible_->getNumElements();
00204 }
00205 if(model_->numberIterations()<model_->lastBadIteration()+200) {
00206
00207 double checkTolerance = 1.0e-8;
00208 if (!model_->factorization()->pivots())
00209 checkTolerance = 1.0e-6;
00210 if (model_->largestPrimalError()>checkTolerance)
00211 tolerance *= model_->largestPrimalError()/checkTolerance;
00212 }
00213 int numberWanted;
00214 if (mode_<2 ) {
00215 numberWanted = number+1;
00216 } else if (mode_==2) {
00217 numberWanted = max(2000,number/8);
00218 } else {
00219 int numberElements = model_->factorization()->numberElements();
00220 double ratio = (double) numberElements/(double) model_->numberRows();
00221 numberWanted = max(2000,number/8);
00222 if (ratio<1.0) {
00223 numberWanted = max(2000,number/20);
00224 } else if (ratio>10.0) {
00225 ratio = number * (ratio/80.0);
00226 if (ratio>number)
00227 numberWanted=number+1;
00228 else
00229 numberWanted = max(2000,(int) ratio);
00230 }
00231 }
00232 int iPass;
00233
00234 int start[4];
00235 start[1]=number;
00236 start[2]=0;
00237 double dstart = ((double) number) * CoinDrand48();
00238 start[0]=(int) dstart;
00239 start[3]=start[0];
00240
00241
00242 for (iPass=0;iPass<2;iPass++) {
00243 int end = start[2*iPass+1];
00244 for (i=start[2*iPass];i<end;i++) {
00245 iRow = index[i];
00246 double value = infeas[iRow];
00247 if (value>tolerance) {
00248
00249 #ifdef OUT_EQ
00250 {
00251 int iSequence = pivotVariable[iRow];
00252 if (upper[iSequence]==lower[iSequence])
00253 value *= 2.0;
00254 }
00255 #endif
00256 double weight = weights_[iRow];
00257
00258
00259
00260
00261
00262 if (value>largest*weight) {
00263
00264 if (iRow==lastPivotRow) {
00265 if (value*1.0e-10<largest*weight)
00266 continue;
00267 else
00268 value *= 1.0e-10;
00269 }
00270 int iSequence = pivotVariable[iRow];
00271 if (!model_->flagged(iSequence)) {
00272
00273 #ifdef CLP_DEBUG
00274 double value2=0.0;
00275 if (solution[iSequence]>upper[iSequence]+tolerance)
00276 value2=solution[iSequence]-upper[iSequence];
00277 else if (solution[iSequence]<lower[iSequence]-tolerance)
00278 value2=solution[iSequence]-lower[iSequence];
00279 assert(fabs(value2*value2-infeas[iRow])<1.0e-8*min(value2*value2,infeas[iRow]));
00280 #endif
00281 if (solution[iSequence]>upper[iSequence]+tolerance||
00282 solution[iSequence]<lower[iSequence]-tolerance) {
00283 chosenRow=iRow;
00284 largest=value/weight;
00285
00286 }
00287 } else {
00288
00289 numberWanted++;
00290 }
00291 }
00292 numberWanted--;
00293 if (!numberWanted)
00294 break;
00295 }
00296 }
00297 if (!numberWanted)
00298 break;
00299 }
00300
00301 return chosenRow;
00302 }
00303 #define TRY_NORM 1.0e-4
00304
00305 double
00306 ClpDualRowSteepest::updateWeights(CoinIndexedVector * input,
00307 CoinIndexedVector * spare,
00308 CoinIndexedVector * updatedColumn)
00309 {
00310 #if CLP_DEBUG>2
00311
00312 {
00313 int numberRows = model_->numberRows();
00314 CoinIndexedVector * temp = new CoinIndexedVector();
00315 temp->reserve(numberRows+
00316 model_->factorization()->maximumPivots());
00317 double * array = alternateWeights_->denseVector();
00318 int * which = alternateWeights_->getIndices();
00319 int i;
00320 for (i=0;i<numberRows;i++) {
00321 double value=0.0;
00322 array[i] = 1.0;
00323 which[0] = i;
00324 alternateWeights_->setNumElements(1);
00325 model_->factorization()->updateColumnTranspose(temp,
00326 alternateWeights_);
00327 int number = alternateWeights_->getNumElements();
00328 int j;
00329 for (j=0;j<number;j++) {
00330 int iRow=which[j];
00331 value+=array[iRow]*array[iRow];
00332 array[iRow]=0.0;
00333 }
00334 alternateWeights_->setNumElements(0);
00335 if (fabs(weights_[i]-value)>1.0e-4)
00336 printf("%d old %g, true %g\n",i,weights_[i],value);
00337
00338
00339 }
00340 delete temp;
00341 }
00342 #endif
00343 assert (input->packedMode());
00344 assert (updatedColumn->packedMode());
00345 double alpha=0.0;
00346 if (!model_->factorization()->networkBasis()) {
00347
00348 alternateWeights_->clear();
00349 double norm = 0.0;
00350 int i;
00351 double * work = input->denseVector();
00352 int numberNonZero = input->getNumElements();
00353 int * which = input->getIndices();
00354 double * work2 = spare->denseVector();
00355 int * which2 = spare->getIndices();
00356
00357
00358
00359
00360 const int *permute = model_->factorization()->permute();
00361
00362 for ( i = 0; i < numberNonZero; i ++ ) {
00363 int iRow = which[i];
00364 double value = work[i];
00365 norm += value*value;
00366 iRow = permute[iRow];
00367 work2[iRow] = value;
00368 which2[i] = iRow;
00369 }
00370 spare->setNumElements ( numberNonZero );
00371
00372 model_->factorization()->updateColumn(spare,spare,true);
00373
00374 numberNonZero = spare->getNumElements();
00375
00376 int pivotRow = model_->pivotRow();
00377 #ifdef CLP_DEBUG
00378 if ( model_->logLevel ( ) >4 &&
00379 fabs(norm-weights_[pivotRow])>1.0e-3*(1.0+norm))
00380 printf("on row %d, true weight %g, old %g\n",
00381 pivotRow,sqrt(norm),sqrt(weights_[pivotRow]));
00382 #endif
00383
00384 norm /= model_->alpha() * model_->alpha();
00385
00386 assert(norm);
00387
00388 alpha=0.0;
00389 double multiplier = 2.0 / model_->alpha();
00390
00391 work = updatedColumn->denseVector();
00392 numberNonZero = updatedColumn->getNumElements();
00393 which = updatedColumn->getIndices();
00394
00395 int nSave=0;
00396 double * work3 = alternateWeights_->denseVector();
00397 int * which3 = alternateWeights_->getIndices();
00398 const int * pivotColumn = model_->factorization()->pivotColumn();
00399 for (i =0; i < numberNonZero; i++) {
00400 int iRow = which[i];
00401 double theta = work[i];
00402 if (iRow==pivotRow)
00403 alpha = theta;
00404 double devex = weights_[iRow];
00405 work3[nSave]=devex;
00406 which3[nSave++]=iRow;
00407
00408 int jRow = pivotColumn[iRow];
00409 double value = work2[jRow];
00410 devex += theta * (theta*norm+value * multiplier);
00411 if (devex < TRY_NORM)
00412 devex = TRY_NORM;
00413 weights_[iRow]=devex;
00414 }
00415 alternateWeights_->setPackedMode(true);
00416 alternateWeights_->setNumElements(nSave);
00417 if (norm < TRY_NORM)
00418 norm = TRY_NORM;
00419 weights_[pivotRow] = norm;
00420 spare->clear();
00421 #ifdef CLP_DEBUG
00422 spare->checkClear();
00423 #endif
00424 } else {
00425
00426 alternateWeights_->clear();
00427 double norm = 0.0;
00428 int i;
00429 double * work = input->denseVector();
00430 int number = input->getNumElements();
00431 int * which = input->getIndices();
00432 double * work2 = spare->denseVector();
00433 int * which2 = spare->getIndices();
00434 for (i=0;i<number;i++) {
00435 int iRow = which[i];
00436 double value = work[i];
00437 norm += value*value;
00438 work2[iRow]=value;
00439 which2[i]=iRow;
00440 }
00441 spare->setNumElements(number);
00442
00443 model_->factorization()->updateColumn(alternateWeights_,spare);
00444
00445 int pivotRow = model_->pivotRow();
00446 #ifdef CLP_DEBUG
00447 if ( model_->logLevel ( ) >4 &&
00448 fabs(norm-weights_[pivotRow])>1.0e-3*(1.0+norm))
00449 printf("on row %d, true weight %g, old %g\n",
00450 pivotRow,sqrt(norm),sqrt(weights_[pivotRow]));
00451 #endif
00452
00453 norm /= model_->alpha() * model_->alpha();
00454
00455 assert(norm);
00456
00457
00458
00459 alpha=0.0;
00460 double multiplier = 2.0 / model_->alpha();
00461
00462 work = updatedColumn->denseVector();
00463 number = updatedColumn->getNumElements();
00464 which = updatedColumn->getIndices();
00465
00466 int nSave=0;
00467 double * work3 = alternateWeights_->denseVector();
00468 int * which3 = alternateWeights_->getIndices();
00469 for (i =0; i < number; i++) {
00470 int iRow = which[i];
00471 double theta = work[i];
00472 if (iRow==pivotRow)
00473 alpha = theta;
00474 double devex = weights_[iRow];
00475 work3[nSave]=devex;
00476 which3[nSave++]=iRow;
00477 double value = work2[iRow];
00478 devex += theta * (theta*norm+value * multiplier);
00479 if (devex < TRY_NORM)
00480 devex = TRY_NORM;
00481 weights_[iRow]=devex;
00482 }
00483 assert (alpha);
00484 alternateWeights_->setPackedMode(true);
00485 alternateWeights_->setNumElements(nSave);
00486 if (norm < TRY_NORM)
00487 norm = TRY_NORM;
00488 weights_[pivotRow] = norm;
00489 spare->clear();
00490 }
00491 #ifdef CLP_DEBUG
00492 spare->checkClear();
00493 #endif
00494 return alpha;
00495 }
00496
00497
00498
00499
00500
00501 void
00502 ClpDualRowSteepest::updatePrimalSolution(
00503 CoinIndexedVector * primalUpdate,
00504 double primalRatio,
00505 double & objectiveChange)
00506 {
00507 double * work = primalUpdate->denseVector();
00508 int number = primalUpdate->getNumElements();
00509 int * which = primalUpdate->getIndices();
00510 int i;
00511 double changeObj=0.0;
00512 double tolerance=model_->currentPrimalTolerance();
00513 const int * pivotVariable = model_->pivotVariable();
00514 double * infeas = infeasible_->denseVector();
00515 int pivotRow = model_->pivotRow();
00516 double * solution = model_->solutionRegion();
00517 #ifdef COLUMN_BIAS
00518 int numberColumns = model_->numberColumns();
00519 #endif
00520 if (primalUpdate->packedMode()) {
00521 for (i=0;i<number;i++) {
00522 int iRow=which[i];
00523 int iPivot=pivotVariable[iRow];
00524 double value = solution[iPivot];
00525 double cost = model_->cost(iPivot);
00526 double change = primalRatio*work[i];
00527 work[i]=0.0;
00528 value -= change;
00529 changeObj -= change*cost;
00530 solution[iPivot] = value;
00531 double lower = model_->lower(iPivot);
00532 double upper = model_->upper(iPivot);
00533
00534
00535
00536 if (iRow==pivotRow) {
00537 iPivot = model_->sequenceIn();
00538 lower = model_->lower(iPivot);
00539 upper = model_->upper(iPivot);
00540 value = model_->valueIncomingDual();
00541 }
00542 if (value<lower-tolerance) {
00543 value -= lower;
00544 value *= value;
00545 #ifdef COLUMN_BIAS
00546 if (iPivot<numberColumns)
00547 value *= COLUMN_BIAS;
00548 #endif
00549 #ifdef FIXED_BIAS
00550 if (lower==upper)
00551 value *= FIXED_BIAS;
00552 #endif
00553
00554 if (infeas[iRow])
00555 infeas[iRow] = value;
00556 else
00557 infeasible_->quickAdd(iRow,value);
00558 } else if (value>upper+tolerance) {
00559 value -= upper;
00560 value *= value;
00561 #ifdef COLUMN_BIAS
00562 if (iPivot<numberColumns)
00563 value *= COLUMN_BIAS;
00564 #endif
00565 #ifdef FIXED_BIAS
00566 if (lower==upper)
00567 value *= FIXED_BIAS;
00568 #endif
00569
00570 if (infeas[iRow])
00571 infeas[iRow] = value;
00572 else
00573 infeasible_->quickAdd(iRow,value);
00574 } else {
00575
00576 if (infeas[iRow])
00577 infeas[iRow] = 1.0e-100;
00578 }
00579 }
00580 } else {
00581 for (i=0;i<number;i++) {
00582 int iRow=which[i];
00583 int iPivot=pivotVariable[iRow];
00584 double value = solution[iPivot];
00585 double cost = model_->cost(iPivot);
00586 double change = primalRatio*work[iRow];
00587 value -= change;
00588 changeObj -= change*cost;
00589 solution[iPivot] = value;
00590 double lower = model_->lower(iPivot);
00591 double upper = model_->upper(iPivot);
00592
00593
00594
00595 if (iRow==pivotRow) {
00596 iPivot = model_->sequenceIn();
00597 lower = model_->lower(iPivot);
00598 upper = model_->upper(iPivot);
00599 value = model_->valueIncomingDual();
00600 }
00601 if (value<lower-tolerance) {
00602 value -= lower;
00603 value *= value;
00604 #ifdef COLUMN_BIAS
00605 if (iPivot<numberColumns)
00606 value *= COLUMN_BIAS;
00607 #endif
00608 #ifdef FIXED_BIAS
00609 if (lower==upper)
00610 value *= FIXED_BIAS;
00611 #endif
00612
00613 if (infeas[iRow])
00614 infeas[iRow] = value;
00615 else
00616 infeasible_->quickAdd(iRow,value);
00617 } else if (value>upper+tolerance) {
00618 value -= upper;
00619 value *= value;
00620 #ifdef COLUMN_BIAS
00621 if (iPivot<numberColumns)
00622 value *= COLUMN_BIAS;
00623 #endif
00624 #ifdef FIXED_BIAS
00625 if (lower==upper)
00626 value *= FIXED_BIAS;
00627 #endif
00628
00629 if (infeas[iRow])
00630 infeas[iRow] = value;
00631 else
00632 infeasible_->quickAdd(iRow,value);
00633 } else {
00634
00635 if (infeas[iRow])
00636 infeas[iRow] = 1.0e-100;
00637 }
00638 work[iRow]=0.0;
00639 }
00640 }
00641 primalUpdate->setNumElements(0);
00642 objectiveChange += changeObj;
00643 }
00644
00645
00646
00647
00648
00649
00650 void
00651 ClpDualRowSteepest::saveWeights(ClpSimplex * model,int mode)
00652 {
00653
00654 model_ = model;
00655 int numberRows = model_->numberRows();
00656 int numberColumns = model_->numberColumns();
00657 const int * pivotVariable = model_->pivotVariable();
00658 int i;
00659 if (mode==1&&weights_) {
00660 alternateWeights_->clear();
00661
00662 int * which = alternateWeights_->getIndices();
00663 for (i=0;i<numberRows;i++) {
00664 int iPivot=pivotVariable[i];
00665 which[i]=iPivot;
00666 }
00667 state_=1;
00668 } else if (mode==2||mode==4||mode==5) {
00669
00670 if (!weights_||state_==-1||mode==5) {
00671
00672 delete [] weights_;
00673 delete alternateWeights_;
00674 weights_ = new double[numberRows];
00675 alternateWeights_ = new CoinIndexedVector();
00676
00677 alternateWeights_->reserve(numberRows+
00678 model_->factorization()->maximumPivots());
00679 if (!mode_||mode_==2||mode==5) {
00680
00681 for (i=0;i<numberRows;i++) {
00682 weights_[i]=1.0;
00683 }
00684 } else {
00685 CoinIndexedVector * temp = new CoinIndexedVector();
00686 temp->reserve(numberRows+
00687 model_->factorization()->maximumPivots());
00688 double * array = alternateWeights_->denseVector();
00689 int * which = alternateWeights_->getIndices();
00690 for (i=0;i<numberRows;i++) {
00691 double value=0.0;
00692 array[0] = 1.0;
00693 which[0] = i;
00694 alternateWeights_->setNumElements(1);
00695 alternateWeights_->setPackedMode(true);
00696 model_->factorization()->updateColumnTranspose(temp,
00697 alternateWeights_);
00698 int number = alternateWeights_->getNumElements();
00699 int j;
00700 for (j=0;j<number;j++) {
00701 value+=array[j]*array[j];
00702 array[j]=0.0;
00703 }
00704 alternateWeights_->setNumElements(0);
00705 weights_[i] = value;
00706 }
00707 delete temp;
00708 }
00709
00710 savedWeights_ = new CoinIndexedVector();
00711 savedWeights_->reserve(numberRows);
00712
00713 double * array = savedWeights_->denseVector();
00714 int * which = savedWeights_->getIndices();
00715 for (i=0;i<numberRows;i++) {
00716 array[i]=weights_[i];
00717 which[i]=pivotVariable[i];
00718 }
00719 } else {
00720 int * which = alternateWeights_->getIndices();
00721 if (mode!=4) {
00722
00723 memcpy(savedWeights_->getIndices(),which,
00724 numberRows*sizeof(int));
00725 memcpy(savedWeights_->denseVector(),weights_,
00726 numberRows*sizeof(double));
00727 } else {
00728
00729 memcpy(which,savedWeights_->getIndices(),
00730 numberRows*sizeof(int));
00731 memcpy(weights_,savedWeights_->denseVector(),
00732 numberRows*sizeof(double));
00733 }
00734
00735 double * array = new double[numberRows+numberColumns];
00736 for (i=0;i<numberRows;i++) {
00737 int iSeq=which[i];
00738 array[iSeq]=weights_[i];
00739 }
00740 for (i=0;i<numberRows;i++) {
00741 int iPivot=pivotVariable[i];
00742 weights_[i]=array[iPivot];
00743 if (weights_[i]<TRY_NORM)
00744 weights_[i] = TRY_NORM;
00745 }
00746 delete [] array;
00747 }
00748 state_=0;
00749
00750 if (!infeasible_) {
00751 infeasible_ = new CoinIndexedVector();
00752 infeasible_->reserve(numberRows);
00753 }
00754 }
00755 if (mode>=2) {
00756
00757
00758
00759
00760 infeasible_->clear();
00761 int iRow;
00762 const int * pivotVariable = model_->pivotVariable();
00763 double tolerance=model_->currentPrimalTolerance();
00764 for (iRow=0;iRow<numberRows;iRow++) {
00765 int iPivot=pivotVariable[iRow];
00766 double value = model_->solution(iPivot);
00767 double lower = model_->lower(iPivot);
00768 double upper = model_->upper(iPivot);
00769 if (value<lower-tolerance) {
00770 value -= lower;
00771 value *= value;
00772 #ifdef COLUMN_BIAS
00773 if (iPivot<numberColumns)
00774 value *= COLUMN_BIAS;
00775 #endif
00776 #ifdef FIXED_BIAS
00777 if (lower==upper)
00778 value *= FIXED_BIAS;
00779 #endif
00780
00781 infeasible_->quickAdd(iRow,value);
00782 } else if (value>upper+tolerance) {
00783 value -= upper;
00784 value *= value;
00785 #ifdef COLUMN_BIAS
00786 if (iPivot<numberColumns)
00787 value *= COLUMN_BIAS;
00788 #endif
00789 #ifdef FIXED_BIAS
00790 if (lower==upper)
00791 value *= FIXED_BIAS;
00792 #endif
00793
00794 infeasible_->quickAdd(iRow,value);
00795 }
00796 }
00797 }
00798 }
00799
00800 void
00801 ClpDualRowSteepest::unrollWeights()
00802 {
00803 double * saved = alternateWeights_->denseVector();
00804 int number = alternateWeights_->getNumElements();
00805 int * which = alternateWeights_->getIndices();
00806 int i;
00807 if (alternateWeights_->packedMode()) {
00808 for (i=0;i<number;i++) {
00809 int iRow = which[i];
00810 weights_[iRow]=saved[i];
00811 saved[i]=0.0;
00812 }
00813 } else {
00814 for (i=0;i<number;i++) {
00815 int iRow = which[i];
00816 weights_[iRow]=saved[iRow];
00817 saved[iRow]=0.0;
00818 }
00819 }
00820 alternateWeights_->setNumElements(0);
00821 }
00822
00823
00824
00825 ClpDualRowPivot * ClpDualRowSteepest::clone(bool CopyData) const
00826 {
00827 if (CopyData) {
00828 return new ClpDualRowSteepest(*this);
00829 } else {
00830 return new ClpDualRowSteepest();
00831 }
00832 }
00833
00834 void
00835 ClpDualRowSteepest::clearArrays()
00836 {
00837 delete [] weights_;
00838 weights_=NULL;
00839 delete [] dubiousWeights_;
00840 dubiousWeights_=NULL;
00841 delete infeasible_;
00842 infeasible_ = NULL;
00843 delete alternateWeights_;
00844 alternateWeights_ = NULL;
00845 delete savedWeights_;
00846 savedWeights_ = NULL;
00847 state_ =-1;
00848 }
00849
00850 bool
00851 ClpDualRowSteepest::looksOptimal() const
00852 {
00853 int iRow;
00854 const int * pivotVariable = model_->pivotVariable();
00855 double tolerance=model_->currentPrimalTolerance();
00856
00857
00858 double error = min(1.0e-3,model_->largestPrimalError());
00859
00860 tolerance = tolerance + error;
00861
00862 tolerance = min(1000.0,tolerance);
00863 int numberRows = model_->numberRows();
00864 int numberInfeasible=0;
00865 for (iRow=0;iRow<numberRows;iRow++) {
00866 int iPivot=pivotVariable[iRow];
00867 double value = model_->solution(iPivot);
00868 double lower = model_->lower(iPivot);
00869 double upper = model_->upper(iPivot);
00870 if (value<lower-tolerance) {
00871 numberInfeasible++;
00872 } else if (value>upper+tolerance) {
00873 numberInfeasible++;
00874 }
00875 }
00876 return (numberInfeasible==0);
00877 }
00878