1 /* Sparse_Row class declaration. 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_Sparse_Row_defs_hh 25 #define PPL_Sparse_Row_defs_hh 1 26 27 #include "Sparse_Row_types.hh" 28 29 #include "CO_Tree_defs.hh" 30 #include "Coefficient_defs.hh" 31 #include "Dense_Row_types.hh" 32 33 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 34 //! A finite sparse sequence of coefficients. 35 /*! \ingroup PPL_CXX_interface 36 This class is implemented using a CO_Tree. See the documentation of CO_Tree 37 for details on the implementation and the performance. 38 39 This class is a drop-in replacement of Dense_Row, meaning that code 40 using Dense_Row can be ported to Sparse_Row changing only the type. 41 The resulting code will work, but probably needs more CPU and memory (it 42 does not exploit the sparse representation yet). 43 44 To take advantage of the sparse representation, the client code must then be 45 modified to use methods which can have a faster implementation on sparse 46 data structures. 47 48 The main changes are the replacement of calls to operator[] with calls to 49 find(), lower_bound() or insert(), using hint iterators when possible. 50 Sequential scanning of rows should probably be implemented using iterators 51 rather than indexes, to improve performance. 52 reset() should be called to zero elements. 53 54 \see Sparse_Matrix 55 \see CO_Tree 56 */ 57 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS) 58 class Parma_Polyhedra_Library::Sparse_Row { 59 60 public: 61 62 //! An %iterator on the row elements 63 /*! 64 This %iterator skips non-stored zeroes. 65 \see CO_Tree::iterator 66 */ 67 typedef CO_Tree::iterator iterator; 68 69 //! A const %iterator on the row elements 70 /*! 71 This %iterator skips non-stored zeroes. 72 \see CO_Tree::const_iterator 73 */ 74 typedef CO_Tree::const_iterator const_iterator; 75 76 //! Constructs a row with the specified size. 77 /*! 78 \param n 79 The size for the new row. 80 81 The row will contain only non-stored zeroes. 82 83 This constructor takes \f$O(1)\f$ time. 84 */ 85 explicit Sparse_Row(dimension_type n = 0); 86 87 //! Constructs a row with the specified size. 88 /*! 89 \param n 90 The size for the new row. 91 92 \param capacity 93 It is ignored. This parameter is needed for compatibility with Dense_Row. 94 95 The row will contain only non-stored zeroes. 96 97 This constructor takes \f$O(1)\f$ time. 98 */ 99 Sparse_Row(dimension_type n, dimension_type capacity); 100 101 //! Copy constructor with specified capacity. 102 /*! 103 It is assumed that \p capacity is greater than or equal to 104 the size of \p y. 105 */ 106 Sparse_Row(const Sparse_Row& y, dimension_type capacity); 107 108 //! Copy constructor with specified size and capacity. 109 /*! 110 It is assumed that \p sz is less than or equal to \p capacity. 111 */ 112 Sparse_Row(const Sparse_Row& y, dimension_type sz, dimension_type capacity); 113 114 //! Constructor from a Dense_Row. 115 /*! 116 \param row 117 The row that will be copied into *this. 118 119 This constructor takes \f$O(n)\f$ time. Note that constructing of a row of 120 zeroes and then inserting n elements costs \f$O(n*\log^2 n)\f$ time. 121 */ 122 explicit Sparse_Row(const Dense_Row& row); 123 124 //! Copy constructor from a Dense_Row with specified size and capacity. 125 /*! 126 It is assumed that \p sz is less than or equal to \p capacity. 127 */ 128 Sparse_Row(const Dense_Row& y, dimension_type sz, dimension_type capacity); 129 130 Sparse_Row& operator=(const Dense_Row& row); 131 132 //! Swaps *this and x. 133 /*! 134 \param x 135 The row that will be swapped with *this. 136 137 This method takes \f$O(1)\f$ time. 138 */ 139 void m_swap(Sparse_Row& x); 140 141 //! Returns the size of the row. 142 /*! 143 This method takes \f$O(1)\f$ time. 144 */ 145 dimension_type size() const; 146 147 //! Returns the number of elements explicitly stored in the row. 148 /*! 149 This is equivalent to std::distance(begin(), end()), but it's much faster. 150 151 This method takes \f$O(1)\f$ time. 152 */ 153 dimension_type num_stored_elements() const; 154 155 //! Resizes the row to the specified size. 156 /*! 157 \param n 158 The new size for the row. 159 160 This method takes \f$O(k*\log^2 n)\f$ amortized time when shrinking the 161 row and removing the trailing k elements. 162 It takes \f$O(1)\f$ time when enlarging the row. 163 */ 164 void resize(dimension_type n); 165 166 //! Resizes the row to size \p n. 167 /*! 168 \param n 169 The new size for the row. 170 171 This method, with this signature, is needed for compatibility with 172 Dense_Row. 173 174 This method takes \f$O(1)\f$ time. 175 */ 176 void expand_within_capacity(dimension_type n); 177 178 //! Resizes the row to size \p n. 179 /*! 180 \param n 181 The new size for the row. 182 183 This method, with this signature, is needed for compatibility with 184 Dense_Row. 185 186 This method takes \f$O(k*\log^2 n)\f$ amortized time where k is the number 187 of removed elements. 188 */ 189 void shrink(dimension_type n); 190 191 /*! 192 \brief Deletes the i-th element from the row, shifting the next elements 193 to the left. 194 195 \param i 196 The index of the element that will be deleted. 197 198 The size of the row is decreased by 1. 199 200 This operation invalidates existing iterators. 201 202 This method takes \f$O(k+\log^2 n)\f$ amortized time, where k is the 203 number of elements with index greater than i. 204 */ 205 void delete_element_and_shift(dimension_type i); 206 207 //! Adds \p n zeroes before index \p i. 208 /*! 209 \param n 210 The number of non-stored zeroes that will be added to the row. 211 212 \param i 213 The index of the element before which the zeroes will be added. 214 215 Existing elements with index greater than or equal to \p i are shifted to 216 the right by \p n positions. The size is increased by \p n. 217 218 Existing iterators are not invalidated, but are shifted to the right 219 by \p n if they pointed at or after index \p i (i.e., they point to 220 the same, possibly shifted, values as before). 221 222 This method takes \f$O(k + \log m)\f$ expected time, where \f$k\f$ is 223 the number of elements with index greater than or equal to \p i and 224 \f$m\f$ the number of stored elements. 225 */ 226 void add_zeroes_and_shift(dimension_type n, dimension_type i); 227 228 //! Returns an %iterator that points at the first stored element. 229 /*! 230 This method takes \f$O(1)\f$ time. 231 */ 232 iterator begin(); 233 234 //! Returns an %iterator that points after the last stored element. 235 /*! 236 This method always returns a reference to the same internal %iterator, 237 that is kept valid. 238 Client code can keep a const reference to that %iterator instead of 239 keep updating a local %iterator. 240 241 This method takes \f$O(1)\f$ time. 242 */ 243 const iterator& end(); 244 245 //! Equivalent to <CODE>cbegin()</CODE>. 246 const_iterator begin() const; 247 248 //! Equivalent to <CODE>cend()</CODE>. 249 const const_iterator& end() const; 250 251 //! Returns an %iterator that points at the first element. 252 /*! 253 This method takes \f$O(1)\f$ time. 254 */ 255 const_iterator cbegin() const; 256 257 //! Returns an %iterator that points after the last element. 258 /*! 259 This method always returns a reference to the same internal %iterator, 260 that is updated at each operation that modifies the structure. 261 Client code can keep a const reference to that %iterator instead of 262 keep updating a local %iterator. 263 264 This method takes \f$O(1)\f$ time. 265 */ 266 const const_iterator& cend() const; 267 268 //! Returns the size() of the largest possible Sparse_Row. 269 static dimension_type max_size(); 270 271 //! Resets all the elements of this row. 272 /*! 273 This method takes \f$O(n)\f$ time. 274 */ 275 void clear(); 276 277 //! Gets a reference to the i-th element. 278 /*! 279 \param i 280 The index of the desired element. 281 282 For read-only access it's better to use get(), that avoids allocating 283 space for zeroes. 284 285 If possible, use the insert(), find() or lower_bound() methods with 286 a hint instead of this, to improve performance. 287 288 This operation invalidates existing iterators. 289 290 This method takes \f$O(\log n)\f$ amortized time when there is already an 291 element with index \p i, and \f$O(\log^2 n)\f$ otherwise. 292 */ 293 Coefficient& operator[](dimension_type i); 294 295 //! Equivalent to <CODE>get(i)</CODE>, provided for convenience. 296 /*! 297 This method takes \f$O(\log n)\f$ time. 298 */ 299 Coefficient_traits::const_reference operator[](dimension_type i) const; 300 301 //! Gets the i-th element in the sequence. 302 /*! 303 \param i 304 The index of the desired element. 305 306 If possible, use the insert(), find() or lower_bound() methods with 307 a hint instead of this, to improve performance. 308 309 This method takes \f$O(\log n)\f$ time. 310 */ 311 Coefficient_traits::const_reference get(dimension_type i) const; 312 313 //! Looks for an element with index i. 314 /*! 315 \param i 316 The index of the desired element. 317 318 If possible, use the find() method that takes a hint %iterator, to improve 319 performance. 320 321 This method takes \f$O(\log n)\f$ time. 322 */ 323 iterator find(dimension_type i); 324 325 //! Looks for an element with index i. 326 /*! 327 \param i 328 The index of the desired element. 329 330 \param itr 331 It is used as a hint. This method will be faster if the searched element 332 is near to \p itr. 333 334 The value of \p itr does not affect the result of this method, as long it 335 is a valid %iterator for this row. \p itr may even be end(). 336 337 This method takes \f$O(\log n)\f$ time. 338 If the distance between \p itr and the searched position is \f$O(1)\f$, 339 this method takes \f$O(1)\f$ time. 340 */ 341 iterator find(iterator itr, dimension_type i); 342 343 //! Looks for an element with index i. 344 /*! 345 \param i 346 The index of the desired element. 347 348 If possible, use the find() method that takes a hint %iterator, to improve 349 performance. 350 351 This method takes \f$O(\log n)\f$ time. 352 */ 353 const_iterator find(dimension_type i) const; 354 355 //! Looks for an element with index i. 356 /*! 357 \param i 358 The index of the desired element. 359 360 \param itr 361 It is used as a hint. This method will be faster if the searched element 362 is near to \p itr. 363 364 The value of \p itr does not affect the result of this method, as long it 365 is a valid %iterator for this row. \p itr may even be end(). 366 367 This method takes \f$O(\log n)\f$ time. 368 If the distance between \p itr and the searched position is \f$O(1)\f$, 369 this method takes \f$O(1)\f$ time. 370 */ 371 const_iterator find(const_iterator itr, dimension_type i) const; 372 373 //! Lower bound of index i. 374 /*! 375 \param i 376 The index of the desired element. 377 378 \returns an %iterator to the first element with index greater than or 379 equal to i. 380 If there are no such elements, returns end(). 381 382 If possible, use the find() method that takes a hint %iterator, to improve 383 performance. 384 385 This method takes \f$O(\log n)\f$ time. 386 */ 387 iterator lower_bound(dimension_type i); 388 389 //! Lower bound of index i. 390 /*! 391 \param i 392 The index of the desired element. 393 394 \param itr 395 It is used as a hint. This method will be faster if the searched element 396 is near to \p itr. 397 398 \returns an %iterator to the first element with index greater than or 399 equal to i. 400 If there are no such elements, returns end(). 401 402 The value of \p itr does not affect the result of this method, as long it 403 is a valid %iterator for this row. \p itr may even be end(). 404 405 This method takes \f$O(\log n)\f$ time. 406 If the distance between \p itr and the searched position is \f$O(1)\f$, 407 this method takes \f$O(1)\f$ time. 408 */ 409 iterator lower_bound(iterator itr, dimension_type i); 410 411 //! Lower bound of index i. 412 /*! 413 414 \param i 415 The index of the desired element. 416 417 \returns an %iterator to the first element with index greater than or 418 equal to i. 419 If there are no such elements, returns end(). 420 421 If possible, use the find() method that takes a hint %iterator, to improve 422 performance. 423 424 This method takes \f$O(\log n)\f$ time. 425 */ 426 const_iterator lower_bound(dimension_type i) const; 427 428 //! Lower bound of index i. 429 /*! 430 \param i 431 The index of the desired element. 432 433 \param itr 434 It is used as a hint. This method will be faster if the searched element 435 is near to \p itr. 436 437 \returns an %iterator to the first element with index greater than or 438 equal to i. 439 If there are no such elements, returns end(). 440 441 The value of \p itr does not affect the result of this method, as long it 442 is a valid %iterator for this row. \p itr may even be end(). 443 444 This method takes \f$O(\log n)\f$ time. 445 If the distance between \p itr and the searched position is \f$O(1)\f$, 446 this method takes \f$O(1)\f$ time. 447 */ 448 const_iterator lower_bound(const_iterator itr, dimension_type i) const; 449 450 //! Equivalent to <CODE>(*this)[i] = x; find(i)</CODE>, but faster. 451 /*! 452 \param i 453 The index of the desired element. 454 455 \param x 456 The value that will be associated to the element. 457 458 If possible, use versions of this method that take a hint, to improve 459 performance. 460 461 This operation invalidates existing iterators. 462 463 This method takes \f$O(\log^2 n)\f$ amortized time. 464 */ 465 iterator insert(dimension_type i, Coefficient_traits::const_reference x); 466 467 //! Equivalent to <CODE>(*this)[i] = x; find(i)</CODE>, but faster. 468 /*! 469 \param i 470 The index of the desired element. 471 472 \param x 473 The value that will be associated to the element. 474 475 \param itr 476 It is used as a hint. This method will be faster if the searched element 477 is near to \p itr, even faster than <CODE>(*this)[i] = x</CODE>. 478 479 The value of \p itr does not affect the result of this method, as long it 480 is a valid %iterator for this row. \p itr may even be end(). 481 482 This operation invalidates existing iterators. 483 484 This method takes \f$O(\log^2 n)\f$ amortized time. If the distance 485 between \p itr and the searched position is \f$O(1)\f$ and the row already 486 contains an element with this index, this method takes \f$O(1)\f$ time. 487 */ 488 iterator insert(iterator itr, dimension_type i, 489 Coefficient_traits::const_reference x); 490 491 //! Equivalent to <CODE>(*this)[i]; find(i)</CODE>, but faster. 492 /*! 493 \param i 494 The index of the desired element. 495 496 If possible, use versions of this method that take a hint, to improve 497 performance. 498 499 This operation invalidates existing iterators. 500 501 This method takes \f$O(\log^2 n)\f$ amortized time. 502 */ 503 iterator insert(dimension_type i); 504 505 //! Equivalent to <CODE>(*this)[i]; find(i)</CODE>, but faster. 506 /*! 507 \param i 508 The index of the desired element. 509 510 \param itr 511 It is used as a hint. This method will be faster if the searched element 512 is near to \p itr, even faster than <CODE>(*this)[i]</CODE>. 513 514 The value of \p itr does not affect the result of this method, as long it 515 is a valid %iterator for this row. \p itr may even be end(). 516 517 This operation invalidates existing iterators. 518 519 This method takes \f$O(\log^2 n)\f$ amortized time. If the distance 520 between \p itr and the searched position is \f$O(1)\f$ and the row already 521 contains an element with this index, this method takes \f$O(1)\f$ time. 522 */ 523 iterator insert(iterator itr, dimension_type i); 524 525 //! Swaps the i-th element with the j-th element. 526 /*! 527 \param i 528 The index of an element. 529 530 \param j 531 The index of another element. 532 533 This operation invalidates existing iterators. 534 535 This method takes \f$O(\log^2 n)\f$ amortized time. 536 */ 537 void swap_coefficients(dimension_type i, dimension_type j); 538 539 //! Equivalent to swap(i,itr.index()), but it assumes that 540 //! lower_bound(i)==itr. 541 /*! 542 Iterators that pointed to the itr.index()-th element remain valid 543 but now point to the i-th element. Other iterators are unaffected. 544 545 This method takes \f$O(1)\f$ time. 546 */ 547 void fast_swap(dimension_type i, iterator itr); 548 549 //! Swaps the element pointed to by i with the element pointed to by j. 550 /*! 551 \param i 552 An %iterator pointing to an element. 553 554 \param j 555 An %iterator pointing to another element. 556 557 This method takes \f$O(1)\f$ time. 558 */ 559 void swap_coefficients(iterator i, iterator j); 560 561 //! Resets to zero the value pointed to by i. 562 /*! 563 \param i 564 An %iterator pointing to the element that will be reset (not stored 565 anymore). 566 567 By calling this method instead of getting a reference to the value and 568 setting it to zero, the element will no longer be stored. 569 570 This operation invalidates existing iterators. 571 572 This method takes \f$O(\log^2 n)\f$ amortized time. 573 */ 574 iterator reset(iterator i); 575 576 //! Resets to zero the values in the range [first,last). 577 /*! 578 \param first 579 An %iterator pointing to the first element to reset. 580 581 \param last 582 An %iterator pointing after the last element to reset. 583 584 By calling this method instead of getting a reference to the values and 585 setting them to zero, the elements will no longer be stored. 586 587 This operation invalidates existing iterators. 588 589 This method takes \f$O(k*\log^2 n)\f$ amortized time, where k is the 590 number of elements in [first,last). 591 */ 592 iterator reset(iterator first, iterator last); 593 594 //! Resets to zero the i-th element. 595 /*! 596 \param i 597 The index of the element to reset. 598 599 By calling this method instead of getting a reference to the value and 600 setting it to zero, the element will no longer be stored. 601 602 This operation invalidates existing iterators. 603 604 This method takes \f$O(\log^2 n)\f$ amortized time. 605 */ 606 void reset(dimension_type i); 607 608 //! Resets to zero the elements with index greater than or equal to i. 609 /*! 610 \param i 611 The index of the first element to reset. 612 613 By calling this method instead of getting a reference to the values and 614 setting them to zero, the elements will no longer be stored. 615 616 This operation invalidates existing iterators. 617 618 This method takes \f$O(k*\log^2 n)\f$ amortized time, where k is the 619 number of elements with index greater than or equal to i. 620 */ 621 void reset_after(dimension_type i); 622 623 //! Normalizes the modulo of coefficients so that they are mutually prime. 624 /*! 625 Computes the Greatest Common Divisor (GCD) among the elements of the row 626 and normalizes them by the GCD itself. 627 628 This method takes \f$O(n)\f$ time. 629 */ 630 void normalize(); 631 632 //! Calls g(x[i],y[i]), for each i. 633 /*! 634 \param y 635 The row that will be combined with *this. 636 637 \param f 638 A functor that should take a Coefficient&. 639 f(c1) must be equivalent to g(c1, 0). 640 641 \param g 642 A functor that should take a Coefficient& and a 643 Coefficient_traits::const_reference. 644 g(c1, c2) must do nothing when c1 is zero. 645 646 This method takes \f$O(n*\log^2 n)\f$ time. 647 648 \note 649 The functors will only be called when necessary, assuming the requested 650 properties hold. 651 652 \see combine_needs_second 653 \see combine 654 */ 655 template <typename Func1, typename Func2> 656 void combine_needs_first(const Sparse_Row& y, 657 const Func1& f, const Func2& g); 658 659 //! Calls g(x[i],y[i]), for each i. 660 /*! 661 \param y 662 The row that will be combined with *this. 663 664 \param g 665 A functor that should take a Coefficient& and a 666 Coefficient_traits::const_reference. 667 g(c1, 0) must do nothing, for every c1. 668 669 \param h 670 A functor that should take a Coefficient& and a 671 Coefficient_traits::const_reference. 672 h(c1, c2) must be equivalent to g(c1, c2) when c1 is zero. 673 674 This method takes \f$O(n*\log^2 n)\f$ time. 675 676 \note 677 The functors will only be called when necessary, assuming the requested 678 properties hold. 679 680 \see combine_needs_first 681 \see combine 682 */ 683 template <typename Func1, typename Func2> 684 void combine_needs_second(const Sparse_Row& y, 685 const Func1& g, const Func2& h); 686 687 //! Calls g(x[i],y[i]), for each i. 688 /*! 689 \param y 690 The row that will be combined with *this. 691 692 \param f 693 A functor that should take a Coefficient&. 694 f(c1) must be equivalent to g(c1, 0). 695 696 \param g 697 A functor that should take a Coefficient& and a 698 Coefficient_traits::const_reference. 699 g(c1, c2) must do nothing when both c1 and c2 are zero. 700 701 \param h 702 A functor that should take a Coefficient& and a 703 Coefficient_traits::const_reference. 704 h(c1, c2) must be equivalent to g(c1, c2) when c1 is zero. 705 706 This method takes \f$O(n*\log^2 n)\f$ time. 707 708 \note 709 The functors will only be called when necessary, assuming the requested 710 properties hold. 711 712 \see combine_needs_first 713 \see combine_needs_second 714 */ 715 template <typename Func1, typename Func2, typename Func3> 716 void combine(const Sparse_Row& y, 717 const Func1& f, const Func2& g, const Func3& h); 718 719 //! Executes <CODE>(*this)[i] = (*this)[i]*coeff1 + y[i]*coeff2</CODE>, for 720 //! each i. 721 /*! 722 \param y 723 The row that will be combined with *this. 724 725 \param coeff1 726 The coefficient used for elements of *this. 727 This must not be 0. 728 729 \param coeff2 730 The coefficient used for elements of y. 731 This must not be 0. 732 733 This method takes \f$O(n*\log^2 n)\f$ time. 734 735 \note 736 The functors will only be called when necessary. 737 This method can be implemented in user code, too. It is provided for 738 convenience only. 739 740 \see combine_needs_first 741 \see combine_needs_second 742 \see combine 743 */ 744 void linear_combine(const Sparse_Row& y, 745 Coefficient_traits::const_reference coeff1, 746 Coefficient_traits::const_reference coeff2); 747 748 //! Equivalent to <CODE>(*this)[i] = (*this)[i] * c1 + y[i] * c2</CODE>, 749 //! for each i in [start, end). 750 /*! 751 This method, unlike the other linear_combine() method, detects when 752 coeff1==1 and/or coeff2==1 or coeff2==-1 in order to save some work. 753 */ 754 void linear_combine(const Sparse_Row& y, 755 Coefficient_traits::const_reference c1, 756 Coefficient_traits::const_reference c2, 757 dimension_type start, dimension_type end); 758 759 PPL_OUTPUT_DECLARATIONS 760 761 //! Loads the row from an ASCII representation generated using ascii_dump(). 762 /*! 763 \param s 764 The stream from which the ASCII representation will be loaded. 765 */ 766 bool ascii_load(std::istream& s); 767 768 //! Returns the size in bytes of the memory managed by \p *this. 769 /*! 770 This method takes \f$O(n)\f$ time. 771 */ 772 memory_size_type external_memory_in_bytes() const; 773 774 //! Returns the size in bytes of the memory managed by \p *this. 775 /*! 776 This method is provided for compatibility with Dense_Row. 777 778 This method takes \f$O(n)\f$ time. 779 780 \param capacity 781 This parameter is ignored. 782 */ 783 memory_size_type external_memory_in_bytes(dimension_type capacity) const; 784 785 //! Returns the size in bytes of the memory managed by \p *this. 786 /*! 787 This method takes \f$O(n)\f$ time. 788 */ 789 memory_size_type total_memory_in_bytes() const; 790 791 //! Returns the size in bytes of the memory managed by \p *this. 792 /*! 793 This method is provided for compatibility with Dense_Row. 794 795 This method takes \f$O(n)\f$ time. 796 797 \param capacity 798 This parameter is ignored. 799 */ 800 memory_size_type total_memory_in_bytes(dimension_type capacity) const; 801 802 //! Checks the invariant. 803 bool OK() const; 804 805 //! Checks the invariant. 806 /*! 807 This method is provided for compatibility with Dense_Row. 808 809 \param capacity 810 This parameter is ignored. 811 */ 812 bool OK(dimension_type capacity) const; 813 814 private: 815 //! The tree used to store the elements. 816 CO_Tree tree; 817 818 //! The size of the row. 819 /*! 820 The elements contained in this row have indexes that are less than size_. 821 */ 822 dimension_type size_; 823 }; 824 825 826 namespace Parma_Polyhedra_Library { 827 828 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 829 //! Swaps \p x with \p y. 830 /*! \relates Sparse_Row */ 831 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS) 832 void swap(Parma_Polyhedra_Library::Sparse_Row& x, 833 Parma_Polyhedra_Library::Sparse_Row& y); 834 835 void swap(Parma_Polyhedra_Library::Sparse_Row& x, 836 Parma_Polyhedra_Library::Dense_Row& y); 837 838 void swap(Parma_Polyhedra_Library::Dense_Row& x, 839 Parma_Polyhedra_Library::Sparse_Row& y); 840 841 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 842 //! Returns <CODE>true</CODE> if and only if \p x and \p y are equal. 843 /*! \relates Sparse_Row */ 844 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS) 845 bool operator==(const Sparse_Row& x, const Sparse_Row& y); 846 847 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 848 //! Returns <CODE>true</CODE> if and only if \p x and \p y are different. 849 /*! \relates Sparse_Row */ 850 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS) 851 bool operator!=(const Sparse_Row& x, const Sparse_Row& y); 852 853 bool operator==(const Dense_Row& x, const Sparse_Row& y); 854 bool operator!=(const Dense_Row& x, const Sparse_Row& y); 855 856 bool operator==(const Sparse_Row& x, const Dense_Row& y); 857 bool operator!=(const Sparse_Row& x, const Dense_Row& y); 858 859 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 860 //! Equivalent to <CODE>x[i] = x[i] * c1 + y[i] * c2</CODE>, 861 //! for each i in [start, end). 862 /*! \relates Sparse_Row */ 863 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS) 864 void linear_combine(Sparse_Row& x, const Dense_Row& y, 865 Coefficient_traits::const_reference coeff1, 866 Coefficient_traits::const_reference coeff2); 867 868 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 869 //! Equivalent to <CODE>x[i] = x[i] * c1 + y[i] * c2</CODE>, 870 //! for each i in [start, end). 871 /*! \relates Sparse_Row 872 This function detects when coeff1==1 and/or coeff2==1 or coeff2==-1 in 873 order to save some work. 874 */ 875 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS) 876 void linear_combine(Sparse_Row& x, const Dense_Row& y, 877 Coefficient_traits::const_reference c1, 878 Coefficient_traits::const_reference c2, 879 dimension_type start, dimension_type end); 880 881 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 882 //! Equivalent to <CODE>x[i] = x[i] * c1 + y[i] * c2</CODE>, 883 //! for each i in [start, end). 884 /*! \relates Sparse_Row */ 885 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS) 886 void linear_combine(Dense_Row& x, const Sparse_Row& y, 887 Coefficient_traits::const_reference coeff1, 888 Coefficient_traits::const_reference coeff2); 889 890 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 891 //! Equivalent to <CODE>x[i] = x[i] * c1 + y[i] * c2</CODE>, 892 //! for each i in [start, end). 893 /*! \relates Sparse_Row 894 This function detects when coeff1==1 and/or coeff2==1 or coeff2==-1 in 895 order to save some work. 896 */ 897 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS) 898 void linear_combine(Dense_Row& x, const Sparse_Row& y, 899 Coefficient_traits::const_reference c1, 900 Coefficient_traits::const_reference c2, 901 dimension_type start, dimension_type end); 902 903 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 904 //! Equivalent to <CODE>x[i] = x[i] * c1 + y[i] * c2</CODE>, 905 //! for each i in [start, end). 906 /*! \relates Sparse_Row */ 907 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS) 908 void linear_combine(Sparse_Row& x, const Sparse_Row& y, 909 Coefficient_traits::const_reference coeff1, 910 Coefficient_traits::const_reference coeff2); 911 912 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 913 //! Equivalent to <CODE>x[i] = x[i] * c1 + y[i] * c2</CODE>, 914 //! for each i in [start, end). 915 /*! \relates Sparse_Row 916 This function detects when coeff1==1 and/or coeff2==1 or coeff2==-1 in 917 order to save some work. 918 */ 919 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS) 920 void linear_combine(Sparse_Row& x, const Sparse_Row& y, 921 Coefficient_traits::const_reference c1, 922 Coefficient_traits::const_reference c2, 923 dimension_type start, dimension_type end); 924 925 } // namespace Parma_Polyhedra_Library 926 927 #include "Sparse_Row_inlines.hh" 928 #include "Sparse_Row_templates.hh" 929 930 #endif // !defined(PPL_Sparse_Row_defs_hh) 931