numeric.grdec = function uncmin(f,x0,tol,gradient,maxit,callback,options) { var grad = numeric.gradient; if(typeof options === "undefined") { options = {}; } if(typeof tol === "undefined") { tol = 1e-8; } if(typeof gradient === "undefined") { gradient = function(x) { return grad(f,x); }; } if(typeof maxit === "undefined") maxit = 1000; x0 = numeric.clone(x0); var n = x0.length; var f0 = f(x0),f1,df0; if(isNaN(f0)) throw new Error('uncmin: f(x0) is a NaN!'); var max = Math.max, norm2 = numeric.norm2; tol = max(tol,numeric.epsilon); var step,g0,g1,H1 = options.Hinv || numeric.identity(n); var dot = numeric.dot, inv = numeric.inv, sub = numeric.sub, add = numeric.add, ten = numeric.tensor, div = numeric.div, mul = numeric.mul; var all = numeric.all, isfinite = numeric.isFinite, neg = numeric.neg; var it=0,i,s,x1,y,Hy,Hs,ys,i0,t,nstep,t1,t2; var msg = ""; g0 = gradient(x0); while(it= 0.1*t*df0 || isNaN(f1)) { t *= 0.5; ++it; continue; } break; } if(t*nstep < tol) { msg = "Line search step size smaller than tol"; break; } if(it === maxit) { msg = "maxit reached during line search"; break; } g1 = gradient(x1); y = sub(g1,g0); ys = dot(y,s); Hy = dot(H1,y); // H1 = sub(add(H1, // mul( // (ys+dot(y,Hy))/(ys*ys), // ten(s,s) )), // div(add(ten(Hy,s),ten(s,Hy)),ys)); x0 = x1; f0 = f1; g0 = g1; ++it; } return {solution: x0, f: f0, gradient: g0, invHessian: H1, iterations:it, message: msg}; }