// // C++ Implementation: Locator // // Description: // // // Author: Takeshi Nakazato , (C) 2012 // // Copyright: See COPYING file that comes with this distribution // // #include #include #include #include "Locator.h" namespace asap { template Locator::Locator() : x_(0), n_(0), ascending_(true), copy_(false) { } template Locator::Locator(T *v, unsigned int n, bool copystorage) : x_(0), n_(0), ascending_(true), copy_(false) { set(v, n, copystorage); } template Locator::~Locator() { if (copy_ && x_) delete[] x_; } template void Locator::set(T *v, unsigned int n, bool copystorage) { if (copy_) { if (!copystorage || n > n_) { delete[] x_; x_ = 0; } } copy_ = copystorage; n_ = n; if (copy_) { if (!x_) x_ = new double[n_]; for (unsigned int i = 0; i < n_; i++) x_[i] = v[i]; } else { x_ = v; } assert(n_ > 0); if (n_ == 0) { throw std::runtime_error("Input array length is 0."); } ascending_ = (x_[0] <= x_[n_-1]); } template unsigned int Locator::bisection(T x, unsigned int left, unsigned int right) { unsigned int jl = left; unsigned int ju = right; if (ascending_) { // ascending order if (x <= x_[0]) return 0; else if (x > x_[n_-1]) return n_; unsigned int jm; while (ju - jl > 1) { jm = (ju + jl) / 2; if (x > x_[jm]) jl = jm; else ju = jm; } } else { // descending order if (x >= x_[0]) return 0; else if (x < x_[n_-1]) return n_; unsigned int jm; while (ju - jl > 1) { jm = (ju + jl) / 2; if (x < x_[jm]) jl = jm; else ju = jm; } } return ju; } }