267 "DampenedNewtonNonlinearSolver<Scalar>::solve(...)",
268 *x_inout->
space(), *model_->get_x_space() );
279 if(out.
get() && showNewtonIters) {
280 *out <<
"\nBeginning dampended Newton solve of model = " << model_->description() <<
"\n\n";
281 if (!useDampenedLineSearch())
282 *out <<
"\nDoing undampened newton ...\n\n";
286 if(!J_.get()) J_ = model_->create_W();
292 V_S(ee.
ptr(),ST::zero());
296 int maxIters = this->defaultMaxNewtonIterations();
300 ,
"DampenedNewtonNonlinearSolver<Scalar>::solve(...): Error, can only support resudual-based"
301 " convergence criteria!");
304 solveCriteria->
extraParameters->validateParameters(*getValidSolveCriteriaExtraParameters());
305 maxIters = solveCriteria->
extraParameters->get(
"Max Iters",
int(maxIters));
309 if(out.
get() && showNewtonDetails)
310 *out <<
"\nCompute the initial starting point ...\n";
312 eval_f_W( *model_, *x, &*f, &*J_ );
313 if(out.
get() && dumpAll) {
314 *out <<
"\nInitial starting point:\n";
315 *out <<
"\nx =\n" << *x;
316 *out <<
"\nf =\n" << *f;
317 *out <<
"\nJ =\n" << *J_;
321 int newtonIter, num_residual_evals = 1;
325 for( newtonIter = 1; newtonIter <= maxIters; ++newtonIter ) {
327 if(out.
get() && showNewtonDetails) *out <<
"\n*** newtonIter = " << newtonIter << endl;
330 if(out.
get() && showNewtonDetails) *out <<
"\nChecking for convergence ... : ";
331 const Scalar phi = scalarProd(*f,*f), sqrt_phi = ST::squareroot(phi);
333 const bool isConverged = sqrt_phi <= tol;
334 if(out.
get() && showNewtonDetails) *out
335 <<
"sqrt(phi) = sqrt(<f,f>) = ||f|| = " << sqrt_phi << ( isConverged ?
" <= " :
" > " ) <<
"tol = " << tol << endl;
336 if(out.
get() && showNewtonIters) *out
337 <<
"newton_iter="<<newtonIter<<
": Check convergence: ||f|| = "
338 << sqrt_phi << ( isConverged ?
" <= " :
" > " ) <<
"tol = " << tol << ( isConverged ?
", Converged!!!" :
"" ) << endl;
340 if(x_inout != x.
get()) assign( ptr(x_inout), *x );
341 if(out.
get() && showNewtonDetails) {
342 *out <<
"\nWe have converged :-)\n"
343 <<
"\n||x||inf = " << norm_inf(*x) << endl;
344 if(dumpAll) *out <<
"\nx =\n" << *x;
345 *out <<
"\nExiting SimpleNewtonSolver::solve(...)\n";
347 std::ostringstream oss;
348 oss <<
"Converged! ||f|| = " << sqrt_phi <<
", num_newton_iters="<<newtonIter<<
", num_residual_evals="<<num_residual_evals<<
".";
350 solveStatus.
message = oss.str();
353 if(out.
get() && showNewtonDetails) *out <<
"\nWe have to keep going :-(\n";
357 if(out.
get() && showNewtonDetails) *out <<
"\nComputing the Jacobian J_ at current point ...\n";
358 eval_f_W<Scalar>( *model_, *x, NULL, &*J_ );
359 if(out.
get() && dumpAll) *out <<
"\nJ =\n" << *J_;
363 if(out.
get() && showNewtonDetails) *out <<
"\nComputing the Newton step: dx = - inv(J)*f ...\n";
364 if(out.
get() && showNewtonIters) *out <<
"newton_iter="<<newtonIter<<
": Computing Newton step ...\n";
365 assign( dx.
ptr(), ST::zero() );
367 Vt_S( dx.
ptr(), Scalar(-ST::one()) );
368 Vp_V( ee.
ptr(), *dx);
369 if(out.
get() && showNewtonDetails) *out <<
"\n||dx||inf = " << norm_inf(*dx) << endl;
370 if(out.
get() && dumpAll) *out <<
"\ndy =\n" << *dx;
373 if(out.
get() && showNewtonDetails) *out <<
"\nStarting backtracking line search iterations ...\n";
374 if(out.
get() && showNewtonIters) *out <<
"newton_iter="<<newtonIter<<
": Starting backtracking line search ...\n";
375 const Scalar Dphi = -2.0*phi;
378 ++num_residual_evals;
379 for( lineSearchIter = 1; lineSearchIter <= maxLineSearchIterations(); ++lineSearchIter, ++num_residual_evals ) {
381 if(out.
get() && showNewtonDetails) *out <<
"\n*** lineSearchIter = " << lineSearchIter << endl;
383 assign( x_new.
ptr(), *x ); Vp_StV( x_new.
ptr(), alpha, *dx );
384 if(out.
get() && showNewtonDetails) *out <<
"\n||x_new||inf = " << norm_inf(*x_new) << endl;
385 if(out.
get() && dumpAll) *out <<
"\nx_new =\n" << *x_new;
387 eval_f(*model_,*x_new,&*f);
388 if(out.
get() && dumpAll) *out <<
"\nf_new =\n" << *f;
389 const Scalar phi_new = scalarProd(*f,*f), phi_frac = phi + alpha * armijoConstant() * Dphi;
390 if(out.
get() && showNewtonDetails) *out <<
"\nphi_new = <f_new,f_new> = " << phi_new << endl;
392 if(out.
get() && showNewtonDetails) *out <<
"\nphi_new is not a valid number, backtracking (alpha = 0.1*alpha) ...\n";
396 const bool acceptPoint = (phi_new <= phi_frac);
397 if(out.
get() && showNewtonDetails) *out
398 <<
"\nphi_new = " << phi_new << ( acceptPoint ?
" <= " :
" > " )
399 <<
"phi + alpha * eta * Dphi = " << phi <<
" + " << alpha <<
" * " << armijoConstant() <<
" * " << Dphi
400 <<
" = " << phi_frac << endl;
401 if(out.
get() && (showLineSearchIters || (showNewtonIters && acceptPoint))) *out
402 <<
"newton_iter="<<newtonIter<<
", ls_iter="<<lineSearchIter<<
" : "
403 <<
"phi(alpha="<<alpha<<
") = "<<phi_new<<(acceptPoint ?
" <=" :
" >")<<
" armijo_cord = " << phi_frac << endl;
404 if (out.
get() && showNewtonDetails && !useDampenedLineSearch())
405 *out <<
"\nUndamped newton, always accpeting the point!\n";
406 if( acceptPoint || !useDampenedLineSearch() ) {
407 if(out.
get() && showNewtonDetails) *out <<
"\nAccepting the current step with step length alpha = " << alpha <<
"!\n";
410 if(out.
get() && showNewtonDetails) *out <<
"\nBacktracking (alpha = 0.5*alpha) ...\n";
415 if( lineSearchIter > maxLineSearchIterations() ) {
416 std::ostringstream oss;
418 <<
"lineSearchIter = " << lineSearchIter <<
" > maxLineSearchIterations = " << maxLineSearchIterations()
419 <<
": Linear search failure! Algorithm terminated!";
420 solveStatus.
message = oss.str();
421 if(out.
get() && (showNewtonIters || showNewtonDetails)) *out << endl << oss.str() << endl;
426 std::swap<RCP<VectorBase<Scalar> > >( x_new, x );
432 if(out.
get() && showNewtonIters) *out
433 <<
"\n[Final] newton_iters="<<newtonIter<<
", num_residual_evals="<<num_residual_evals<<
"\n";
435 if(newtonIter > maxIters) {
436 std::ostringstream oss;
438 <<
"newton_iter = " << newtonIter <<
" > maxIters = " << maxIters
439 <<
": Newton algorithm terminated!";
440 solveStatus.
message = oss.str();
441 if( out.
get() && (showNewtonIters || showNewtonDetails)) *out << endl << oss.str() << endl;
444 if(x_inout != x.
get()) assign( ptr(x_inout), *x );
445 if(delta != NULL) assign( ptr(delta), *ee );
446 current_x_ = x_inout->
clone_v();
447 J_is_current_ = newtonIter==1;
449 if(out.
get() && showNewtonDetails) *out
450 <<
"\n*** Ending dampended Newton solve." << endl;