diff --git a/include/boost/numeric/ublas/functional.hpp b/include/boost/numeric/ublas/functional.hpp index cdbcaf94..7c4fefa8 100644 --- a/include/boost/numeric/ublas/functional.hpp +++ b/include/boost/numeric/ublas/functional.hpp @@ -1722,6 +1722,7 @@ namespace boost { namespace numeric { namespace ublas { bool other (size_type /* i */, size_type /* j */) { return true; } + // FIXME: this should not be used at all static BOOST_UBLAS_INLINE size_type restrict1 (size_type i, size_type j) { @@ -1744,6 +1745,84 @@ namespace boost { namespace numeric { namespace ublas { } }; + namespace detail { + template < class L > + struct transposed_structure { + typedef typename L::size_type size_type; + + template + static + BOOST_UBLAS_INLINE + size_type packed_size (LAYOUT l, size_type size_i, size_type size_j) { + return L::packed_size(l, size_j, size_i); + } + + static + BOOST_UBLAS_INLINE + bool zero (size_type i, size_type j) { + return L::zero(j, i); + } + static + BOOST_UBLAS_INLINE + bool one (size_type i, size_type j) { + return L::one(j, i); + } + static + BOOST_UBLAS_INLINE + bool other (size_type i, size_type j) { + return L::other(j, i); + } + template + static + BOOST_UBLAS_INLINE + size_type element (LAYOUT l, size_type i, size_type size_i, size_type j, size_type size_j) { + return L::element(l, j, size_j, i, size_i); + } + + static + BOOST_UBLAS_INLINE + size_type restrict1 (size_type i, size_type j, size_type size1, size_type size2) { + return L::restrict2(j, i, size2, size1); + } + static + BOOST_UBLAS_INLINE + size_type restrict2 (size_type i, size_type j, size_type size1, size_type size2) { + return L::restrict1(j, i, size2, size1); + } + static + BOOST_UBLAS_INLINE + size_type mutable_restrict1 (size_type i, size_type j, size_type size1, size_type size2) { + return L::mutable_restrict2(j, i, size2, size1); + } + static + BOOST_UBLAS_INLINE + size_type mutable_restrict2 (size_type i, size_type j, size_type size1, size_type size2) { + return L::mutable_restrict1(j, i, size2, size1); + } + + static + BOOST_UBLAS_INLINE + size_type global_restrict1 (size_type index1, size_type size1, size_type index2, size_type size2) { + return L::global_restrict2(index2, size2, index1, size1); + } + static + BOOST_UBLAS_INLINE + size_type global_restrict2 (size_type index1, size_type size1, size_type index2, size_type size2) { + return L::global_restrict1(index2, size2, index1, size1); + } + static + BOOST_UBLAS_INLINE + size_type global_mutable_restrict1 (size_type index1, size_type size1, size_type index2, size_type size2) { + return L::global_mutable_restrict2(index2, size2, index1, size1); + } + static + BOOST_UBLAS_INLINE + size_type global_mutable_restrict2 (size_type index1, size_type size1, size_type index2, size_type size2) { + return L::global_mutable_restrict1(index2, size2, index1, size1); + } + }; + } + template struct basic_lower { typedef Z size_type; @@ -1777,80 +1856,56 @@ namespace boost { namespace numeric { namespace ublas { return L::lower_element (i, size_i, j, size_j); } + // return nearest valid index in column j static BOOST_UBLAS_INLINE - size_type restrict1 (size_type i, size_type j) { - return (std::max) (i, j); + size_type restrict1 (size_type i, size_type j, size_type size1, size_type size2) { + return (std::max)(j, (std::min) (size1, i)); } + // return nearest valid index in row i static BOOST_UBLAS_INLINE - size_type restrict2 (size_type i, size_type j) { - return (std::min) (i + 1, j); + size_type restrict2 (size_type i, size_type j, size_type /* size1 */, size_type /* size2 */) { + return (std::max)(size_type(0), (std::min) (i+1, j)); } + // return nearest valid mutable index in column j static BOOST_UBLAS_INLINE - size_type mutable_restrict1 (size_type i, size_type j) { - return (std::max) (i, j); + size_type mutable_restrict1 (size_type i, size_type j, size_type size1, size_type size2) { + return (std::max)(j, (std::min) (size1, i)); } + // return nearest valid mutable index in row i static BOOST_UBLAS_INLINE - size_type mutable_restrict2 (size_type i, size_type j) { - return (std::min) (i + 1, j); - } - }; - template - struct basic_upper { - typedef Z size_type; - - template - static - BOOST_UBLAS_INLINE - size_type packed_size (L, size_type size_i, size_type size_j) { - return L::triangular_size (size_i, size_j); + size_type mutable_restrict2 (size_type i, size_type j, size_type /* size1 */, size_type /* size2 */) { + return (std::max)(size_type(0), (std::min) (i+1, j)); } - static - BOOST_UBLAS_INLINE - bool zero (size_type i, size_type j) { - return j < i; - } - static - BOOST_UBLAS_INLINE - bool one (size_type /* i */, size_type /* j */) { - return false; - } - static - BOOST_UBLAS_INLINE - bool other (size_type i, size_type j) { - return j >= i; - } - template - static - BOOST_UBLAS_INLINE - size_type element (L, size_type i, size_type size_i, size_type j, size_type size_j) { - return L::upper_element (i, size_i, j, size_j); - } + // return an index between the first and (1+last) filled row + static + BOOST_UBLAS_INLINE + size_type global_restrict1 (size_type index1, size_type size1, size_type index2, size_type size2) { + return (std::max)(size_type(0), (std::min)(size1, index1) ); + } + // return an index between the first and (1+last) filled column + static + BOOST_UBLAS_INLINE + size_type global_restrict2 (size_type index1, size_type size1, size_type index2, size_type size2) { + return (std::max)(size_type(0), (std::min)(size2, index2) ); + } - static - BOOST_UBLAS_INLINE - size_type restrict1 (size_type i, size_type j) { - return (std::min) (i, j + 1); - } - static - BOOST_UBLAS_INLINE - size_type restrict2 (size_type i, size_type j) { - return (std::max) (i, j); - } - static - BOOST_UBLAS_INLINE - size_type mutable_restrict1 (size_type i, size_type j) { - return (std::min) (i, j + 1); - } - static - BOOST_UBLAS_INLINE - size_type mutable_restrict2 (size_type i, size_type j) { - return (std::max) (i, j); - } + // return an index between the first and (1+last) filled mutable row + static + BOOST_UBLAS_INLINE + size_type global_mutable_restrict1 (size_type index1, size_type size1, size_type index2, size_type size2) { + return (std::max)(size_type(0), (std::min)(size1, index1) ); + } + // return an index between the first and (1+last) filled mutable column + static + BOOST_UBLAS_INLINE + size_type global_mutable_restrict2 (size_type index1, size_type size1, size_type index2, size_type size2) { + return (std::max)(size_type(0), (std::min)(size2, index2) ); + } }; // the first row only contains a single 1. Thus it is not stored. @@ -1888,64 +1943,33 @@ namespace boost { namespace numeric { namespace ublas { static BOOST_UBLAS_INLINE - size_type mutable_restrict1 (size_type i, size_type j) { - return (std::max) ( (std::max)(1, i), j); + size_type mutable_restrict1 (size_type i, size_type j, size_type size1, size_type size2) { + return (std::max)(j+1, (std::min) (size1, i)); } static BOOST_UBLAS_INLINE - size_type mutable_restrict2 (size_type i, size_type j) { - return (std::min) ( (std::max)(1, i), j); + size_type mutable_restrict2 (size_type i, size_type j, size_type size1, size_type size2) { + return (std::max)(size_type(0), (std::min) (i, j)); } + + // return an index between the first and (1+last) filled mutable row + static + BOOST_UBLAS_INLINE + size_type global_mutable_restrict1 (size_type index1, size_type size1, size_type index2, size_type size2) { + return (std::max)(size_type(1), (std::min)(size1, index1) ); + } + // return an index between the first and (1+last) filled mutable column + static + BOOST_UBLAS_INLINE + size_type global_mutable_restrict2 (size_type index1, size_type size1, size_type index2, size_type size2) { + BOOST_UBLAS_CHECK( size2 >= 1 , external_logic() ); + return (std::max)(size_type(0), (std::min)(size2-1, index2) ); + } }; - // the last row only contains a single 1. Thus it is not stored. + // the first row only contains no element. Thus it is not stored. template - struct basic_unit_upper : public basic_upper { - typedef Z size_type; - - template - static - BOOST_UBLAS_INLINE - size_type packed_size (L, size_type size_i, size_type size_j) { - // Zero size strict triangles are bad at this point - BOOST_UBLAS_CHECK (size_i != 0 && size_j != 0, bad_index ()); - return L::triangular_size (size_i - 1, size_j - 1); - } - - static - BOOST_UBLAS_INLINE - bool one (size_type i, size_type j) { - return j == i; - } - static - BOOST_UBLAS_INLINE - bool other (size_type i, size_type j) { - return j > i; - } - template - static - BOOST_UBLAS_INLINE - size_type element (L, size_type i, size_type size_i, size_type j, size_type size_j) { - // Zero size strict triangles are bad at this point - BOOST_UBLAS_CHECK (size_i != 0 && size_j != 0 && j != 0, bad_index ()); - return L::upper_element (i, size_i - 1, j-1, size_j - 1); - } - - static - BOOST_UBLAS_INLINE - size_type mutable_restrict1 (size_type i, size_type j) { - return (std::min) (i, (std::max)(1, j)); - } - static - BOOST_UBLAS_INLINE - size_type mutable_restrict2 (size_type i, size_type j) { - return (std::max) (i, (std::max)(1, j)); - } - }; - - // the first row only contains a single 1. Thus it is not stored. - template - struct basic_strict_lower : public basic_lower { + struct basic_strict_lower : public basic_unit_lower { typedef Z size_type; template @@ -1983,85 +2007,42 @@ namespace boost { namespace numeric { namespace ublas { static BOOST_UBLAS_INLINE - size_type restrict1 (size_type i, size_type j) { - return (std::max) ( (std::max)(1, i), j); + size_type restrict1 (size_type i, size_type j, size_type size1, size_type size2) { + return mutable_restrict1(i, j, size1, size2); } static BOOST_UBLAS_INLINE - size_type restrict2 (size_type i, size_type j) { - return (std::min) ( (std::max)(1, i), j); - } - static - BOOST_UBLAS_INLINE - size_type mutable_restrict1 (size_type i, size_type j) { - return (std::max) ( (std::max)(1, i), j); - } - static - BOOST_UBLAS_INLINE - size_type mutable_restrict2 (size_type i, size_type j) { - return (std::min) ( (std::max)(1, i), j); + size_type restrict2 (size_type i, size_type j, size_type size1, size_type size2) { + return mutable_restrict2(i, j, size1, size2); } + + // return an index between the first and (1+last) filled row + static + BOOST_UBLAS_INLINE + size_type global_restrict1 (size_type index1, size_type size1, size_type index2, size_type size2) { + return global_mutable_restrict1(index1, index2, size1, size2); + } + // return an index between the first and (1+last) filled column + static + BOOST_UBLAS_INLINE + size_type global_restrict2 (size_type index1, size_type size1, size_type index2, size_type size2) { + return global_mutable_restrict2(index1, index2, size1, size2); + } }; - // the last row only contains a single 1. Thus it is not stored. + template - struct basic_strict_upper : public basic_upper { - typedef Z size_type; + struct basic_upper : public detail::transposed_structure > + { }; - template - static - BOOST_UBLAS_INLINE - size_type packed_size (L, size_type size_i, size_type size_j) { - // Zero size strict triangles are bad at this point - BOOST_UBLAS_CHECK (size_i != 0 && size_j != 0, bad_index ()); - return L::triangular_size (size_i - 1, size_j - 1); - } + template + struct basic_unit_upper : public detail::transposed_structure > + { }; - static - BOOST_UBLAS_INLINE - bool zero (size_type i, size_type j) { - return j <= i; - } - static - BOOST_UBLAS_INLINE - bool one (size_type /*i*/, size_type /*j*/) { - return false; - } - static - BOOST_UBLAS_INLINE - bool other (size_type i, size_type j) { - return j > i; - } - template - static - BOOST_UBLAS_INLINE - size_type element (L, size_type i, size_type size_i, size_type j, size_type size_j) { - // Zero size strict triangles are bad at this point - BOOST_UBLAS_CHECK (size_i != 0 && size_j != 0 && j != 0, bad_index ()); - return L::upper_element (i, size_i - 1, j-1, size_j - 1); - } + template + struct basic_strict_upper : public detail::transposed_structure > + { }; - static - BOOST_UBLAS_INLINE - size_type restrict1 (size_type i, size_type j) { - return (std::min) (i, (std::max)(1, j)); - } - static - BOOST_UBLAS_INLINE - size_type restrict2 (size_type i, size_type j) { - return (std::max) (i, (std::max)(1, j)); - } - static - BOOST_UBLAS_INLINE - size_type mutable_restrict1 (size_type i, size_type j) { - return (std::min) (i, (std::max)(1, j)); - } - static - BOOST_UBLAS_INLINE - size_type mutable_restrict2 (size_type i, size_type j) { - return (std::max) (i, (std::max)(1, j)); - } - }; }}} diff --git a/include/boost/numeric/ublas/triangular.hpp b/include/boost/numeric/ublas/triangular.hpp index f0be81e9..8bbef2ee 100644 --- a/include/boost/numeric/ublas/triangular.hpp +++ b/include/boost/numeric/ublas/triangular.hpp @@ -295,25 +295,33 @@ namespace boost { namespace numeric { namespace ublas { BOOST_UBLAS_INLINE const_iterator1 find1 (int rank, size_type i, size_type j) const { if (rank == 1) - i = triangular_type::restrict1 (i, j); + i = triangular_type::restrict1 (i, j, size1_, size2_); + if (rank == 0) + i = triangular_type::global_restrict1 (i, size1_, j, size2_); return const_iterator1 (*this, i, j); } BOOST_UBLAS_INLINE iterator1 find1 (int rank, size_type i, size_type j) { if (rank == 1) - i = triangular_type::mutable_restrict1 (i, j); + i = triangular_type::mutable_restrict1 (i, j, size1_, size2_); + if (rank == 0) + i = triangular_type::global_mutable_restrict1 (i, size1_, j, size2_); return iterator1 (*this, i, j); } BOOST_UBLAS_INLINE const_iterator2 find2 (int rank, size_type i, size_type j) const { if (rank == 1) - j = triangular_type::restrict2 (i, j); + j = triangular_type::restrict2 (i, j, size1_, size2_); + if (rank == 0) + j = triangular_type::global_restrict2 (i, size1_, j, size2_); return const_iterator2 (*this, i, j); } BOOST_UBLAS_INLINE iterator2 find2 (int rank, size_type i, size_type j) { if (rank == 1) - j = triangular_type::mutable_restrict2 (i, j); + j = triangular_type::mutable_restrict2 (i, j, size1_, size2_); + if (rank == 0) + j = triangular_type::global_mutable_restrict2 (i, size1_, j, size2_); return iterator2 (*this, i, j); }