/* $Id: ClpCholeskyBase.hpp 1722 2011-04-17 09:58:37Z stefan $ */ // Copyright (C) 2003, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). #ifndef ClpCholeskyBase_H #define ClpCholeskyBase_H #include "CoinPragma.hpp" #include "CoinTypes.hpp" //#define CLP_LONG_CHOLESKY 0 #ifndef CLP_LONG_CHOLESKY #define CLP_LONG_CHOLESKY 0 #endif /* valid combinations are CLP_LONG_CHOLESKY 0 and COIN_LONG_WORK 0 CLP_LONG_CHOLESKY 1 and COIN_LONG_WORK 1 CLP_LONG_CHOLESKY 2 and COIN_LONG_WORK 1 */ #if COIN_LONG_WORK==0 #if CLP_LONG_CHOLESKY>0 #define CHOLESKY_BAD_COMBINATION #endif #else #if CLP_LONG_CHOLESKY==0 #define CHOLESKY_BAD_COMBINATION #endif #endif #ifdef CHOLESKY_BAD_COMBINATION # warning("Bad combination of CLP_LONG_CHOLESKY and COIN_BIG_DOUBLE/COIN_LONG_WORK"); "Bad combination of CLP_LONG_CHOLESKY and COIN_LONG_WORK" #endif #if CLP_LONG_CHOLESKY>1 typedef long double longDouble; #define CHOL_SMALL_VALUE 1.0e-15 #elif CLP_LONG_CHOLESKY==1 typedef double longDouble; #define CHOL_SMALL_VALUE 1.0e-11 #else typedef double longDouble; #define CHOL_SMALL_VALUE 1.0e-11 #endif class ClpInterior; class ClpCholeskyDense; class ClpMatrixBase; /** Base class for Clp Cholesky factorization Will do better factorization. very crude ordering Derived classes may be using more sophisticated methods */ class ClpCholeskyBase { public: /**@name Virtual methods that the derived classes may provide */ //@{ /** Orders rows and saves pointer to matrix.and model. returns non-zero if not enough memory. You can use preOrder to set up ADAT If using default symbolic etc then must set sizeFactor_ to size of input matrix to order (and to symbolic). Also just permute_ and permuteInverse_ should be created */ virtual int order(ClpInterior * model); /** Does Symbolic factorization given permutation. This is called immediately after order. If user provides this then user must provide factorize and solve. Otherwise the default factorization is used returns non-zero if not enough memory */ virtual int symbolic(); /** Factorize - filling in rowsDropped and returning number dropped. If return code negative then out of memory */ virtual int factorize(const CoinWorkDouble * diagonal, int * rowsDropped) ; /** Uses factorization to solve. */ virtual void solve (CoinWorkDouble * region) ; /** Uses factorization to solve. - given as if KKT. region1 is rows+columns, region2 is rows */ virtual void solveKKT (CoinWorkDouble * region1, CoinWorkDouble * region2, const CoinWorkDouble * diagonal, CoinWorkDouble diagonalScaleFactor); private: /// AMD ordering int orderAMD(); public: //@} /**@name Gets */ //@{ /// status. Returns status inline int status() const { return status_; } /// numberRowsDropped. Number of rows gone inline int numberRowsDropped() const { return numberRowsDropped_; } /// reset numberRowsDropped and rowsDropped. void resetRowsDropped(); /// rowsDropped - which rows are gone inline char * rowsDropped() const { return rowsDropped_; } /// choleskyCondition. inline double choleskyCondition() const { return choleskyCondition_; } /// goDense i.e. use dense factoriaztion if > this (default 0.7). inline double goDense() const { return goDense_; } /// goDense i.e. use dense factoriaztion if > this (default 0.7). inline void setGoDense(double value) { goDense_ = value; } /// rank. Returns rank inline int rank() const { return numberRows_ - numberRowsDropped_; } /// Return number of rows inline int numberRows() const { return numberRows_; } /// Return size inline CoinBigIndex size() const { return sizeFactor_; } /// Return sparseFactor inline longDouble * sparseFactor() const { return sparseFactor_; } /// Return diagonal inline longDouble * diagonal() const { return diagonal_; } /// Return workDouble inline longDouble * workDouble() const { return workDouble_; } /// If KKT on inline bool kkt() const { return doKKT_; } /// Set KKT inline void setKKT(bool yesNo) { doKKT_ = yesNo; } /// Set integer parameter inline void setIntegerParameter(int i, int value) { integerParameters_[i] = value; } /// get integer parameter inline int getIntegerParameter(int i) { return integerParameters_[i]; } /// Set double parameter inline void setDoubleParameter(int i, double value) { doubleParameters_[i] = value; } /// get double parameter inline double getDoubleParameter(int i) { return doubleParameters_[i]; } //@} public: /**@name Constructors, destructor */ //@{ /** Constructor which has dense columns activated. Default is off. */ ClpCholeskyBase(int denseThreshold = -1); /** Destructor (has to be public) */ virtual ~ClpCholeskyBase(); /// Copy ClpCholeskyBase(const ClpCholeskyBase&); /// Assignment ClpCholeskyBase& operator=(const ClpCholeskyBase&); //@} //@{ ///@name Other /// Clone virtual ClpCholeskyBase * clone() const; /// Returns type inline int type() const { if (doKKT_) return 100; else return type_; } protected: /// Sets type inline void setType(int type) { type_ = type; } /// model. inline void setModel(ClpInterior * model) { model_ = model; } //@} /**@name Symbolic, factor and solve */ //@{ /** Symbolic1 - works out size without clever stuff. Uses upper triangular as much easier. Returns size */ int symbolic1(const CoinBigIndex * Astart, const int * Arow); /** Symbolic2 - Fills in indices Uses lower triangular so can do cliques etc */ void symbolic2(const CoinBigIndex * Astart, const int * Arow); /** Factorize - filling in rowsDropped and returning number dropped in integerParam. */ void factorizePart2(int * rowsDropped) ; /** solve - 1 just first half, 2 just second half - 3 both. If 1 and 2 then diagonal has sqrt of inverse otherwise inverse */ void solve(CoinWorkDouble * region, int type); /// Forms ADAT - returns nonzero if not enough memory int preOrder(bool lowerTriangular, bool includeDiagonal, bool doKKT); /// Updates dense part (broken out for profiling) void updateDense(longDouble * d, /*longDouble * work,*/ int * first); //@} protected: /**@name Data members The data members are protected to allow access for derived classes. */ //@{ /// type (may be useful) if > 20 do KKT int type_; /// Doing full KKT (only used if default symbolic and factorization) bool doKKT_; /// Go dense at this fraction double goDense_; /// choleskyCondition. double choleskyCondition_; /// model. ClpInterior * model_; /// numberTrials. Number of trials before rejection int numberTrials_; /// numberRows. Number of Rows in factorization int numberRows_; /// status. Status of factorization int status_; /// rowsDropped char * rowsDropped_; /// permute inverse. int * permuteInverse_; /// main permute. int * permute_; /// numberRowsDropped. Number of rows gone int numberRowsDropped_; /// sparseFactor. longDouble * sparseFactor_; /// choleskyStart - element starts CoinBigIndex * choleskyStart_; /// choleskyRow (can be shorter than sparsefactor) int * choleskyRow_; /// Index starts CoinBigIndex * indexStart_; /// Diagonal longDouble * diagonal_; /// double work array longDouble * workDouble_; /// link array int * link_; // Integer work array CoinBigIndex * workInteger_; // Clique information int * clique_; /// sizeFactor. CoinBigIndex sizeFactor_; /// Size of index array CoinBigIndex sizeIndex_; /// First dense row int firstDense_; /// integerParameters int integerParameters_[64]; /// doubleParameters; double doubleParameters_[64]; /// Row copy of matrix ClpMatrixBase * rowCopy_; /// Dense indicators char * whichDense_; /// Dense columns (updated) longDouble * denseColumn_; /// Dense cholesky ClpCholeskyDense * dense_; /// Dense threshold (for taking out of Cholesky) int denseThreshold_; //@} }; #endif