// NewtonSolver by Walter Bislin, 07.10.2015 // http://walter.bislins.ch // You may do what ever you want with this file and code! function SolveWithNewton( fn, target, guess, prec, data ) { // function aFunction( x, data ) // aData: user data passed to aFunction // In data you can specify properties: // { MaxLoops: 1000 } // Solver returns in aData: // { Result, Status, NLoops } var dx, X, Y, Y1, Y2, Xnew, slope; data = data || NewtonSolver; data.Result = 0; data.Status = ''; data.NLoops = 0; fn = fn || function(x,d){ d.Status='no function defined'; return x; }; target = target || 0; guess = guess || 0; prec = prec || 0.0001; var maxLoops = data.MaxLoops || 1000; var nLoops = 0; var eps = prec / 2.0; var eps2 = eps / 2; Xnew = guess; do { X = Xnew; try { Y = fn( X, data ) - target; if (Y == 0) break; // exact solution found Y1 = fn( X-eps2, data ) - target; if (Y1 == 0) { // exact solution found Xnew = X - eps2; break; } Y2 = fn( X + eps2, data ) - target; if (Y2 == 0) { // exact solution found Xnew = X + eps2; break; } slope = (Y2 - Y1) / eps; if (slope == 0) { // slope zero, cant find a solution data.Status = 'extremum found'; break; } Xnew = X - (Y / slope); } catch(err) { data.Status = err.message; break; } nLoops++; dx = Math.abs( Xnew - X ); } while ((dx > prec) && (nLoops < maxLoops)); if (data.Status == '' && nLoops >= maxLoops) data.Status = 'max loops exceedet'; data.NLoops = nLoops; data.Result = (data.Status == '') ? Xnew : 0; return data.Result; } var NewtonSolver = { MaxLoops: 1000, Result: 0, Status: '', NLoops: 0 };