Add the Newton decrement as a termination criterion of the Newton solver.
After an accepted line-search step, the solver has already rebuilt the gradient and Hessian and solved for the next search direction, so the Newton decrement 0.5*g'*H^-1*g -- the quadratic model's predicted cost improvement of the next iteration -- costs one dot product. Terminating when it falls below tolerance avoids running one more iteration only to observe a correspondingly small actual improvement. This is a C port of Alain's proposal in MJWarp: https://github.com/google-deepmind/mujoco_warp/pull/1520 PiperOrigin-RevId: 947768034 Change-Id: I94e5c71a4e2b4a7775611edd1dad254bba2633b4
This commit is contained in:
committed by
Copybara-Service
parent
2444defc63
commit
1e66efd114
@@ -2393,12 +2393,17 @@ static void mj_solPrimal(const mjModel* m, mjData* d, int island, int maxiter, i
|
||||
saveStats(m, d, island, iter, improvement, gradient, ctx.LSslope,
|
||||
ctx.nactive, nchange, ctx.LSiter, ctx.nupdate);
|
||||
|
||||
// Newton decrement: 0.5*grad'*H^-1*grad, the model's predicted improvement of the
|
||||
// next step; clamp to 0 so that tolerance == 0 keeps early termination disabled
|
||||
mjtNum decrement = flg_Newton ? mju_max(0, 0.5*scale*mju_dot(ctx.grad, ctx.Mgrad, nv)) : 0;
|
||||
|
||||
// increment iteration count
|
||||
iter++;
|
||||
|
||||
// termination
|
||||
if ((improvement > 0 && improvement < m->opt.tolerance) ||
|
||||
gradient < m->opt.tolerance) {
|
||||
gradient < m->opt.tolerance ||
|
||||
(flg_Newton && decrement < m->opt.tolerance)) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user