source: trunk/Clp/src/AbcSimplexFactorization.cpp @ 1878

Last change on this file since 1878 was 1878, checked in by forrest, 7 years ago

minor changes to implement Aboca

File size: 20.4 KB
Line 
1/* $Id: AbcSimplexFactorization.cpp 1732 2011-05-31 08:09:41Z forrest $ */
2// Copyright (C) 2002, International Business Machines
3// Corporation and others, Copyright (C) 2012, FasterCoin.  All Rights Reserved.
4// This code is licensed under the terms of the Eclipse Public License (EPL).
5#if CLP_HAS_ABC
6#define USE_DENSE_FAC -1
7#define USE_SMALL_FAC 200
8#define USE_LONG_FAC 10000
9#include "CoinPragma.hpp"
10#include "AbcSimplexFactorization.hpp"
11#include "ClpFactorization.hpp"
12#include "ClpMessage.hpp"
13#include "CoinAbcCommon.hpp"
14#include "CoinHelperFunctions.hpp"
15#include "CoinIndexedVector.hpp"
16#include "AbcSimplex.hpp"
17#include "AbcSimplexDual.hpp"
18#include "AbcMatrix.hpp"
19#include "CoinAbcFactorization.hpp"
20//#include "CoinDenseFactorization.hpp"
21#ifdef ABC_JUST_ONE_FACTORIZATION
22#define CoinAbcFactorization CoinAbcBaseFactorization
23#define CoinAbcSmallFactorization CoinAbcBaseFactorization
24#define CoinAbcLongFactorization CoinAbcBaseFactorization
25#define CoinAbcOrderedFactorization CoinAbcBaseFactorization
26#endif
27#ifndef ABC_LONG_FACTORIZATION
28#undef CoinAbcLongFactorization
29#define CoinAbcLongFactorization CoinAbcOrderedFactorization
30#endif
31#ifdef ABC_TEMPORARY_FACTORIZATION
32#undef CoinAbcSmallFactorization
33#define CoinAbcSmallFactorization CoinAbcOrderedFactorization
34#endif
35//-------------------------------------------------------------------
36// Default Constructor
37//-------------------------------------------------------------------
38AbcSimplexFactorization::AbcSimplexFactorization (int /*numberRows*/)
39{
40  model_=NULL;
41  coinAbcFactorization_ = new CoinAbcFactorization();
42  forceB_ = 0;
43  goDenseThreshold_ = USE_DENSE_FAC;
44  goSmallThreshold_ = USE_SMALL_FAC;
45  goLongThreshold_ = USE_LONG_FAC;
46  numberSlacks_=0;
47}
48
49//-------------------------------------------------------------------
50// Copy constructor
51//-------------------------------------------------------------------
52AbcSimplexFactorization::AbcSimplexFactorization (const AbcSimplexFactorization & rhs,
53                                                  int denseIfSmaller)
54{
55  forceB_ = rhs.forceB_;
56  goDenseThreshold_ = rhs.goDenseThreshold_;
57  goSmallThreshold_ = rhs.goSmallThreshold_;
58  goLongThreshold_ = rhs.goLongThreshold_;
59  numberSlacks_=rhs.numberSlacks_;
60  int goDense = 0;
61  model_=rhs.model_;
62  if (denseIfSmaller > 0 && denseIfSmaller <= goDenseThreshold_) {
63    CoinAbcDenseFactorization * denseR =
64      dynamic_cast<CoinAbcDenseFactorization *>(rhs.coinAbcFactorization_);
65    if (!denseR)
66      goDense = 1;
67  }
68  if (denseIfSmaller > 0 && !rhs.coinAbcFactorization_) {
69    if (denseIfSmaller <= goDenseThreshold_)
70      goDense = 1;
71    else if (denseIfSmaller <= goSmallThreshold_)
72      goDense = 2;
73    else if (denseIfSmaller >= goLongThreshold_)
74      goDense = 3;
75  } else if (denseIfSmaller < 0) {
76    if (-denseIfSmaller <= goDenseThreshold_)
77      goDense = 1;
78    else if (-denseIfSmaller <= goSmallThreshold_)
79      goDense = 2;
80    else if (-denseIfSmaller >= goLongThreshold_)
81      goDense = 3;
82  }
83  if (rhs.coinAbcFactorization_ && (denseIfSmaller >= 0 || !goDense))
84    coinAbcFactorization_ = rhs.coinAbcFactorization_->clone();
85  else
86    coinAbcFactorization_ = NULL;
87  if (goDense) {
88    delete coinAbcFactorization_;
89    if (goDense == 1)
90      coinAbcFactorization_ = new CoinAbcDenseFactorization();
91    else if (goDense == 2)
92      coinAbcFactorization_ = new CoinAbcSmallFactorization();
93    else if (goDense == 3)
94      coinAbcFactorization_ = new CoinAbcLongFactorization();
95    else
96      coinAbcFactorization_ = new CoinAbcFactorization();
97    assert (coinAbcFactorization_);
98    coinAbcFactorization_->maximumPivots(rhs.coinAbcFactorization_->maximumPivots());
99    coinAbcFactorization_->pivotTolerance(rhs.coinAbcFactorization_->pivotTolerance());
100    coinAbcFactorization_->zeroTolerance(rhs.coinAbcFactorization_->zeroTolerance());
101  }
102}
103//-------------------------------------------------------------------
104// Destructor
105//-------------------------------------------------------------------
106AbcSimplexFactorization::~AbcSimplexFactorization ()
107{
108  delete coinAbcFactorization_;
109}
110
111//----------------------------------------------------------------
112// Assignment operator
113//-------------------------------------------------------------------
114AbcSimplexFactorization &
115AbcSimplexFactorization::operator=(const AbcSimplexFactorization& rhs)
116{
117  if (this != &rhs) {
118    forceB_ = rhs.forceB_;
119    model_=rhs.model_;
120    goDenseThreshold_ = rhs.goDenseThreshold_;
121    goSmallThreshold_ = rhs.goSmallThreshold_;
122    goLongThreshold_ = rhs.goLongThreshold_;
123    numberSlacks_=rhs.numberSlacks_;
124   
125    if (rhs.coinAbcFactorization_) {
126      delete coinAbcFactorization_;
127      coinAbcFactorization_ = rhs.coinAbcFactorization_->clone();
128    }
129  }
130  return *this;
131}
132// Go over to dense code
133void
134AbcSimplexFactorization::goDenseOrSmall(int numberRows)
135{
136  if (!forceB_) {
137    delete coinAbcFactorization_;
138    if (numberRows <= goDenseThreshold_) {
139      coinAbcFactorization_ = new CoinAbcDenseFactorization();
140    } else if (numberRows <= goSmallThreshold_) {
141      coinAbcFactorization_ = new CoinAbcSmallFactorization();
142    } else if (numberRows >= goLongThreshold_) {
143      coinAbcFactorization_ = new CoinAbcLongFactorization();
144    } else {
145      coinAbcFactorization_ = new CoinAbcFactorization();
146    }
147  }
148}
149// If nonzero force use of 1,dense 2,small 3,long
150void
151AbcSimplexFactorization::forceOtherFactorization(int which)
152{
153  delete coinAbcFactorization_;
154  forceB_ = 0;
155  coinAbcFactorization_ = NULL;
156  if (which > 0 && which < 6) {
157    forceB_ = which;
158    switch (which) {
159    case 1:
160      coinAbcFactorization_ = new CoinAbcDenseFactorization();
161      goDenseThreshold_ = COIN_INT_MAX;
162      break;
163    case 2:
164    case 4:
165      coinAbcFactorization_ = new CoinAbcSmallFactorization();
166      goSmallThreshold_ = COIN_INT_MAX;
167      break;
168    case 3:
169    case 5:
170      coinAbcFactorization_ = new CoinAbcLongFactorization();
171      goLongThreshold_ = 0;
172      break;
173    }
174  } else {
175    coinAbcFactorization_ = new CoinAbcFactorization();
176  }
177}
178// Synchronize stuff
179void 
180AbcSimplexFactorization::synchronize(const ClpFactorization * otherFactorization,const AbcSimplex * model)
181{
182  goDenseThreshold_=otherFactorization->goDenseThreshold();
183  goSmallThreshold_=otherFactorization->goSmallThreshold();
184  goLongThreshold_=otherFactorization->goOslThreshold();
185  //forceOtherFactorization(otherFactorization->typeOfFactorization());
186  goDenseOrSmall(model->numberRows());
187  maximumPivots(static_cast<int>(otherFactorization->maximumPivots()*1.2));
188}
189int
190AbcSimplexFactorization::factorize ( AbcSimplex * model,
191                                     int solveType, bool valuesPass)
192{
193  model_= model;
194  AbcMatrix * matrix = model->abcMatrix();
195  int numberRows = model->numberRows();
196  if (!numberRows)
197    return 0;
198  bool anyChanged = false;
199  coinAbcFactorization_->setStatus(-99);
200  const int *  COIN_RESTRICT pivotVariable = model->pivotVariable();
201  //returns 0 -okay, -1 singular, -2 too many in basis */
202  // allow dense
203  int solveMode = coinAbcFactorization_->solveMode()&1;
204  if (model->numberIterations()>model->baseIteration())
205    solveMode += 8;
206  else
207    solveMode = 1; // try dense
208  if (valuesPass)
209    solveMode += 4;
210  coinAbcFactorization_->setSolveMode(solveMode);
211  while (status() < -98) {
212   
213    int i;
214    int numberBasic = 0;
215    // Move pivot variables across if they look good
216    int *  COIN_RESTRICT pivotTemp = model->usefulArray(0)->getIndices();
217#ifndef NDEBUG
218    model_->checkArrays();
219#endif
220    assert (!model->usefulArray(0)->getNumElements());
221    // Seems to prefer things in order so quickest
222    // way is to go though like this
223    for (i = 0; i < numberRows; i++) {
224      if (pivotVariable[i]<numberRows)
225        pivotTemp[numberBasic++] = pivotVariable[i];
226    }
227    numberSlacks_ = numberBasic;
228    /* Put column basic variables into pivotVariable
229    */
230    for (i = 0; i < numberRows; i++) {
231      if (pivotVariable[i]>=numberRows)
232        pivotTemp[numberBasic++] = pivotVariable[i];
233    }
234    CoinBigIndex numberElements = numberSlacks_;
235   
236    // compute how much in basis
237    int numberColumnBasic = numberBasic - numberSlacks_;
238   
239    numberElements += matrix->countBasis(pivotTemp + numberSlacks_,
240                                         numberColumnBasic);
241    //printf("Basis has %d slacks - size %d\n",numberSlacks_,numberElements);
242    // Not needed for dense
243    numberElements = 3 * numberBasic + 3 * numberElements + 20000;
244    int numberIterations = model->numberIterations();
245    coinAbcFactorization_->setUsefulInformation(&numberIterations, 0);
246    coinAbcFactorization_->getAreas ( numberRows,
247                                    numberSlacks_ + numberColumnBasic, numberElements,
248                                    2 * numberElements );
249#if 0
250    if (!model->numberIterations())
251      printf("do I need destructor etc in getAreas?\n");
252#endif
253    // Fill in counts so we can skip part of preProcess
254    // This is NOT needed for dense but would be needed for later versions
255    CoinFactorizationDouble *  COIN_RESTRICT elementU;
256    int *  COIN_RESTRICT indexRowU;
257    CoinBigIndex *  COIN_RESTRICT startColumnU;
258    int *  COIN_RESTRICT numberInRow;
259    int *  COIN_RESTRICT numberInColumn;
260    elementU = coinAbcFactorization_->elements();
261    indexRowU = coinAbcFactorization_->indices();
262    startColumnU = coinAbcFactorization_->starts();
263#define slackValue 1.0
264    numberInRow = coinAbcFactorization_->numberInRow();
265    numberInColumn = coinAbcFactorization_->numberInColumn();
266    coinAbcFactorization_->setNumberSlacks(numberSlacks_);
267    CoinZeroN ( numberInRow, numberRows  );
268    CoinZeroN ( numberInColumn, numberRows );
269    for (i = 0; i < numberSlacks_; i++) {
270      int iRow = pivotTemp[i];
271      indexRowU[i] = iRow;
272      startColumnU[i] = i;
273      elementU[i] = slackValue;
274      numberInRow[iRow] = 1;
275      numberInColumn[i] = 1;
276    }
277    startColumnU[numberSlacks_] = numberSlacks_;
278    // can change for gub so redo
279    numberColumnBasic = numberRows - numberSlacks_;
280    matrix->fillBasis(pivotTemp + numberSlacks_,
281                      numberColumnBasic,
282                      indexRowU,
283                      startColumnU + numberSlacks_,
284                      numberInRow,
285                      numberInColumn + numberSlacks_,
286                      elementU);
287    numberElements = startColumnU[numberRows-1]
288      + numberInColumn[numberRows-1];
289    coinAbcFactorization_->preProcess ( );
290    coinAbcFactorization_->factor (model);
291#if 0
292    if (model_->numberIterations()==23) {
293      CoinAbcFactorization * factor = dynamic_cast<CoinAbcFactorization *>(coinAbcFactorization_);
294      if (factor)
295        factor->show_self();
296    }
297#endif
298    if (coinAbcFactorization_->status() == -1 &&
299        (coinAbcFactorization_->solveMode() & 1) != 0) {
300      int solveMode = coinAbcFactorization_->solveMode();
301      solveMode --; // so bottom will be 0
302      coinAbcFactorization_->setSolveMode(solveMode);
303      coinAbcFactorization_->setStatus(-99);
304    }
305    if (coinAbcFactorization_->status() == -99)
306      continue;
307    // If we get here status is 0 or -1
308    if (coinAbcFactorization_->status() == 0 && numberBasic == numberRows) {
309      coinAbcFactorization_->postProcess(pivotTemp, model->pivotVariable());
310      model_->moveToBasic();
311    } else if (solveType == 0 || solveType == 2/*||solveType==1*/) {
312      // Change pivotTemp to be correct list
313      anyChanged = true;
314      coinAbcFactorization_->makeNonSingular(pivotTemp);
315      const double *  COIN_RESTRICT lowerArray = model->lowerRegion();
316      const double *  COIN_RESTRICT upperArray = model->upperRegion();
317      double *  COIN_RESTRICT solution = model->solutionRegion();
318      //int * pivotVariable=model_->pivotVariable();
319      //int * fromExternal=model_->fromExternal();
320      int numberTotal=model_->numberTotal();
321      //can use external status_
322      unsigned char *  COIN_RESTRICT statusArray = model_->statusArray();
323      CoinAbcMemset0(statusArray,numberTotal);
324      for (int iRow=0;iRow<numberRows;iRow++) {
325        int iPivot=pivotVariable[iRow];
326        //if (iPivot!=pivotTemp[iRow])
327        //printf("row %d bad pivot %d good %d\n",iRow,iPivot,pivotTemp[iRow]);
328        statusArray[iPivot]=1;
329      }
330      for (int iRow=0;iRow<numberRows;iRow++) {
331        int iPivot=pivotTemp[iRow];
332        statusArray[iPivot]|=2;
333      }
334      int jPivot=0;
335      double largeValue = model->largeValue();
336      for (int iRow=0;iRow<numberRows;iRow++) {
337        int iPivot=pivotVariable[iRow];
338        if (statusArray[iPivot]==1) {
339          // clean
340          while (statusArray[jPivot]!=2) {
341            jPivot++;
342          }
343          statusArray[iPivot]=0;
344          statusArray[jPivot]=0;
345#ifndef NDEBUG
346          printf("On Row %d replacing %d by %d\n",iRow,iPivot,jPivot);
347#endif
348          AbcSimplex::Status thisStatus;
349          if (!valuesPass) {
350            double lower = lowerArray[iPivot];
351            double upper = upperArray[iPivot];
352            double value = solution[iPivot];
353            if (lower > -largeValue || upper < largeValue) {
354              if (lower!=upper) {
355                if (fabs(value - lower) < fabs(value - upper)) {
356                  thisStatus=AbcSimplex::atLowerBound;
357                  solution[iPivot] = lower;
358                } else {
359                  thisStatus= AbcSimplex::atUpperBound;
360                  solution[iPivot] = upper;
361                }
362              } else {
363                thisStatus= AbcSimplex::isFixed;
364                solution[iPivot] = upper;
365              }
366            } else {
367              thisStatus=AbcSimplex::isFree;
368            }
369          } else {
370            thisStatus=AbcSimplex::superBasic;
371          }
372          model_->setInternalStatus(iPivot,thisStatus);
373          model_->setInternalStatus(jPivot,AbcSimplex::basic);
374          // swap (solution will be wrong - but that doesn't matter as basic)
375          model_->swap(iRow,jPivot);
376        }
377      }
378      CoinAbcMemcpy(model_->pivotVariable(),pivotTemp,numberRows);
379#ifndef NDEBUG
380      model_->checkConsistentPivots();
381#endif
382      // signal repeat
383      coinAbcFactorization_->pivotTolerance(0.999);
384      coinAbcFactorization_->setStatus(-99);
385    }
386  }
387  //coinAbcFactorization_->setSolveMode(solveMode|1);
388  if ( anyChanged && model->algorithm() < 0 && solveType > 0) {
389    double dummyCost;
390    static_cast<AbcSimplexDual *> (model)->changeBounds(3,dummyCost);
391  }
392  return coinAbcFactorization_->status();
393}
394#if 0
395/* Checks if can replace one Column to basis,
396   returns 0=OK, 1=Probably OK, 2=singular, 3=no room, 5 max pivots
397   Fills in region for use later
398   partial update already in U */
399int
400AbcSimplexFactorization::checkReplace ( const AbcSimplex * model,
401                                        CoinIndexedVector * regionSparse,
402                                        int pivotRow,
403                                        double &pivotCheck,
404                                        double acceptablePivot)
405{
406  if (pivots()==maximumPivots())
407    return 5;
408  else
409    return coinAbcFactorization_->checkReplace(model,regionSparse,pivotRow,pivotCheck,acceptablePivot);
410}
411/* Replaces one Column in basis,
412   returns 0=OK, 1=Probably OK, 2=singular, 3=no room
413   If skipBtranU is false will do btran part
414   partial update already in U */
415int
416AbcSimplexFactorization::replaceColumn ( const AbcSimplex * model,
417                                         CoinIndexedVector * regionSparse,
418                                         CoinIndexedVector * tableauColumn,
419                                         int pivotRow,
420                                         double pivotCheck ,
421                                         bool skipBtranU,
422                                         double acceptablePivot)
423{
424  bool tab = coinAbcFactorization_->wantsTableauColumn();
425  int tempInfo[1];
426  tempInfo[0] = model->numberIterations();
427  coinAbcFactorization_->setUsefulInformation(tempInfo, 1);
428  int returnCode =
429    coinAbcFactorization_->replaceColumn(tab ? tableauColumn : regionSparse,
430                                       pivotRow,
431                                       pivotCheck,
432                                       skipBtranU,
433                                       acceptablePivot);
434  return returnCode;
435}
436#endif
437/* Replaces one Column to basis,
438   partial update already in U */
439void 
440AbcSimplexFactorization::replaceColumnPart3 ( const AbcSimplex * model,
441                                              CoinIndexedVector * regionSparse,
442                                              CoinIndexedVector * tableauColumn,
443                                              int pivotRow,
444#ifdef ABC_LONG_FACTORIZATION
445                                              long
446#endif
447                                              double alpha )
448{
449  bool tab = coinAbcFactorization_->wantsTableauColumn();
450  int tempInfo[1];
451  tempInfo[0] = model->numberIterations();
452  coinAbcFactorization_->setUsefulInformation(tempInfo, 1);
453  if (tab)
454    coinAbcFactorization_->replaceColumnPart3(model,NULL,tableauColumn,
455                                       pivotRow,
456                                              tableauColumn->denseVector()[pivotRow]);
457  else
458    coinAbcFactorization_->replaceColumnPart3(model,regionSparse,NULL,
459                                              pivotRow,
460                                              alpha);
461}
462/* Replaces one Column to basis,
463   partial update in vector */
464void 
465AbcSimplexFactorization::replaceColumnPart3 ( const AbcSimplex * model,
466                                              CoinIndexedVector * regionSparse,
467                                              CoinIndexedVector * tableauColumn,
468                                              CoinIndexedVector * partialUpdate,
469                                              int pivotRow,
470#ifdef ABC_LONG_FACTORIZATION
471                                              long
472#endif
473                                              double alpha )
474{
475  bool tab = coinAbcFactorization_->wantsTableauColumn();
476  int tempInfo[1];
477  tempInfo[0] = model->numberIterations();
478  coinAbcFactorization_->setUsefulInformation(tempInfo, 1);
479  if (tab)
480    coinAbcFactorization_->replaceColumnPart3(model,NULL,tableauColumn,
481                                              pivotRow,
482                                              tableauColumn->denseVector()[pivotRow]);
483  else
484    coinAbcFactorization_->replaceColumnPart3(model,regionSparse,NULL,partialUpdate,
485                                              pivotRow,
486                                              alpha);
487}
488#if 0
489/* Updates one column (FTRAN) from region2
490   number returned is negative if no room
491   region1 starts as zero and is zero at end */
492int
493AbcSimplexFactorization::updateColumnFT ( CoinIndexedVector * regionSparse,
494                                          CoinIndexedVector * regionSparse2)
495{
496  if (!numberRows())
497    return 0;
498  int returnCode;
499  returnCode = coinAbcFactorization_->updateColumnFT(regionSparse,
500                                                   regionSparse2);
501  return returnCode;
502}
503/* Updates one column (FTRAN) from region2
504   number returned is negative if no room
505   region1 starts as zero and is zero at end */
506int
507AbcSimplexFactorization::updateColumn ( CoinIndexedVector * regionSparse,
508                                        CoinIndexedVector * regionSparse2) const
509{
510  if (!numberRows())
511    return 0;
512  int returnCode;
513  returnCode = coinAbcFactorization_->updateColumn(regionSparse,
514                                                 regionSparse2,true);
515  return returnCode;
516}
517/* Updates one column (FTRAN) from region2
518   Tries to do FT update
519   number returned is negative if no room.
520   Also updates region3
521   region1 starts as zero and is zero at end */
522int
523AbcSimplexFactorization::updateTwoColumnsFT ( CoinIndexedVector * regionSparse1,
524                                              CoinIndexedVector * regionSparse2,
525                                              CoinIndexedVector * regionSparse3)
526{
527  if (!numberRows())
528    return 0;
529  int returnCode = 0;
530  returnCode =
531    coinAbcFactorization_->updateTwoColumnsFT(
532                                            regionSparse1,
533                                            regionSparse2,
534                                            regionSparse3,
535                                            true);
536  return returnCode;
537}
538/* Updates one column (BTRAN) from region2
539   region1 starts as zero and is zero at end */
540int
541AbcSimplexFactorization::updateColumnTranspose ( CoinIndexedVector * regionSparse,
542                                                 CoinIndexedVector * regionSparse2) const
543{
544  if (!numberRows())
545    return 0;
546  int returnCode;
547  returnCode = coinAbcFactorization_->updateColumnTranspose(regionSparse,
548                                                          regionSparse2);
549  return returnCode;
550}
551/* Updates one column for dual steepest edge weights (FTRAN) */
552void
553AbcSimplexFactorization::updateWeights ( CoinIndexedVector & regionSparse) const
554{
555  // NOTE either switch off sparse or pass in a sparseArray_ so can go parallel
556  // may be best to use inner product approach
557  static double fraction[2]={0.0,0.0};
558  static int times=0;
559  times++;
560  fraction[0] += static_cast<double>(regionSparse.getNumElements())/
561    (static_cast<double>(model_->numberRows())+1.0);
562  updateColumn(regionSparse);
563  fraction[1] += static_cast<double>(regionSparse.getNumElements())/
564    (static_cast<double>(model_->numberRows())+1.0);
565  if ((times%1000)==0)
566    printf("Average density %g before then %g\n",
567           (100.0*fraction[0])/static_cast<double>(times),
568           (100.0*fraction[1])/static_cast<double>(times));
569}
570#endif
571/* makes a row copy of L for speed and to allow very sparse problems */
572void
573AbcSimplexFactorization::goSparse()
574{
575  abort();
576  coinAbcFactorization_->goSparse();
577}
578// Set tolerances to safer of existing and given
579void
580AbcSimplexFactorization::saferTolerances (  double zeroValue,
581                                            double pivotValue)
582{
583  double newValue1;
584  // better to have small tolerance even if slower
585  if (zeroValue > 0.0)
586    newValue1 = zeroValue;
587  else
588    newValue1 = -zeroTolerance() * zeroValue; 
589  newValue1 = CoinMin(zeroTolerance(),newValue1);
590  if (newValue1>1.0e-15)
591    zeroTolerance(newValue1);
592  double  newValue2;
593  // better to have large tolerance even if slower
594  if (pivotValue > 0.0)
595    newValue2 = pivotValue;
596  else
597    newValue2 = -pivotTolerance() * pivotValue;
598  newValue2 =CoinMin(CoinMax(pivotTolerance(), newValue2), 0.999);
599  if (newValue2>pivotTolerance()) {
600    pivotTolerance(newValue2);
601    char line[100];
602    sprintf(line,"new zero tolerance %g new pivot tolerance %g",
603            zeroTolerance(),pivotTolerance());
604    model_->messageHandler()->message(CLP_GENERAL2,*model_->messagesPointer())
605      << line << CoinMessageEol;
606  }
607}
608// Sets factorization
609void
610AbcSimplexFactorization::setFactorization(AbcSimplexFactorization & rhs)
611{
612  AbcSimplexFactorization::operator=(rhs);
613}
614#endif
Note: See TracBrowser for help on using the repository browser.