/* Copyright 2013 IST Austria Contributed by: Jan Reininghaus This file is part of PHAT. PHAT is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. PHAT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with PHAT. If not, see . */ #pragma once #include namespace phat { class vector_heap { protected: std::vector< dimension > dims; std::vector< column > matrix; mutable thread_local_storage< column > temp_column_buffer; // std::vector< index > steps_since_last_prune; protected: //void _prune( index idx ) //{ // temp_column_buffer( ).clear( ); // _get_col( idx, temp_column_buffer( ) ); //} index _pop_max_index( index idx ) { return _pop_max_index( matrix[ idx ] ); } index _pop_max_index( column& col ) const { if( col.empty( ) ) return -1; else { index max_element = col.front( ); std::pop_heap( col.begin( ), col.end( ) ); col.pop_back( ); while( !col.empty( ) && col.front( ) == max_element ) { std::pop_heap( col.begin( ), col.end( ) ); col.pop_back( ); if( col.empty( ) ) return -1; else { max_element = col.front( ); std::pop_heap( col.begin( ), col.end( ) ); col.pop_back( ); } } return max_element; } } public: // overall number of cells in boundary_matrix index _get_num_cols( ) const { return (index)matrix.size( ); } void _set_num_cols( index nr_of_columns ) { dims.resize( nr_of_columns ); matrix.resize( nr_of_columns ); // steps_since_last_prune.assign( nr_of_columns, 0 ); } // dimension of given index dimension _get_dim( index idx ) const { return dims[ idx ]; } void _set_dim( index idx, dimension dim ) { dims[ idx ] = dim; } // replaces(!) content of 'col' with boundary of given index void _get_col( index idx, column& col ) const { temp_column_buffer( ) = matrix[ idx ]; index max_index = _pop_max_index( temp_column_buffer() ); while( max_index != -1 ) { col.push_back( max_index ); max_index = _pop_max_index( temp_column_buffer( ) ); } std::reverse( col.begin( ), col.end( ) ); } void _set_col( index idx, const column& col ) { matrix[ idx ] = col; std::make_heap( matrix[ idx ].begin( ), matrix[ idx ].end( ) ); } // true iff boundary of given idx is empty bool _is_empty( index idx ) const { return _get_max_index( idx ) == -1; } // largest row index of given column idx (new name for lowestOne()) index _get_max_index( index idx ) const { column& col = const_cast< column& >( matrix[ idx ] ); index max_element = _pop_max_index( col ); col.push_back( max_element ); std::push_heap( col.begin( ), col.end( ) ); return max_element; } // removes the maximal index of a column void _remove_max( index idx ) { _pop_max_index( idx ); } // clears given column void _clear( index idx ) { matrix[ idx ].clear( ); } // syncronizes all data structures (essential for openmp stuff) void _sync( ) {} // adds column 'source' to column 'target' void _add_to( index source, index target ) { for( index idx = 0; idx < (index)matrix[ source ].size( ); idx++ ) { matrix[ target ].push_back( matrix[ source ][ idx ] ); std::push_heap( matrix[ target ].begin( ), matrix[ target ].end( ) ); } // steps_since_last_prune[ target ] += matrix[ source ].size(); //if( 2 * steps_since_last_prune[ target ] > matrix[ target ].size() ) { // // std::cout << "Prune" << std::endl; // _prune( target ); // steps_since_last_prune[ target ] = 0; //} } }; }