00001
00002
00003
00004
00005
00006
00007
00008
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
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()){
00070 std::cout<<"Matrix is not col ordered"<<std::endl;
00071 iRow = jCol_;
00072 jCol = iRow_;
00073 }
00074
00075
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
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
00195 for(int i = 0 , j = 0; i < nnz_ && j < nnz_ ;){
00196 if(iRow_[i] < jCol_[i]){
00197 int buf = iRow_[i];
00198 iRow_[i] = jCol_[i];
00199 jCol_[i] = buf;
00200 }
00201 }
00202
00203 removeDuplicates();
00204
00205
00206 for(int i = 0 ; i < nnz_ ; i++){
00207 if(jCol_[i] == iRow_[i]){
00208 continue;
00209 }
00210 assert(iRow_[i] < jCol_[i]);
00211 value_[i] /= 2.;
00212 }
00213 }
00214
00215 }
00216