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

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