# Mathematica code for Newton's Method doesn't work [duplicate]

I am trying to program Newton's Method in Mathematica to compute the roots of $$f(x)=x^3-6x^2+11x-6$$ using the Do command but my code gives a General::ivar error and doesn't work and I can't figure out what is wrong with it:

f[x_] := x^3 - 6*x^2 + 11*x - 6
g[x_] := D[f[x], x]
a[0] = 0;
Do[a[n + 1] = a[n] - N[f[a[n]]/g[a[n]]], {n, 0, 100}]

Table[a[n], {n, 0, 100}]


Can you explain what's wrong with it?

• g[x_] = D[f[x], x] works, but the reasoning is a bit complicated for a comment. See Set vs SetDelayed in the documentation. This also might help with that: mathematica.stackexchange.com/questions/18393/… Commented Jan 4, 2022 at 19:47

This would be more idiomatic:

Clear[f, g, newtonIteration]

f[x_] := x^3 - 6*x^2 + 11*x - 6
g[x_] = D[f[x], x];

newtonIteration[previousEstimate_] :=
previousEstimate - f[previousEstimate]/g[previousEstimate]

FixedPointList[
newtonIteration,
0.  (* starting value *),
100 (* max number of iterations *)
]

(* Out: {0., 0.545455, 0.848953, 0.974674, 0.999092, 0.999999, 1., 1., 1.} *)


Even shorter, with pure functions:

FixedPointList[# - f[#]/g[#] &, 0., 100]


The third argument of FixedPointList (the 100) is there to as a fail-safe, to stop runaway iterations that do not converge after 100 steps.

You want to use Set (=) instead of SetDelayed (:=) here to define the derivative g, so it is calculated symbolically and stored in g, and then numerical values of x are substituted as needed. On the other hand, using SetDelayed (:=) forces the re-calculation of the derivative at each step. In particular, this means that x will have already been assigned a numerical value at that point. and it will no longer be a valid variable for differentiation. This was the origin of the error in your original code.

Notice the change in definition of f[x], g[x]

Clear[f, g, a]
f[x_] = x^3 - 6*x^2 + 11*x - 6
g[x_] = D[f[x], x]
a[0] = 0;
Do[a[n + 1] = a[n] - N[f[a[n]]/g[a[n]]], {n, 0, 7}]
Table[a[n], {n, 0, 7}]


{0, 0.545455, 0.848953, 0.974674, 0.999092, 0.999999, 1., 1.}

Save your work before you run such loops.

Clear[f, g, a]
f[x_] = x^3 - 6*x^2 + 11*x - 6
g[x_] = D[f[x], x]
a[0] = 0;
Do[a[n + 1] = a[n] - N[f[a[n]]/g[a[n]]];
Echo[a[n] , "a[" <> ToString@n <> "] = "];
Pause[1];
, {n, 0, 10}]


Now you can try with the SetDelayed :=  and see the difference.

Keep the Pause in there or it would be hard to abort evaluation in cases where it misbehaves.