![]() |
Prev | Next | multi_newton_takedown |
ok = harmonic_takedown(xout)
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 thread if( 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 ); # else delete 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; } }