Ticket #7363: custom_inplace_merge_fixed.diff

File custom_inplace_merge_fixed.diff, 33.4 KB (added by j.ungermann@…, 10 years ago)
  • boost/numeric/ublas/vector_sparse.hpp

     
    262262
    263263    /** \brief Index map based sparse vector
    264264     *
    265      * A sparse vector of values of type T of variable size. The sparse storage type A can be 
     265     * A sparse vector of values of type T of variable size. The sparse storage type A can be
    266266     * \c std::map<size_t, T> or \c map_array<size_t, T>. This means that only non-zero elements
    267267     * are effectively stored.
    268268     *
    269      * For a \f$n\f$-dimensional sparse vector,  and 0 <= i < n the non-zero elements \f$v_i\f$ 
    270      * are mapped to consecutive elements of the associative container, i.e. for elements 
     269     * For a \f$n\f$-dimensional sparse vector,  and 0 <= i < n the non-zero elements \f$v_i\f$
     270     * are mapped to consecutive elements of the associative container, i.e. for elements
    271271     * \f$k = v_{i_1}\f$ and \f$k + 1 = v_{i_2}\f$ of the container, holds \f$i_1 < i_2\f$.
    272272     *
    273      * Supported parameters for the adapted array are \c map_array<std::size_t, T> and 
     273     * Supported parameters for the adapted array are \c map_array<std::size_t, T> and
    274274     * \c map_std<std::size_t, T>. The latter is equivalent to \c std::map<std::size_t, T>.
    275275     *
    276276     * \tparam T the type of object stored in the vector (like double, float, complex, etc...)
     
    771771
    772772
    773773    // Thanks to Kresimir Fresl for extending this to cover different index bases.
    774    
     774
    775775    /** \brief Compressed array based sparse vector
    776776     *
    777      * a sparse vector of values of type T of variable size. The non zero values are stored as 
    778      * two seperate arrays: an index array and a value array. The index array is always sorted 
     777     * a sparse vector of values of type T of variable size. The non zero values are stored as
     778     * two seperate arrays: an index array and a value array. The index array is always sorted
    779779     * and there is at most one entry for each index. Inserting an element can be time consuming.
    780780     * If the vector contains a few zero entries, then it is better to have a normal vector.
    781781     * If the vector has a very high dimension with a few non-zero values, then this vector is
    782782     * very memory efficient (at the cost of a few more computations).
    783783     *
    784      * For a \f$n\f$-dimensional compressed vector and \f$0 \leq i < n\f$ the non-zero elements 
    785      * \f$v_i\f$ are mapped to consecutive elements of the index and value container, i.e. for 
     784     * For a \f$n\f$-dimensional compressed vector and \f$0 \leq i < n\f$ the non-zero elements
     785     * \f$v_i\f$ are mapped to consecutive elements of the index and value container, i.e. for
    786786     * elements \f$k = v_{i_1}\f$ and \f$k + 1 = v_{i_2}\f$ of these containers holds \f$i_1 < i_2\f$.
    787787     *
    788788     * Supported parameters for the adapted array (indices and values) are \c unbounded_array<> ,
     
    14141414
    14151415    /** \brief Coordimate array based sparse vector
    14161416     *
    1417      * a sparse vector of values of type \c T of variable size. The non zero values are stored 
    1418      * as two seperate arrays: an index array and a value array. The arrays may be out of order 
    1419      * with multiple entries for each vector element. If there are multiple values for the same 
     1417     * a sparse vector of values of type \c T of variable size. The non zero values are stored
     1418     * as two seperate arrays: an index array and a value array. The arrays may be out of order
     1419     * with multiple entries for each vector element. If there are multiple values for the same
    14201420     * index the sum of these values is the real value. It is way more efficient for inserting values
    1421      * than a \c compressed_vector but less memory efficient. Also linearly parsing a vector can 
     1421     * than a \c compressed_vector but less memory efficient. Also linearly parsing a vector can
    14221422     * be longer in specific cases than a \c compressed_vector.
    14231423     *
    1424      * For a n-dimensional sorted coordinate vector and \f$ 0 \leq i < n\f$ the non-zero elements 
    1425      * \f$v_i\f$ are mapped to consecutive elements of the index and value container, i.e. for 
     1424     * For a n-dimensional sorted coordinate vector and \f$ 0 \leq i < n\f$ the non-zero elements
     1425     * \f$v_i\f$ are mapped to consecutive elements of the index and value container, i.e. for
    14261426     * elements \f$k = v_{i_1}\f$ and \f$k + 1 = v_{i_2}\f$ of these containers holds \f$i_1 < i_2\f$.
    14271427     *
    14281428     * Supported parameters for the adapted array (indices and values) are \c unbounded_array<> ,
     
    18011801            v1.swap (v2);
    18021802        }
    18031803
     1804        // replacement if STL lower bound algorithm for use of inplace_merge
     1805        size_type lower_bound (size_type beg, size_type end, size_type target) const {
     1806          while (end > beg) {
     1807            size_type mid = (beg + end) / 2;
     1808            if (index_data_[mid] < index_data_[target]) {
     1809              beg = mid + 1;
     1810            } else {
     1811              end = mid;
     1812            }
     1813          }
     1814          return beg;
     1815        }
     1816
     1817        // specialized replacement of STL inplace_merge to avoid compilation
     1818        // problems with respect to the array_triple iterator
     1819        void inplace_merge (size_type beg, size_type mid, size_type end) const {
     1820          size_type len_lef = mid - beg;
     1821          size_type len_rig = end - mid;
     1822
     1823          if (len_lef == 1 && len_rig == 1) {
     1824            if (index_data_[mid] < index_data_[beg]) {
     1825              std::swap(index_data_[beg], index_data_[mid]);
     1826              std::swap(value_data_[beg], value_data_[mid]);
     1827            }
     1828          } else if (len_lef > 0 && len_rig > 0) {
     1829            size_type lef_mid, rig_mid;
     1830            if (len_lef >= len_rig) {
     1831              lef_mid = (beg + mid) / 2;
     1832              rig_mid = lower_bound(mid, end, lef_mid);
     1833            } else {
     1834              rig_mid = (mid + end) / 2;
     1835              lef_mid = lower_bound(beg, mid, rig_mid);
     1836            }
     1837            std::rotate(&index_data_[0] + lef_mid, &index_data_[0] + mid, &index_data_[0] + rig_mid);
     1838            std::rotate(&value_data_[0] + lef_mid, &value_data_[0] + mid, &value_data_[0] + rig_mid);
     1839
     1840            size_type new_mid = lef_mid + rig_mid - mid;
     1841            inplace_merge(beg, lef_mid, new_mid);
     1842            inplace_merge(new_mid, rig_mid, end);
     1843          }
     1844        }
     1845
    18041846        // Sorting and summation of duplicates
    18051847        BOOST_UBLAS_INLINE
    18061848        void sort () const {
     
    18111853                const typename array_pair::iterator iunsorted = ipa.begin () + sorted_filled_;
    18121854                // sort new elements and merge
    18131855                std::sort (iunsorted, ipa.end ());
    1814                 std::inplace_merge (ipa.begin (), iunsorted, ipa.end ());
     1856                // do not use STL algorithm due to compilation problems with recent gcc
     1857                inplace_merge(0, sorted_filled_, filled_);
    18151858#else
    18161859                const typename array_pair::iterator iunsorted = ipa.begin ();
    18171860                std::sort (iunsorted, ipa.end ());
  • boost/numeric/ublas/matrix_sparse.hpp

     
    1313#ifndef _BOOST_UBLAS_MATRIX_SPARSE_
    1414#define _BOOST_UBLAS_MATRIX_SPARSE_
    1515
     16#include <typeinfo>
    1617#include <boost/numeric/ublas/vector_sparse.hpp>
    1718#include <boost/numeric/ublas/matrix_expression.hpp>
    1819#include <boost/numeric/ublas/detail/matrix_assign.hpp>
     
    5455            else
    5556                *p = s;
    5657        }
    57        
     58
    5859    public:
    5960        // Construction and destruction
    6061        BOOST_UBLAS_INLINE
     
    250251    *
    251252    * This class represents a matrix by using a \c key to value mapping. The default type is
    252253    * \code template<class T, class L = row_major, class A =  map_std<std::size_t, T> > class mapped_matrix; \endcode
    253     * So, by default a STL map container is used to associate keys and values. The key is computed depending on 
     254    * So, by default a STL map container is used to associate keys and values. The key is computed depending on
    254255    * the layout type \c L as \code key = layout_type::element(i, size1_, j, size2_); \endcode
    255256    * which means \code key = (i*size2+j) \endcode for a row major matrix.
    256     * Limitations: The matrix size must not exceed \f$(size1*size2) < \f$ \code std::limits<std::size_t> \endcode. 
     257    * Limitations: The matrix size must not exceed \f$(size1*size2) < \f$ \code std::limits<std::size_t> \endcode.
    257258    * The \ref find1() and \ref find2() operations have a complexity of at least \f$\mathcal{O}(log(nnz))\f$, depending
    258259    * on the efficiency of \c std::lower_bound on the key set of the map.
    259     * Orientation and storage can also be specified, otherwise a row major orientation is used. 
    260     * It is \b not required by the storage to initialize elements of the matrix. By default, the orientation is \c row_major. 
     260    * Orientation and storage can also be specified, otherwise a row major orientation is used.
     261    * It is \b not required by the storage to initialize elements of the matrix. By default, the orientation is \c row_major.
    261262    *
    262263    * \sa fwd.hpp, storage_sparse.hpp
    263264    *
     
    427428                return;
    428429            data ().erase (it);
    429430        }
    430        
     431
    431432        // Zeroing
    432433        BOOST_UBLAS_INLINE
    433434        void clear () {
     
    557558        typedef reverse_iterator_base2<iterator2> reverse_iterator2;
    558559
    559560        // Element lookup
    560         // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.   
     561        // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
    561562        const_iterator1 find1 (int rank, size_type i, size_type j, int direction = 1) const {
    562563            const_subiterator_type it (data ().lower_bound (layout_type::address (i, size1_, j, size2_)));
    563564            const_subiterator_type it_end (data ().end ());
     
    586587            }
    587588            return const_iterator1 (*this, rank, i, j, it);
    588589        }
    589         // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.   
     590        // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
    590591        iterator1 find1 (int rank, size_type i, size_type j, int direction = 1) {
    591592            subiterator_type it (data ().lower_bound (layout_type::address (i, size1_, j, size2_)));
    592593            subiterator_type it_end (data ().end ());
     
    615616            }
    616617            return iterator1 (*this, rank, i, j, it);
    617618        }
    618         // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.   
     619        // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
    619620        const_iterator2 find2 (int rank, size_type i, size_type j, int direction = 1) const {
    620621            const_subiterator_type it (data ().lower_bound (layout_type::address (i, size1_, j, size2_)));
    621622            const_subiterator_type it_end (data ().end ());
     
    644645            }
    645646            return const_iterator2 (*this, rank, i, j, it);
    646647        }
    647         // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.   
     648        // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
    648649        iterator2 find2 (int rank, size_type i, size_type j, int direction = 1) {
    649650            subiterator_type it (data ().lower_bound (layout_type::address (i, size1_, j, size2_)));
    650651            subiterator_type it_end (data ().end ());
     
    13771378            matrix_container<self_type> (),
    13781379            size1_ (size1), size2_ (size2), data_ () {
    13791380            data_ [layout_type::size_M (size1_, size2_)] = vector_data_value_type ();
     1381            //std::cerr << std::type_info(A).name() << " ";
     1382            std::cerr << A::data_value_type();
    13801383        }
    13811384        BOOST_UBLAS_INLINE
    13821385        mapped_vector_of_mapped_vector (const mapped_vector_of_mapped_vector &m):
     
    15091512                return;
    15101513            (*itv).second.erase (it);
    15111514        }
    1512        
     1515
    15131516        // Zeroing
    15141517        BOOST_UBLAS_INLINE
    15151518        void clear () {
     
    16321635            subiterator_type it ((*itv).second.find (element2));
    16331636            BOOST_UBLAS_CHECK (it != (*itv).second.end (), bad_index ());
    16341637            BOOST_UBLAS_CHECK ((*it).first == element2, internal_logic ());    // broken map
    1635            
     1638
    16361639            return it->second;
    16371640        }
    16381641
     
    16471650        typedef reverse_iterator_base2<iterator2> reverse_iterator2;
    16481651
    16491652        // Element lookup
    1650         // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.   
     1653        // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
    16511654        const_iterator1 find1 (int rank, size_type i, size_type j, int direction = 1) const {
    16521655            BOOST_UBLAS_CHECK (data ().begin () != data ().end (), internal_logic ());
    16531656            for (;;) {
     
    16621665                    // advance to the first available major index
    16631666                    size_type M = itv->first;
    16641667                    size_type m;
    1665                     if (it != it_end) { 
    1666                         m = it->first; 
     1668                    if (it != it_end) {
     1669                        m = it->first;
    16671670                    } else {
    16681671                        m = layout_type::size_m(size1_, size2_);
    16691672                    }
     
    16961699                }
    16971700            }
    16981701        }
    1699         // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.   
     1702        // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
    17001703        iterator1 find1 (int rank, size_type i, size_type j, int direction = 1) {
    17011704            BOOST_UBLAS_CHECK (data ().begin () != data ().end (), internal_logic ());
    17021705            for (;;) {
     
    17111714                    // advance to the first available major index
    17121715                    size_type M = itv->first;
    17131716                    size_type m;
    1714                     if (it != it_end) { 
    1715                         m = it->first; 
     1717                    if (it != it_end) {
     1718                        m = it->first;
    17161719                    } else {
    17171720                        m = layout_type::size_m(size1_, size2_);
    17181721                    }
     
    17451748                }
    17461749            }
    17471750        }
    1748         // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.   
     1751        // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
    17491752        const_iterator2 find2 (int rank, size_type i, size_type j, int direction = 1) const {
    17501753            BOOST_UBLAS_CHECK (data ().begin () != data ().end (), internal_logic ());
    17511754            for (;;) {
     
    17601763                    // advance to the first available major index
    17611764                    size_type M = itv->first;
    17621765                    size_type m;
    1763                     if (it != it_end) { 
    1764                         m = it->first; 
     1766                    if (it != it_end) {
     1767                        m = it->first;
    17651768                    } else {
    17661769                        m = layout_type::size_m(size1_, size2_);
    17671770                    }
     
    17941797                }
    17951798            }
    17961799        }
    1797         // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.   
     1800        // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
    17981801        iterator2 find2 (int rank, size_type i, size_type j, int direction = 1) {
    17991802            BOOST_UBLAS_CHECK (data ().begin () != data ().end (), internal_logic ());
    18001803            for (;;) {
     
    18091812                    // advance to the first available major index
    18101813                    size_type M = itv->first;
    18111814                    size_type m;
    1812                     if (it != it_end) { 
    1813                         m = it->first; 
     1815                    if (it != it_end) {
     1816                        m = it->first;
    18141817                    } else {
    18151818                        m = layout_type::size_m(size1_, size2_);
    18161819                    }
     
    26822685            index1_data_ (m.index1_data_), index2_data_ (m.index2_data_), value_data_ (m.value_data_) {
    26832686            storage_invariants ();
    26842687        }
    2685          
     2688
    26862689        BOOST_UBLAS_INLINE
    26872690        compressed_matrix (const coordinate_matrix<T, L, IB, IA, TA> &m):
    26882691            matrix_container<self_type> (),
     
    27372740        size_type nnz () const {
    27382741            return filled2_;
    27392742        }
    2740        
     2743
    27412744        // Storage accessors
    27422745        BOOST_UBLAS_INLINE
    27432746        static size_type index_base () {
     
    29422945            }
    29432946            storage_invariants ();
    29442947        }
    2945        
     2948
    29462949        // Zeroing
    29472950        BOOST_UBLAS_INLINE
    29482951        void clear () {
     
    31213124        typedef reverse_iterator_base2<iterator2> reverse_iterator2;
    31223125
    31233126        // Element lookup
    3124         // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.   
     3127        // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
    31253128        const_iterator1 find1 (int rank, size_type i, size_type j, int direction = 1) const {
    31263129            for (;;) {
    31273130                array_size_type address1 (layout_type::index_M (i, j));
     
    31613164                }
    31623165            }
    31633166        }
    3164         // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.   
     3167        // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
    31653168        iterator1 find1 (int rank, size_type i, size_type j, int direction = 1) {
    31663169            for (;;) {
    31673170                array_size_type address1 (layout_type::index_M (i, j));
     
    32013204                }
    32023205            }
    32033206        }
    3204         // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.   
     3207        // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
    32053208        const_iterator2 find2 (int rank, size_type i, size_type j, int direction = 1) const {
    32063209            for (;;) {
    32073210                array_size_type address1 (layout_type::index_M (i, j));
     
    32413244                }
    32423245            }
    32433246        }
    3244         // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.   
     3247        // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
    32453248        iterator2 find2 (int rank, size_type i, size_type j, int direction = 1) {
    32463249            for (;;) {
    32473250                array_size_type address1 (layout_type::index_M (i, j));
     
    39683971            BOOST_UBLAS_CHECK (filled2_ <= capacity_, internal_logic ());
    39693972            BOOST_UBLAS_CHECK (index1_data_ [filled1_ - 1] == k_based (filled2_), internal_logic ());
    39703973        }
    3971        
     3974
    39723975        size_type size1_;
    39733976        size_type size2_;
    39743977        array_size_type capacity_;
     
    42084211            const_pointer p = find_element (i, j);
    42094212            if (p)
    42104213                return *p;
    4211             else 
     4214            else
    42124215                return zero_;
    42134216        }
    42144217        BOOST_UBLAS_INLINE
     
    42674270            }
    42684271            storage_invariants ();
    42694272        }
    4270        
     4273
    42714274        // Zeroing
    42724275        BOOST_UBLAS_INLINE
    42734276        void clear () {
     
    43914394            m1.swap (m2);
    43924395        }
    43934396
     4397        // replacement if STL lower bound algorithm for use of inplace_merge
     4398        array_size_type lower_bound (array_size_type beg, array_size_type end, array_size_type target) const {
     4399          while (end > beg) {
     4400            array_size_type mid = (beg + end) / 2;
     4401            if (((index1_data_[mid] < index1_data_[target]) ||
     4402                 ((index1_data_[mid] == index1_data_[target]) &&
     4403                  (index2_data_[mid] < index2_data_[target])))) {
     4404              beg = mid + 1;
     4405            } else {
     4406              end = mid;
     4407            }
     4408          }
     4409          return beg;
     4410        }
     4411
     4412        // specialized replacement of STL inplace_merge to avoid compilation
     4413        // problems with respect to the array_triple iterator
     4414        void inplace_merge (array_size_type beg, array_size_type mid, array_size_type end) const {
     4415          array_size_type len_lef = mid - beg;
     4416          array_size_type len_rig = end - mid;
     4417
     4418          if (len_lef == 1 && len_rig == 1) {
     4419            if ((index1_data_[mid] < index1_data_[beg]) ||
     4420                ((index1_data_[mid] == index1_data_[beg]) && (index2_data_[mid] < index2_data_[beg])))
     4421              {
     4422                std::swap(index1_data_[beg], index1_data_[mid]);
     4423                std::swap(index2_data_[beg], index2_data_[mid]);
     4424                std::swap(value_data_[beg], value_data_[mid]);
     4425              }
     4426          } else if (len_lef > 0 && len_rig > 0) {
     4427            array_size_type lef_mid, rig_mid;
     4428            if (len_lef >= len_rig) {
     4429              lef_mid = (beg + mid) / 2;
     4430              rig_mid = lower_bound(mid, end, lef_mid);
     4431            } else {
     4432              rig_mid = (mid + end) / 2;
     4433              lef_mid = lower_bound(beg, mid, rig_mid);
     4434            }
     4435            std::rotate(&index1_data_[0] + lef_mid, &index1_data_[0] + mid, &index1_data_[0] + rig_mid);
     4436            std::rotate(&index2_data_[0] + lef_mid, &index2_data_[0] + mid, &index2_data_[0] + rig_mid);
     4437            std::rotate(&value_data_[0] + lef_mid, &value_data_[0] + mid, &value_data_[0] + rig_mid);
     4438
     4439            array_size_type new_mid = lef_mid + rig_mid - mid;
     4440            inplace_merge(beg, lef_mid, new_mid);
     4441            inplace_merge(new_mid, rig_mid, end);
     4442          }
     4443        }
     4444
    43944445        // Sorting and summation of duplicates
    43954446        BOOST_UBLAS_INLINE
    43964447        void sort () const {
    43974448            if (! sorted_ && filled_ > 0) {
    43984449                typedef index_triple_array<index_array_type, index_array_type, value_array_type> array_triple;
    43994450                array_triple ita (filled_, index1_data_, index2_data_, value_data_);
    4400 #ifndef BOOST_UBLAS_COO_ALWAYS_DO_FULL_SORT
    44014451                const typename array_triple::iterator iunsorted = ita.begin () + sorted_filled_;
    44024452                // sort new elements and merge
    44034453                std::sort (iunsorted, ita.end ());
    4404                 std::inplace_merge (ita.begin (), iunsorted, ita.end ());
    4405 #else
    4406                 const typename array_triple::iterator iunsorted = ita.begin ();
    4407                 std::sort (iunsorted, ita.end ());
    4408 #endif               
     4454                // do not use STL algorithm due to compilation problems with recent gcc
     4455                inplace_merge(0, sorted_filled_, filled_);
     4456
    44094457                // sum duplicates with += and remove
    44104458                array_size_type filled = 0;
    44114459                for (array_size_type i = 1; i < filled_; ++ i) {
     
    44344482            size_type element1 = layout_type::index_M (i, j);
    44354483            size_type element2 = layout_type::index_m (i, j);
    44364484            // must maintain sort order
    4437             BOOST_UBLAS_CHECK (sorted_ && 
     4485            BOOST_UBLAS_CHECK (sorted_ &&
    44384486                    (filled_ == 0 ||
    44394487                    index1_data_ [filled_ - 1] < k_based (element1) ||
    44404488                    (index1_data_ [filled_ - 1] == k_based (element1) && index2_data_ [filled_ - 1] < k_based (element2)))
     
    44854533        typedef reverse_iterator_base2<iterator2> reverse_iterator2;
    44864534
    44874535        // Element lookup
    4488         // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.   
     4536        // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
    44894537        const_iterator1 find1 (int rank, size_type i, size_type j, int direction = 1) const {
    44904538            sort ();
    44914539            for (;;) {
     
    45264574                }
    45274575            }
    45284576        }
    4529         // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.   
     4577        // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
    45304578        iterator1 find1 (int rank, size_type i, size_type j, int direction = 1) {
    45314579            sort ();
    45324580            for (;;) {
     
    45674615                }
    45684616            }
    45694617        }
    4570         // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.   
     4618        // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
    45714619        const_iterator2 find2 (int rank, size_type i, size_type j, int direction = 1) const {
    45724620            sort ();
    45734621            for (;;) {
     
    46084656                }
    46094657            }
    46104658        }
    4611         // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.   
     4659        // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
    46124660        iterator2 find2 (int rank, size_type i, size_type j, int direction = 1) {
    46134661            sort ();
    46144662            for (;;) {
  • libs/numeric/ublas/test/test_coordinate_vector_inplace_merge.cpp

     
     1//  Copyright (c) 2011 David Bellot
     2//
     3//  Distributed under the Boost Software License, Version 1.0. (See
     4//  accompanying file LICENSE_1_0.txt or copy at
     5//  http://www.boost.org/LICENSE_1_0.txt)
     6
     7#ifndef BOOST_UBLAS_NO_ELEMENT_PROXIES
     8# define BOOST_UBLAS_NO_ELEMENT_PROXIES
     9#endif
     10
     11#include <boost/numeric/ublas/assignment.hpp>
     12#include <boost/numeric/ublas/vector.hpp>
     13#include <boost/numeric/ublas/vector_sparse.hpp>
     14#include <boost/numeric/ublas/vector_expression.hpp>
     15#include <boost/numeric/ublas/io.hpp>
     16
     17#include "libs/numeric/ublas/test/utils.hpp"
     18
     19const double TOL = 1e-15;
     20
     21
     22template <class AE>
     23typename AE::value_type mean_square(const boost::numeric::ublas::vector_expression<AE> &me) {
     24    typename AE::value_type s(0);
     25    typename AE::size_type i;
     26    for (i=0; i!= me().size(); i++) {
     27      s += boost::numeric::ublas::scalar_traits<typename AE::value_type>::type_abs(me()(i));
     28    }
     29    return s/me().size();
     30}
     31
     32template<typename T>
     33bool check_sortedness(const boost::numeric::ublas::coordinate_vector<T>& vector) {
     34  bool result = true;
     35  typedef boost::numeric::ublas::coordinate_vector<T> vector_type;
     36  typename vector_type::index_array_type idx = vector.index_data();
     37  typename vector_type::size_type size = vector.filled();
     38
     39  for (typename vector_type::size_type i = 0; i + 1 < size && result; ++ i) {
     40    result &= (idx[i] < idx[i + 1]);
     41  }
     42  return result;
     43}
     44
     45void print_entries(size_t size,
     46                   const std::vector<size_t>& entries)
     47{
     48  std::cerr << "Error entries - Size:" << size << ". Entries: ";
     49  for (size_t i = 0; i < entries.size(); ++ i) {
     50    std::cerr << entries[i] << "; ";
     51  }
     52  std::cerr << "\n";
     53}
     54
     55BOOST_UBLAS_TEST_DEF( test_coordinate_vector_inplace_merge_random )
     56{
     57  const size_t max_repeats = 100;
     58  const size_t max_size = 100;
     59  const size_t dim_var = 10;
     60  const size_t nr_entries = 10;
     61
     62  for (size_t repeats = 1; repeats < max_repeats; ++repeats ) {
     63    for (size_t size = 1; size < max_size; size += 5) {
     64      size_t size_vec = size + rand() % dim_var;
     65
     66      boost::numeric::ublas::coordinate_vector<double> vector_coord(size_vec);
     67      boost::numeric::ublas::vector<double> vector_dense(size_vec, 0);
     68
     69      vector_coord.sort();
     70
     71      std::vector<size_t> entries;
     72      for (int entry = 0; entry < nr_entries; ++ entry) {
     73        int x = rand() % size_vec;
     74        entries.push_back(x);
     75        vector_coord.append_element(x, 1);
     76        vector_dense(x) += 1;
     77      }
     78      vector_coord.sort();
     79
     80      {
     81        bool sorted = check_sortedness(vector_coord);
     82        bool identical = mean_square(vector_coord - vector_dense) < TOL;
     83        if (!(sorted && identical)) {
     84          print_entries(size_vec, entries);
     85        }
     86        BOOST_UBLAS_TEST_CHECK( check_sortedness(vector_coord) );
     87        BOOST_UBLAS_TEST_CHECK( mean_square(vector_coord - vector_dense) < TOL);
     88      }
     89
     90      for (int entry = 0; entry < nr_entries; ++ entry) {
     91        int x = rand() % size_vec;
     92        entries.push_back(x);
     93        vector_coord(x) += 1;
     94        vector_dense(x) += 1;
     95        vector_coord.sort();
     96      }
     97
     98      {
     99        bool sorted = check_sortedness(vector_coord);
     100        bool identical = mean_square(vector_coord - vector_dense) < TOL;
     101        if (!(sorted && identical)) {
     102          print_entries(size_vec, entries);
     103        }
     104        BOOST_UBLAS_TEST_CHECK( sorted );
     105        BOOST_UBLAS_TEST_CHECK( identical );
     106      }
     107    }
     108  }
     109}
     110
     111int main()
     112{
     113    BOOST_UBLAS_TEST_BEGIN();
     114
     115    BOOST_UBLAS_TEST_DO( test_coordinate_vector_inplace_merge_random );
     116
     117    BOOST_UBLAS_TEST_END();
     118
     119    return EXIT_SUCCESS;;
     120}
  • libs/numeric/ublas/test/test_coordinate_matrix_inplace_merge.cpp

     
     1//  Copyright (c) 2011 David Bellot
     2//
     3//  Distributed under the Boost Software License, Version 1.0. (See
     4//  accompanying file LICENSE_1_0.txt or copy at
     5//  http://www.boost.org/LICENSE_1_0.txt)
     6
     7#ifndef BOOST_UBLAS_NO_ELEMENT_PROXIES
     8# define BOOST_UBLAS_NO_ELEMENT_PROXIES
     9#endif
     10
     11#include <boost/numeric/ublas/assignment.hpp>
     12#include <boost/numeric/ublas/matrix.hpp>
     13#include <boost/numeric/ublas/matrix_sparse.hpp>
     14#include <boost/numeric/ublas/matrix_expression.hpp>
     15#include <boost/numeric/ublas/io.hpp>
     16
     17#include "libs/numeric/ublas/test/utils.hpp"
     18
     19using std::cout;
     20using std::endl;
     21
     22const double TOL = 1e-15;
     23
     24template <class AE>
     25typename AE::value_type mean_square(const boost::numeric::ublas::matrix_expression<AE> &me) {
     26    typename AE::value_type s(0);
     27    typename AE::size_type i, j;
     28    for (i=0; i!= me().size1(); i++) {
     29        for (j=0; j!= me().size2(); j++) {
     30          s += boost::numeric::ublas::scalar_traits<typename AE::value_type>::type_abs(me()(i,j));
     31        }
     32    }
     33    return s/me().size1()*me().size2();
     34}
     35
     36template<typename T>
     37bool check_sortedness(const boost::numeric::ublas::coordinate_matrix<T>& matrix) {
     38  bool result = true;
     39  typedef boost::numeric::ublas::coordinate_matrix<T> matrix_type;
     40  typename matrix_type::index_array_type i1 = matrix.index1_data();
     41  typename matrix_type::index_array_type i2 = matrix.index2_data();
     42  typename matrix_type::array_size_type size = matrix.filled();
     43
     44  for (typename matrix_type::array_size_type i = 0; i + 1 < size && result; ++ i) {
     45    result &= ( (i1[i] < i1[i + 1]) ||
     46                ((i1[i] == i1[i]) &&
     47                 (i2[i] < i2[i + 1])) );
     48
     49  }
     50  return result;
     51}
     52
     53void print_entries(size_t size_x, size_t size_y,
     54                   const std::vector<std::pair<size_t, size_t> >& entries)
     55{
     56  std::cerr << "Error - Size:" << size_x << " x " << size_y << ". Entries: ";
     57  for (size_t i = 0; i < entries.size(); ++ i) {
     58    std::cerr << entries[i].first << ", " << entries[i].second << "; ";
     59  }
     60  std::cerr << "\n";
     61}
     62
     63
     64BOOST_UBLAS_TEST_DEF( test_coordinate_matrix_inplace_merge_random )
     65{
     66  const size_t max_repeats = 100;
     67  const size_t max_size = 100;
     68  const size_t dim_var = 10;
     69  const size_t nr_entries = 10;
     70
     71  for (size_t repeats = 1; repeats < max_repeats; ++repeats ) {
     72    for (size_t size = 1; size < max_size; size += 5) {
     73      size_t size_x = size + rand() % dim_var;
     74      size_t size_y = size + rand() % dim_var;
     75
     76      boost::numeric::ublas::coordinate_matrix<double> matrix_coord(size_x, size_y);
     77      boost::numeric::ublas::matrix<double> matrix_dense(size_x, size_y, 0);
     78
     79      matrix_coord.sort();
     80
     81      std::vector<std::pair<size_t, size_t> > entries;
     82      for (int entry = 0; entry < nr_entries; ++ entry) {
     83        int x = rand() % size_x;
     84        int y = rand() % size_y;
     85        entries.push_back(std::make_pair(x, y));
     86        matrix_coord.append_element(x, y, 1);
     87        matrix_dense(x, y) += 1;
     88      }
     89      matrix_coord.sort();
     90
     91      {
     92        bool sorted = check_sortedness(matrix_coord);
     93        bool identical = mean_square(matrix_coord - matrix_dense) < TOL;
     94        if (!(sorted && identical)) {
     95          print_entries(size_x, size_y, entries);
     96        }
     97        BOOST_UBLAS_TEST_CHECK( check_sortedness(matrix_coord) );
     98        BOOST_UBLAS_TEST_CHECK( mean_square(matrix_coord - matrix_dense) < TOL);
     99      }
     100
     101      for (int entry = 0; entry < nr_entries; ++ entry) {
     102        int x = rand() % size_x;
     103        int y = rand() % size_y;
     104        entries.push_back(std::make_pair(x, y));
     105        matrix_coord(x, y) += 1;
     106        matrix_dense(x, y) += 1;
     107        matrix_coord.sort();
     108      }
     109
     110      {
     111        bool sorted = check_sortedness(matrix_coord);
     112        bool identical = mean_square(matrix_coord - matrix_dense) < TOL;
     113        if (!(sorted && identical)) {
     114          print_entries(size_x, size_y, entries);
     115        }
     116        BOOST_UBLAS_TEST_CHECK( sorted );
     117        BOOST_UBLAS_TEST_CHECK( identical );
     118      }
     119    }
     120  }
     121}
     122
     123int main()
     124{
     125    BOOST_UBLAS_TEST_BEGIN();
     126
     127    BOOST_UBLAS_TEST_DO( test_coordinate_matrix_inplace_merge_random );
     128
     129    BOOST_UBLAS_TEST_END();
     130
     131    return EXIT_SUCCESS;;
     132}