| Prev | Next |  |  |  |  |  | multi_newton_worker |

Do One Thread's Work for Multi-Threaded Newton Method
Syntax
`multi_newton_worker()`
Purpose
This function finds all the zeros in the interval `[ low , up ]` .
low
This is the value of the multi_newton_common information `
low = work_all_[thread_num]->xlow
`
up
This is the value of the multi_newton_common information `
up = work_all_[thread_num]->xup
`
thread_num
This is the number for the current thread; see thread_num .
Source

    namespace {
    void multi_newton_worker(void)
    {
         // Split [xlow, xup] into num_sub intervales and
         // look for one zero in each sub-interval.
         size_t thread_num    = thread_alloc::thread_num();
         size_t num_threads   = std::max(num_threads_, size_t(1));
         bool   ok            = thread_num < num_threads;
         size_t num_sub       = work_all_[thread_num]->num_sub;
         double xlow          = work_all_[thread_num]->xlow;
         double xup           = work_all_[thread_num]->xup;
         vector<double>& x    = work_all_[thread_num]->x;

         // check arguments
         ok &= max_itr_ > 0;
         ok &= num_sub > 0;
         ok &= xlow < xup;
         ok &= x.size() == 0;

         // check for special case where there is nothing for this thread to do
         if( num_sub == 0 )
         {     work_all_[thread_num]->ok = ok;
              return;
         }

         // check for a zero on each sub-interval
         size_t i;
         double xlast = xlow - 2.0 * sub_length_; // over sub_length_ away from x_low
         double flast = 2.0 * epsilon_;           // any value > epsilon_ would do
         for(i = 0; i < num_sub; i++)
         {
              // note that when i == 0, xlow_i == xlow (exactly)
              double xlow_i = xlow + double(i) * sub_length_;

              // note that when i == num_sub - 1, xup_i = xup (exactly)
              double xup_i  = xup  - double(num_sub - i - 1) * sub_length_;

              // initial point for Newton iterations
              double xcur = (xup_i + xlow_i) / 2.;

              // Newton iterations
              bool more_itr = true;
              size_t itr    = 0;
              // initialize these values to avoid MSC C++ warning
              double fcur=0.0, dfcur=0.0;
              while( more_itr )
              {     fun_(xcur, fcur, dfcur);

                   // check end of iterations
                   if( fabs(fcur) <= epsilon_ )
                        more_itr = false;
                   if( (xcur == xlow_i ) & (fcur * dfcur > 0.) )
                        more_itr = false;
                   if( (xcur == xup_i)   & (fcur * dfcur < 0.) )
                        more_itr = false;

                   // next Newton iterate
                   if( more_itr )
                   {     xcur = xcur - fcur / dfcur;
                        // keep in bounds
                        xcur = std::max(xcur, xlow_i);
                        xcur = std::min(xcur, xup_i);

                        more_itr = ++itr < max_itr_;
                   }
              }
              if( fabs( fcur ) <= epsilon_ )
              {     // check for case where xcur is lower bound for this
                   // sub-interval and upper bound for previous sub-interval
                   if( fabs(xcur - xlast) >= sub_length_ )
                   {     x.push_back( xcur );
                        xlast = xcur;
                        flast = fcur;
                   }
                   else if( fabs(fcur) < fabs(flast) )
                   {     x[ x.size() - 1] = xcur;
                        xlast            = xcur;
                        flast            = fcur;
                   }
              }
         }
         work_all_[thread_num]->ok = ok;
    }
    }

Input File: example/multi_thread/multi_newton.cpp