BeginPackage["ISP`Newton`"]

AnimateNewton::usage = "AnimateNewton[f, g, n, {low, high}] animates n
iterations of Newton's method for finding the root of f beginning with
a guess of g.  The portion of the x-axis between low and high is shown."

Begin["Private`"]

minmax[h_, low_, high_] :=
  Module[{x, delta, min, max, value, extra},
         (delta = (high-low)/1000.;
          x = low;
          i = 1000;
          min = max = h[x];
          While[i > 1,
                (x = x + delta;
                 value = h[x];
                 If[value < min, min = value];
                 If[value > max, max = value];
                 i = i-1)];
          extra = (max - min) * .1;
          Return[{min-extra, max+extra}])]
         

doNewton[h_, hprime_, g_] := g - h[g]/hprime[g]

plotTangent[h_, hprime_, tangent_, low_, high_] :=
  Module[{x},
         Plot[hprime[tangent]*x + h[tangent] - hprime[tangent]*tangent,
              {x, low, high}, DisplayFunction->Identity]]
              

AnimateNewton[h_, guess_, nframes_, {low_, high_}] :=
  Module[{i, x, g, hprime, thePlot, aPlot, range},
	 (g = guess;
          range = minmax[h, low, high];
          hprime = Derivative[1][h];
          thePlot = Plot[h[x], {x, low, high}, DisplayFunction->Identity];
          Show[thePlot, DisplayFunction->$DisplayFunction,
                        PlotRange->{range[[1]], range[[2]]}];
          i = 1;
          While[i <= nframes,
  	        (aPlot = plotTangent[h, hprime, g, low, high];
                 Show[{thePlot, aPlot}, DisplayFunction->$DisplayFunction,
                                        PlotRange->{range[[1]], range[[2]]}];
                 g = doNewton[h, hprime, g]);
                 i = i+1])]

End[]

EndPackage[]
