|
PPL
0.12.1
|
00001 /* Sparse_Matrix class implementation (non-inline functions). 00002 Copyright (C) 2001-2010 Roberto Bagnara <bagnara@cs.unipr.it> 00003 Copyright (C) 2010-2012 BUGSENG srl (http://bugseng.com) 00004 00005 This file is part of the Parma Polyhedra Library (PPL). 00006 00007 The PPL is free software; you can redistribute it and/or modify it 00008 under the terms of the GNU General Public License as published by the 00009 Free Software Foundation; either version 3 of the License, or (at your 00010 option) any later version. 00011 00012 The PPL is distributed in the hope that it will be useful, but WITHOUT 00013 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00014 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 00015 for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with this program; if not, write to the Free Software Foundation, 00019 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307, USA. 00020 00021 For the most up-to-date information see the Parma Polyhedra Library 00022 site: http://bugseng.com/products/ppl/ . */ 00023 00024 #include "ppl-config.h" 00025 #include "Sparse_Matrix.defs.hh" 00026 00027 namespace PPL = Parma_Polyhedra_Library; 00028 00029 PPL::Sparse_Matrix::Sparse_Matrix(dimension_type n, Flags row_flags) 00030 : rows(n), num_columns_(n) { 00031 for (dimension_type i = 0; i < rows.size(); ++i) { 00032 rows[i].set_flags(row_flags); 00033 rows[i].resize(num_columns_); 00034 } 00035 PPL_ASSERT(OK()); 00036 } 00037 00038 PPL::Sparse_Matrix::Sparse_Matrix(dimension_type num_rows, 00039 dimension_type num_columns, 00040 Flags row_flags) 00041 : rows(num_rows), num_columns_(num_columns) { 00042 for (dimension_type i = 0; i < rows.size(); ++i) { 00043 rows[i].set_flags(row_flags); 00044 rows[i].resize(num_columns_); 00045 } 00046 PPL_ASSERT(OK()); 00047 } 00048 00049 void 00050 PPL::Sparse_Matrix::resize(dimension_type num_rows, 00051 dimension_type num_columns, 00052 Flags row_flags) { 00053 const dimension_type old_num_rows = rows.size(); 00054 rows.resize(num_rows); 00055 if (old_num_rows < num_rows) { 00056 for (dimension_type i = old_num_rows; i < num_rows; ++i) { 00057 rows[i].set_flags(row_flags); 00058 rows[i].resize(num_columns); 00059 } 00060 if (num_columns_ != num_columns) { 00061 num_columns_ = num_columns; 00062 for (dimension_type i = 0; i < old_num_rows; ++i) 00063 rows[i].resize(num_columns); 00064 } 00065 } else 00066 if (num_columns_ != num_columns) { 00067 num_columns_ = num_columns; 00068 for (dimension_type i = 0; i < num_rows; ++i) 00069 rows[i].resize(num_columns); 00070 } 00071 PPL_ASSERT(OK()); 00072 } 00073 00074 void 00075 PPL::Sparse_Matrix 00076 ::permute_columns(const std::vector<dimension_type>& cycles) { 00077 PPL_DIRTY_TEMP_COEFFICIENT(tmp); 00078 const dimension_type n = cycles.size(); 00079 PPL_ASSERT(cycles[n - 1] == 0); 00080 for (dimension_type k = num_rows(); k-- > 0; ) { 00081 Sparse_Row& rows_k = (*this)[k]; 00082 for (dimension_type i = 0, j = 0; i < n; i = ++j) { 00083 // Make `j' be the index of the next cycle terminator. 00084 while (cycles[j] != 0) 00085 ++j; 00086 // Cycles of length less than 2 are not allowed. 00087 PPL_ASSERT(j - i >= 2); 00088 if (j - i == 2) 00089 // For cycles of length 2 no temporary is needed, just a swap. 00090 rows_k.m_swap(cycles[i], cycles[i + 1]); 00091 else { 00092 // Longer cycles need a temporary. 00093 tmp = rows_k.get(cycles[j - 1]); 00094 for (dimension_type l = (j - 1); l > i; --l) 00095 rows_k.m_swap(cycles[l-1], cycles[l]); 00096 if (tmp == 0) 00097 rows_k.reset(cycles[i]); 00098 else { 00099 using std::swap; 00100 swap(tmp, rows_k[cycles[i]]); 00101 } 00102 } 00103 } 00104 } 00105 } 00106 00107 void 00108 PPL::Sparse_Matrix::add_zero_columns(dimension_type n, dimension_type i) { 00109 for (dimension_type j = rows.size(); j-- > 0; ) 00110 rows[j].add_zeroes_and_shift(n, i); 00111 num_columns_ += n; 00112 PPL_ASSERT(OK()); 00113 } 00114 00115 void 00116 PPL::Sparse_Matrix::remove_column(dimension_type i) { 00117 for (dimension_type j = rows.size(); j-- > 0; ) 00118 rows[j].delete_element_and_shift(i); 00119 --num_columns_; 00120 PPL_ASSERT(OK()); 00121 } 00122 00123 void 00124 PPL::Sparse_Matrix::ascii_dump(std::ostream& s) const { 00125 s << num_rows() << " x "; 00126 s << num_columns() << "\n"; 00127 for (const_iterator i = begin(), i_end = end(); i !=i_end; ++i) 00128 i->ascii_dump(s); 00129 } 00130 00131 PPL_OUTPUT_DEFINITIONS_ASCII_ONLY(Sparse_Matrix) 00132 00133 bool 00134 PPL::Sparse_Matrix::ascii_load(std::istream& s) { 00135 std::string str; 00136 dimension_type new_num_rows; 00137 dimension_type new_num_cols; 00138 if (!(s >> new_num_rows)) 00139 return false; 00140 if (!(s >> str) || str != "x") 00141 return false; 00142 if (!(s >> new_num_cols)) 00143 return false; 00144 00145 for (iterator i = rows.begin(), i_end = rows.end(); i != i_end; ++i) 00146 i->clear(); 00147 00148 resize(new_num_rows, new_num_cols); 00149 00150 for (dimension_type row = 0; row < new_num_rows; ++row) 00151 if (!rows[row].ascii_load(s)) 00152 return false; 00153 00154 // Check invariants. 00155 PPL_ASSERT(OK()); 00156 return true; 00157 } 00158 00159 PPL::memory_size_type 00160 PPL::Sparse_Matrix::external_memory_in_bytes() const { 00161 // Estimate the size of vector. 00162 memory_size_type n = rows.capacity() * sizeof(Sparse_Row); 00163 for (const_iterator i = begin(), i_end = end(); i != i_end; ++i) 00164 n += i->external_memory_in_bytes(); 00165 return n; 00166 } 00167 00168 bool 00169 PPL::Sparse_Matrix::OK() const { 00170 for (const_iterator i = begin(), i_end = end(); i != i_end; ++i) 00171 if (i->size() != num_columns_) 00172 return false; 00173 return true; 00174 } 00175 00177 bool 00178 PPL::operator==(const Sparse_Matrix& x, const Sparse_Matrix& y) { 00179 if (x.num_rows() != y.num_rows()) 00180 return false; 00181 if (x.num_columns() != y.num_columns()) 00182 return false; 00183 for (dimension_type i = x.num_rows(); i-- > 0; ) 00184 if (x[i] != y[i]) 00185 return false; 00186 return true; 00187 } 00188 00190 bool 00191 PPL::operator!=(const Sparse_Matrix& x, const Sparse_Matrix& y) { 00192 return !(x == y); 00193 }