void ITM<ITM_TRAITS>::handleDeletions( node_type best, node_type second ) { observation_type & bestCentroid = graph_[best].centroid; observation_type & secondCentroid = graph_[second].centroid; // Don't know of other way to avoid iterator invalidation than to do this // twice. out_edge_iterator iChild; out_edge_iterator eChild; typename std::list<node_type> erase; for ( boost::tie( iChild, eChild ) = boost::out_edges( best, graph_ ); iChild != eChild; ++iChild ) { node_type child = boost::target( *iChild, graph_ ); if ( child != best ) { // Do not try to delete self-edges observation_type centroid = graph_[child].centroid; observation_type center = ( bestCentroid + centroid ) * 0.5; if ( distance_( center, secondCentroid ) < distance_( center, centroid ) ) { erase.push_back( child ); } } } typename std::list<node_type>::iterator iErase; typename std::list<node_type>::iterator eErase = erase.end(); for ( iErase = erase.begin(); iErase != eErase; ++iErase ) { boost::remove_edge( best, *iErase, graph_ ); boost::remove_edge( *iErase, best, graph_ ); boost::tie( iChild, eChild ) = boost::out_edges( *iErase, graph_ ); // The or condition is to handle self-edges if ( iChild == eChild || ( std::distance( iChild, eChild ) == 1 && boost::target( *iChild, graph_ ) == *iErase ) ) { boost::clear_vertex( *iErase, graph_ ); boost::remove_vertex( *iErase, graph_ ); } } }
static void dispatch(int n, int m, double *x_ptr, double *c_ptr, double *d_ptr, int nlhs, mxArray *plhs[]) { // Read parameters typename KDTree<K, double>::points_type X; typename KDTree<K, double>::point_type v; for (int i = 0; i < n; ++i) { for (unsigned k = 0; k < K; ++k) v[k] = x_ptr[i + (n * k)]; X.push_back(v); } typename KDTree<K, double>::points_type C; std::vector<double> R; for (int i = 0; i < m; ++i) { for (unsigned k = 0; k < K; ++k) v[k] = c_ptr[i + (m * k)]; C.push_back(v); R.push_back(d_ptr[i]); } // Build kd-tree KDTree<K, double> kdtree(X); // Compute queries std::list<typename KDTree<K, double>::set_type > res_list; typename KDTree<K, double>::set_type res; for (int i = 0; i < m; ++i) { kdtree.ball_query(C[i], R[i], res); res_list.push_back(res); res.clear(); } // Write output if (nlhs > 0) { const mwSize size[2] = {res_list.size(), 1}; plhs[0] = mxCreateCellArray(2, size); int cnt = 0; for (typename std::list<typename KDTree<K, double>::set_type>::const_iterator it = res_list.begin(); it != res_list.end(); ++it, ++cnt) { if (it->size()) { mxArray * pArray = mxCreateDoubleMatrix(it->size(), 1, mxREAL); double * p = mxGetPr(pArray); for (typename KDTree<K, double>::set_type::const_iterator it2 = it->begin(); it2 != it->end(); ++it2) *p++ = it2->second + 1; mxSetCell(plhs[0], cnt, pArray); } } } if (nlhs > 1) { const mwSize size[2] = {res_list.size(), 1}; plhs[1] = mxCreateCellArray(2, size); int cnt = 0; for (typename std::list<typename KDTree<K, double>::set_type>::const_iterator it = res_list.begin(); it != res_list.end(); ++it, ++cnt) { if (it->size()) { mxArray * pArray = mxCreateDoubleMatrix(it->size(), 1, mxREAL); double * p = mxGetPr(pArray); for (typename KDTree<K, double>::set_type::const_iterator it2 = it->begin(); it2 != it->end(); ++it2) *p++ = it2->first; mxSetCell(plhs[1], cnt, pArray); } } } }