1 /* DB_Matrix class implementation: inline functions.
2 Copyright (C) 2001-2010 Roberto Bagnara <bagnara@cs.unipr.it>
3 Copyright (C) 2010-2016 BUGSENG srl (http://bugseng.com)
4
5 This file is part of the Parma Polyhedra Library (PPL).
6
7 The PPL is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11
12 The PPL is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software Foundation,
19 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307, USA.
20
21 For the most up-to-date information see the Parma Polyhedra Library
22 site: http://bugseng.com/products/ppl/ . */
23
24 #ifndef PPL_DB_Matrix_inlines_hh
25 #define PPL_DB_Matrix_inlines_hh 1
26
27 #include "globals_defs.hh"
28 #include "Checked_Number_defs.hh"
29 #include "distances_defs.hh"
30 #include "assertions.hh"
31 #include <iostream>
32
33 namespace Parma_Polyhedra_Library {
34
35 template <typename T>
36 inline void
m_swap(DB_Matrix & y)37 DB_Matrix<T>::m_swap(DB_Matrix& y) {
38 using std::swap;
39 swap(rows, y.rows);
40 swap(row_size, y.row_size);
41 swap(row_capacity, y.row_capacity);
42 }
43
44 template <typename T>
45 inline dimension_type
max_num_rows()46 DB_Matrix<T>::max_num_rows() {
47 return std::vector<DB_Row<T> >().max_size();
48 }
49
50 template <typename T>
51 inline dimension_type
max_num_columns()52 DB_Matrix<T>::max_num_columns() {
53 return DB_Row<T>::max_size();
54 }
55
56 template <typename T>
57 inline memory_size_type
total_memory_in_bytes() const58 DB_Matrix<T>::total_memory_in_bytes() const {
59 return sizeof(*this) + external_memory_in_bytes();
60 }
61
62 template <typename T>
63 inline
const_iterator()64 DB_Matrix<T>::const_iterator::const_iterator()
65 : i(Iter()) {
66 }
67
68 template <typename T>
69 inline
const_iterator(const Iter & b)70 DB_Matrix<T>::const_iterator::const_iterator(const Iter& b)
71 : i(b) {
72 }
73
74 template <typename T>
75 inline
const_iterator(const const_iterator & y)76 DB_Matrix<T>::const_iterator::const_iterator(const const_iterator& y)
77 : i(y.i) {
78 }
79
80 template <typename T>
81 inline typename DB_Matrix<T>::const_iterator&
operator =(const const_iterator & y)82 DB_Matrix<T>::const_iterator::operator=(const const_iterator& y) {
83 i = y.i;
84 return *this;
85 }
86
87 template <typename T>
88 inline typename DB_Matrix<T>::const_iterator::reference
operator *() const89 DB_Matrix<T>::const_iterator::operator*() const {
90 return *i;
91 }
92
93 template <typename T>
94 inline typename DB_Matrix<T>::const_iterator::pointer
operator ->() const95 DB_Matrix<T>::const_iterator::operator->() const {
96 return &*i;
97 }
98
99 template <typename T>
100 inline typename DB_Matrix<T>::const_iterator&
operator ++()101 DB_Matrix<T>::const_iterator::operator++() {
102 ++i;
103 return *this;
104 }
105
106 template <typename T>
107 inline typename DB_Matrix<T>::const_iterator
operator ++(int)108 DB_Matrix<T>::const_iterator::operator++(int) {
109 return const_iterator(i++);
110 }
111
112 template <typename T>
113 inline bool
operator ==(const const_iterator & y) const114 DB_Matrix<T>::const_iterator::operator==(const const_iterator& y) const {
115 return i == y.i;
116 }
117
118 template <typename T>
119 inline bool
operator !=(const const_iterator & y) const120 DB_Matrix<T>::const_iterator::operator!=(const const_iterator& y) const {
121 return !operator==(y);
122 }
123
124 template <typename T>
125 inline typename DB_Matrix<T>::const_iterator
begin() const126 DB_Matrix<T>::begin() const {
127 return const_iterator(rows.begin());
128 }
129
130 template <typename T>
131 inline typename DB_Matrix<T>::const_iterator
end() const132 DB_Matrix<T>::end() const {
133 return const_iterator(rows.end());
134 }
135
136 template <typename T>
137 inline
DB_Matrix()138 DB_Matrix<T>::DB_Matrix()
139 : rows(),
140 row_size(0),
141 row_capacity(0) {
142 }
143
144 template <typename T>
145 inline
~DB_Matrix()146 DB_Matrix<T>::~DB_Matrix() {
147 }
148
149 template <typename T>
150 inline DB_Row<T>&
operator [](const dimension_type k)151 DB_Matrix<T>::operator[](const dimension_type k) {
152 PPL_ASSERT(k < rows.size());
153 return rows[k];
154 }
155
156 template <typename T>
157 inline const DB_Row<T>&
operator [](const dimension_type k) const158 DB_Matrix<T>::operator[](const dimension_type k) const {
159 PPL_ASSERT(k < rows.size());
160 return rows[k];
161 }
162
163 template <typename T>
164 inline dimension_type
num_rows() const165 DB_Matrix<T>::num_rows() const {
166 return rows.size();
167 }
168
169 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
170 /*! \relates DB_Matrix */
171 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
172 template <typename T>
173 inline bool
operator !=(const DB_Matrix<T> & x,const DB_Matrix<T> & y)174 operator!=(const DB_Matrix<T>& x, const DB_Matrix<T>& y) {
175 return !(x == y);
176 }
177
178 template <typename T>
179 inline
DB_Matrix(const DB_Matrix & y)180 DB_Matrix<T>::DB_Matrix(const DB_Matrix& y)
181 : rows(y.rows),
182 row_size(y.row_size),
183 row_capacity(compute_capacity(y.row_size, max_num_columns())) {
184 }
185
186 template <typename T>
187 inline DB_Matrix<T>&
operator =(const DB_Matrix & y)188 DB_Matrix<T>::operator=(const DB_Matrix& y) {
189 // Without the following guard against auto-assignments we would
190 // recompute the row capacity based on row size, possibly without
191 // actually increasing the capacity of the rows. This would lead to
192 // an inconsistent state.
193 if (this != &y) {
194 // The following assignment may do nothing on auto-assignments...
195 rows = y.rows;
196 row_size = y.row_size;
197 // ... hence the following assignment must not be done on
198 // auto-assignments.
199 row_capacity = compute_capacity(y.row_size, max_num_columns());
200 }
201 return *this;
202 }
203
204 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
205 /*! \relates DB_Matrix */
206 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
207 template <typename Specialization, typename Temp, typename To, typename T>
208 inline bool
l_m_distance_assign(Checked_Number<To,Extended_Number_Policy> & r,const DB_Matrix<T> & x,const DB_Matrix<T> & y,const Rounding_Dir dir,Temp & tmp0,Temp & tmp1,Temp & tmp2)209 l_m_distance_assign(Checked_Number<To, Extended_Number_Policy>& r,
210 const DB_Matrix<T>& x,
211 const DB_Matrix<T>& y,
212 const Rounding_Dir dir,
213 Temp& tmp0,
214 Temp& tmp1,
215 Temp& tmp2) {
216 const dimension_type x_num_rows = x.num_rows();
217 if (x_num_rows != y.num_rows()) {
218 return false;
219 }
220 assign_r(tmp0, 0, ROUND_NOT_NEEDED);
221 for (dimension_type i = x_num_rows; i-- > 0; ) {
222 const DB_Row<T>& x_i = x[i];
223 const DB_Row<T>& y_i = y[i];
224 for (dimension_type j = x_num_rows; j-- > 0; ) {
225 const T& x_i_j = x_i[j];
226 const T& y_i_j = y_i[j];
227 if (is_plus_infinity(x_i_j)) {
228 if (is_plus_infinity(y_i_j)) {
229 continue;
230 }
231 else {
232 pinf:
233 assign_r(r, PLUS_INFINITY, ROUND_NOT_NEEDED);
234 return true;
235 }
236 }
237 else if (is_plus_infinity(y_i_j)) {
238 goto pinf;
239 }
240 const Temp* tmp1p;
241 const Temp* tmp2p;
242 if (x_i_j > y_i_j) {
243 maybe_assign(tmp1p, tmp1, x_i_j, dir);
244 maybe_assign(tmp2p, tmp2, y_i_j, inverse(dir));
245 }
246 else {
247 maybe_assign(tmp1p, tmp1, y_i_j, dir);
248 maybe_assign(tmp2p, tmp2, x_i_j, inverse(dir));
249 }
250 sub_assign_r(tmp1, *tmp1p, *tmp2p, dir);
251 PPL_ASSERT(sgn(tmp1) >= 0);
252 Specialization::combine(tmp0, tmp1, dir);
253 }
254 }
255 Specialization::finalize(tmp0, dir);
256 assign_r(r, tmp0, dir);
257 return true;
258 }
259
260 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
261 /*! \relates DB_Matrix */
262 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
263 template <typename Temp, typename To, typename T>
264 inline bool
rectilinear_distance_assign(Checked_Number<To,Extended_Number_Policy> & r,const DB_Matrix<T> & x,const DB_Matrix<T> & y,const Rounding_Dir dir,Temp & tmp0,Temp & tmp1,Temp & tmp2)265 rectilinear_distance_assign(Checked_Number<To, Extended_Number_Policy>& r,
266 const DB_Matrix<T>& x,
267 const DB_Matrix<T>& y,
268 const Rounding_Dir dir,
269 Temp& tmp0,
270 Temp& tmp1,
271 Temp& tmp2) {
272 return
273 l_m_distance_assign<Rectilinear_Distance_Specialization<Temp> >(r, x, y,
274 dir,
275 tmp0,
276 tmp1,
277 tmp2);
278 }
279
280
281 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
282 /*! \relates DB_Matrix */
283 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
284 template <typename Temp, typename To, typename T>
285 inline bool
euclidean_distance_assign(Checked_Number<To,Extended_Number_Policy> & r,const DB_Matrix<T> & x,const DB_Matrix<T> & y,const Rounding_Dir dir,Temp & tmp0,Temp & tmp1,Temp & tmp2)286 euclidean_distance_assign(Checked_Number<To, Extended_Number_Policy>& r,
287 const DB_Matrix<T>& x,
288 const DB_Matrix<T>& y,
289 const Rounding_Dir dir,
290 Temp& tmp0,
291 Temp& tmp1,
292 Temp& tmp2) {
293 return
294 l_m_distance_assign<Euclidean_Distance_Specialization<Temp> >(r, x, y,
295 dir,
296 tmp0,
297 tmp1,
298 tmp2);
299 }
300
301 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
302 /*! \relates DB_Matrix */
303 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
304 template <typename Temp, typename To, typename T>
305 inline bool
l_infinity_distance_assign(Checked_Number<To,Extended_Number_Policy> & r,const DB_Matrix<T> & x,const DB_Matrix<T> & y,const Rounding_Dir dir,Temp & tmp0,Temp & tmp1,Temp & tmp2)306 l_infinity_distance_assign(Checked_Number<To, Extended_Number_Policy>& r,
307 const DB_Matrix<T>& x,
308 const DB_Matrix<T>& y,
309 const Rounding_Dir dir,
310 Temp& tmp0,
311 Temp& tmp1,
312 Temp& tmp2) {
313 return
314 l_m_distance_assign<L_Infinity_Distance_Specialization<Temp> >(r, x, y,
315 dir,
316 tmp0,
317 tmp1,
318 tmp2);
319 }
320
321 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
322 /*! \relates DB_Matrix */
323 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
324 template <typename T>
325 inline void
swap(DB_Matrix<T> & x,DB_Matrix<T> & y)326 swap(DB_Matrix<T>& x, DB_Matrix<T>& y) {
327 x.m_swap(y);
328 }
329
330 } // namespace Parma_Polyhedra_Library
331
332 #endif // !defined(PPL_DB_Matrix_inlines_hh)
333