namespace {
bool multi_newton_takedown(vector<double>& xout)
{ // number of threads in the calculation
size_t num_threads = std::max(num_threads_, size_t(1));
// remove duplicates and points that are not solutions
xout.resize(0);
bool ok = true;
ok &= thread_alloc::thread_num() == 0;
// initialize as more that sub_length_ / 2 from any possible solution
double xlast = - sub_length_;
for(size_t thread_num = 0; thread_num < num_threads; thread_num++)
{ vector<double>& x = work_all_[thread_num]->x;
size_t i;
for(i = 0; i < x.size(); i++)
{ // check for case where this point is lower limit for this// thread and upper limit for previous threadif( fabs(x[i] - xlast) >= sub_length_ )
{ xout.push_back( x[i] );
xlast = x[i];
}
else
{ double fcur, flast, df;
fun_(x[i], fcur, df);
fun_(xlast, flast, df);
if( fabs(fcur) < fabs(flast) )
{ xout[ xout.size() - 1] = x[i];
xlast = x[i];
}
}
}
// check that this thread was ok with the work it did
ok &= work_all_[thread_num]->ok;
}
// go down so free memory for other threads before memory for master
size_t thread_num = num_threads;
while(thread_num--)
{
# if USE_THREAD_ALLOC_FOR_WORK_ALL
// call the destructor for vector destructor
work_all_[thread_num]->x.~vector<double>();
// delete the raw memory allocation
void* v_ptr = static_cast<void*>( work_all_[thread_num] );
thread_alloc::return_memory( v_ptr );
# elsedelete work_all_[thread_num];
# endif// Note that xout corresponds to memroy that is inuse by master// (so we can only chech have freed all their memory).if( thread_num > 0 )
{ // check that there is no longer any memory inuse by this thread
ok &= thread_alloc::inuse(thread_num) == 0;
// return all memory being held for future use by this thread
thread_alloc::free_available(thread_num);
}
}
// now we are done with the work_all_ vector so free its memory// (because it is a static variable)
work_all_.clear();
return ok;
}
}