/home/coin/SVN-release/OS-2.1.0/Bonmin/src/Algorithms/QuadCuts/BonTMatrix.cpp

Go to the documentation of this file.
00001 // (C) Copyright International Business Machines Corporation 2007
00002 // All Rights Reserved.
00003 // This code is published under the Common Public License.
00004 //
00005 // Authors :
00006 // Pierre Bonami, International Business Machines Corporation
00007 //
00008 // Date : 10/06/2007
00009 
00010 #include "BonTMatrix.hpp"
00011 
00012 namespace Bonmin{
00013 
00015 TMat::TMat(const TMat &other):
00016   iRow_(NULL), jCol_(NULL), value_(NULL), nnz_(other.nnz_),
00017   capacity_(other.nnz_), columnOrdering_(other.columnOrdering_),
00018   rowOrdering_(other.rowOrdering_), nonEmptyRows_(), nonEmptyCols_(){
00019    iRow_ = CoinCopyOfArray(other.iRow_, other.nnz_);
00020    jCol_ = CoinCopyOfArray(other.jCol_, other.nnz_);
00021    value_ = CoinCopyOfArray(other.value_, other.nnz_);
00022   }
00023 
00025 TMat::TMat(const CoinPackedMatrix &M, MatrixStorageType T):
00026   iRow_(NULL), jCol_(NULL), value_(NULL), nnz_(M.getNumElements()),
00027   capacity_(M.getNumElements()), columnOrdering_(), rowOrdering_(),
00028   nonEmptyRows_(), nonEmptyCols_(){
00029   create(M);
00030   make_upper_triangular(T);
00031 }
00033 TMat& 
00034 TMat::operator=(const TMat &rhs){
00035   if(this != &rhs){
00036     freeSpace();
00037     nnz_ = rhs.nnz_;
00038     capacity_ = rhs.capacity_;
00039     iRow_ = CoinCopyOfArray(rhs.iRow_, rhs.nnz_);
00040     jCol_ = CoinCopyOfArray(rhs.jCol_, rhs.nnz_);
00041     value_ = CoinCopyOfArray(rhs.value_, rhs.nnz_);
00042     columnOrdering_ = rhs.columnOrdering_;
00043     rowOrdering_ = rhs.rowOrdering_; 
00044     nonEmptyCols_.clear();
00045     nonEmptyRows_.clear();
00046   }
00047   return (*this);
00048 }
00049 
00051 TMat & 
00052 TMat::operator=(const CoinPackedMatrix &M){
00053   freeSpace();
00054   columnOrdering_.clear();
00055   rowOrdering_.clear();
00056   nnz_ = capacity_ = M.getNumElements();
00057   create(M); 
00058   return (*this);
00059 }
00060 
00061 void TMat::create(const CoinPackedMatrix &M){ 
00062   // Allocate arrays;
00063   iRow_ = new int[capacity_];
00064   jCol_ = new int[capacity_];
00065   value_ = new double[capacity_];
00066 
00067   int * iRow = iRow_;
00068   int * jCol = jCol_;
00069   if(!M.isColOrdered()){// Have to swap
00070     std::cout<<"Matrix is not col ordered"<<std::endl;
00071     iRow = jCol_;
00072     jCol = iRow_;
00073   }
00074   
00075   // Now we can safely assume that M is colorderd.
00076   int numcols = M.getMajorDim();
00077   const int * start = M.getVectorStarts();
00078   const int * length = M.getVectorLengths();
00079   const int * indice = M.getIndices();
00080   const double * value = M.getElements();
00081   int nnz = 0;
00082   for(int i = 0 ; i < numcols ; i++){
00083     int begin = start[i];
00084     int end = start[i] + length[i];
00085     for(int k = begin ; k < end ; k++){
00086       value_[nnz] = value[k];
00087       iRow[nnz] = indice[k];
00088       jCol[nnz++] = i;
00089     }
00090   }
00091   assert(nnz==nnz_);
00092 }
00093 
00094 // Destructor
00095 TMat::~TMat(){
00096    delete [] iRow_;
00097    delete [] jCol_;
00098    delete [] value_;
00099 }
00100 
00103 int 
00104 TMat::numNonEmptyRows(){
00105   if(nnz_ == 0) return 0;
00106   orderByRows();
00107   nonEmptyRows_.clear();
00108   nonEmptyRows_.push_back(std::pair<int, int>(iRow_[rowOrdering_[0]], 0));
00109   int num = 1;
00110   for(int i = 1 ; i < nnz_ ; i++){
00111     if(iRow_[rowOrdering_[i]] > nonEmptyRows_.back().first){
00112       nonEmptyRows_.push_back(std::pair<int, int>(iRow_[rowOrdering_[i]],i));
00113       num++;
00114     }
00115   }
00116   return num;
00117 }
00118 
00119 
00122 int 
00123 TMat::numNonEmptyCols(){
00124   if(nnz_ == 0) return 0;
00125   orderByColumns();
00126   nonEmptyCols_.clear();
00127   nonEmptyCols_.push_back(std::pair<int, int>(jCol_[columnOrdering_[0]], 0));
00128   int num = 1;
00129   for(int i = 1 ; i < nnz_ ; i++){
00130     if(jCol_[columnOrdering_[i]] > nonEmptyCols_.back().first){
00131       nonEmptyCols_.push_back(std::pair<int, int>(jCol_[columnOrdering_[i]],i));
00132       num++;
00133     }
00134   }
00135   return num;
00136 }
00138 void 
00139 TMat::removeDuplicates(){
00140   orderByRows();
00141   int j = 0;
00142   for(int i = 1; i < nnz_ ; i++){
00143     if((jCol_[rowOrdering_[i]] == jCol_[rowOrdering_[j]]) && 
00144        (iRow_[rowOrdering_[i]] == iRow_[rowOrdering_[j]])){
00145        value_[rowOrdering_[j]] += value_[rowOrdering_[i]];
00146     }
00147     else{
00148       jCol_[rowOrdering_[++j]] = jCol_[rowOrdering_[i]];
00149       iRow_[rowOrdering_[j]] = iRow_[rowOrdering_[i]];
00150       value_[rowOrdering_[j]] = value_[rowOrdering_[i]];
00151     }
00152   }
00153   resizeAndCopyArray(jCol_, j, capacity_);
00154   resizeAndCopyArray(iRow_, j, capacity_);
00155   resizeAndCopyArray(value_, j, capacity_);
00156   nnz_ = j;
00157 }
00158 
00159 void
00160 TMat::make_upper_triangular(const MatrixStorageType &T){
00161    switch (T){
00162      case Upper:
00163        for(int i = 0 ; i < nnz_ ; i++){
00164           assert(jCol_[i] >= iRow_[i]);
00165        }
00166        break;
00167      case Lower:
00168        for(int i = 0 ; i < nnz_ ; i++){
00169           assert(jCol_[i] <= iRow_[i]);
00170        }
00171        make_lower_to_be_upper();
00172        break;
00173      case Full:
00174        make_full_upper_triangular();
00175        break;
00176    }
00177    for(int i = 0 ; i < nnz_ ; i++){
00178       assert(jCol_[i] >= iRow_[i]);
00179    }
00180 }
00181 
00184 void
00185 TMat::make_lower_to_be_upper(){
00186   int * buff = iRow_;
00187   iRow_ = jCol_;
00188   jCol_ = buff;
00189 }
00190 
00192 void
00193 TMat::make_full_upper_triangular(){
00194   // Make it upper triangular
00195   for(int i = 0 , j = 0; i < nnz_ && j < nnz_ ;){
00196     if(iRow_[i] < jCol_[i]){//swap the two entries
00197       int buf = iRow_[i];
00198       iRow_[i] = jCol_[i];
00199       jCol_[i] = buf;
00200     }
00201   }
00202   // add up the duplicated entries
00203   removeDuplicates();
00204 
00205   //Now divide all non-diagonal entries by two;
00206   for(int i = 0 ; i < nnz_ ; i++){
00207     if(jCol_[i] == iRow_[i]){//skip
00208       continue;
00209     }
00210     assert(iRow_[i] < jCol_[i]);
00211     value_[i] /= 2.;
00212   }
00213 }
00214 
00215 }//Ends Bonmin namepace
00216 

Generated on Tue Mar 30 03:04:34 2010 by  doxygen 1.4.7