|
Prev
| Next
|
|
|
|
|
|
multi_newton_worker |
|
@(@\newcommand{\W}[1]{ \; #1 \; }
\newcommand{\R}[1]{ {\rm #1} }
\newcommand{\B}[1]{ {\bf #1} }
\newcommand{\D}[2]{ \frac{\partial #1}{\partial #2} }
\newcommand{\DD}[3]{ \frac{\partial^2 #1}{\partial #2 \partial #3} }
\newcommand{\Dpow}[2]{ \frac{\partial^{#1}}{\partial {#2}^{#1}} }
\newcommand{\dpow}[2]{ \frac{ {\rm d}^{#1}}{{\rm d}\, {#2}^{#1}} }@)@This is cppad-20221105 documentation. Here is a link to its
current documentation
.
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