void Miniball<CoordAccessor>::mtf_mb (Sit n) { // Algorithm 1: mtf_mb (L_{n-1}, B), where L_{n-1} = [L.begin, n) // B: the set of forced points, defining the current ball // S: the superset of support points computed by the algorithm // -------------------------------------------------------------- // from B. Gaertner, Fast and Robust Smallest Enclosing Balls, ESA 1999, // http://www.inf.ethz.ch/personal/gaertner/texts/own_work/esa99_final.pdf // PRE: B = S assert (fsize == ssize); support_end = L.begin(); if ((fsize) == d+1) return; // incremental construction for (Sit i = L.begin(); i != n;) { // INV: (support_end - L.begin() == |S|-|B|) assert (std::distance (L.begin(), support_end) == ssize - fsize); Sit j = i++; if (excess(*j) > nt0) if (push(*j)) { // B := B + p_i mtf_mb (j); // mtf_mb (L_{i-1}, B + p_i) pop(); // B := B - p_i mtf_move_to_front(j); } } // POST: the range [L.begin(), support_end) stores the set S\B }
void Miniball::build (bool pivoting) { B.reset(); support_end = L.begin(); if (pivoting) pivot_mb (L.end()); else mtf_mb (L.end()); }
void Miniball::pivot_mb (It i) { It t = ++L.begin(); mtf_mb (t); double max_e, old_sqr_r; do { It pivot; max_e = max_excess (t, i, pivot); if (max_e > 0) { t = support_end; if (t==pivot) ++t; old_sqr_r = B.squared_radius(); B.push (*pivot); mtf_mb (support_end); B.pop(); move_to_front (pivot); } } while ((max_e > 0) && (B.squared_radius() > old_sqr_r)); }
void Miniball::mtf_mb (It i) { support_end = L.begin(); if ((B.size())==BSIZE) return; for (It k=L.begin(); k!=i;) { It j=k++; if (B.excess(*j) > 0) { if (B.push(*j)) { mtf_mb (j); B.pop(); move_to_front(j); } } } }
void Miniball<CoordAccessor>::pivot_mb (Pit n) { // Algorithm 2: pivot_mb (L_{n-1}), where L_{n-1} = [L.begin, n) // -------------------------------------------------------------- // from B. Gaertner, Fast and Robust Smallest Enclosing Balls, ESA 1999, // http://www.inf.ethz.ch/personal/gaertner/texts/own_work/esa99_final.pdf NT old_sqr_r; const NT* c; Pit pivot, k; NT e, max_e, sqr_r; Cit p; do { old_sqr_r = current_sqr_r; sqr_r = current_sqr_r; pivot = points_begin; max_e = nt0; for (k = points_begin; k != n; ++k) { p = coord_accessor(k); e = -sqr_r; c = current_c; for (int j=0; j<d; ++j) e += mb_sqr<NT>(*p++-*c++); if (e > max_e) { max_e = e; pivot = k; } } if (max_e > nt0) { // check if the pivot is already contained in the support set if (std::find(L.begin(), support_end, pivot) == support_end) { assert (fsize == 0); if (push (pivot)) { mtf_mb(support_end); pop(); pivot_move_to_front(pivot); } } } } while (old_sqr_r < current_sqr_r); }