4
$\begingroup$

I have a function $f(x) = \dfrac{1}{3} (2-e^x + x^2), [a,b]=[0,1]$ I start with an initial value of $.5$ What I am trying to do is write a short program that takes my initial $P_0 = 0.5$, plug it into the function to output $P_1$, put $P_1$ back into the function to output $P_2$, and take that value, put it back into the function to get $P_3$, etc. I want it to stop when $|P_n - P_{n-1}| \leq 0.0001$

I have written this, but I don't get any output from it:

 f[x_] := (1/3)*(2 - Exp[x] + x^2);
 a = 0.5;
 Do[{c = f[a]
      If[Abs[c - a] > 0.001, a = c
         Print[c]]
      If[Abs[c - a] <= 0.001, Print["The solution is " c]]
    }, {i, 1, 10}];

If you are so kind to give me advice, take into account my only programming experience was FORTRAN from 22 years ago, so I am quite lost!

Thank you!

$\endgroup$
5
  • 3
    $\begingroup$ Does this do what you want? With[{eps = 0.0001}, FixedPoint[Function[{x}, (1/3)*(2 - Exp[x] + x^2)], .5, SameTest -> (Abs[#1 - #2] < eps &)] ] !Mathematica graphics $\endgroup$
    – Nasser
    Commented Sep 10, 2016 at 2:31
  • 1
    $\begingroup$ @Nasser: Is there a way to get that snippet to print the individual steps as it iterates? $\endgroup$
    – Moo
    Commented Sep 10, 2016 at 2:54
  • 2
    $\begingroup$ @Moo, yes, but need to replace FixedPoint with FixedPointList, like this With[{eps = 0.0001}, FixedPointList[Function[{x}, (1/3)*(2 - Exp[x] + x^2)], .5, SameTest -> (Abs[#1 - #2] < eps &)]] and this gives {0.5, 0.200426, 0.272749, 0.253607, 0.25855, 0.257266, 0.257599, 0.257512} $\endgroup$
    – Nasser
    Commented Sep 10, 2016 at 3:07
  • $\begingroup$ Excellent - should have figured that out - thanks! $\endgroup$
    – Moo
    Commented Sep 10, 2016 at 3:08
  • $\begingroup$ That definitely does it! Thank you. @Nasser $\endgroup$
    – Jabernet
    Commented Sep 10, 2016 at 4:12

4 Answers 4

4
$\begingroup$

Just for fun:

f[x_] := (1/3)*(2 - Exp[x] + x^2);
it[n_] := 
 Flatten[{#1, {#2[[1]], #2[[1]]}, #2} & @@@ 
   Partition[NestList[{#[[2]], f[#[[2]]]} &, {0.5, f[0.5]}, n], 2, 1],
   1]
fp = {t, t} /. FindRoot[f[t] == t, {t, 0.2}];
vis[n_] := 
 Show[Plot[{f[t], t}, {t, 0, 1}, 
   Epilog -> {Purple, PointSize[0.04], Point[fp], PointSize[0.02], 
     Green, Point[fp], Black, Text[fp, fp, {-1/2, 4}]}], 
  ListPlot[it[n], PlotRange -> All, Joined -> True, PlotStyle -> Red],
   PlotRange -> {{0, 0.5}, {0, .3}}, Frame -> True, 
  PlotLabel -> 
   Row[{"Iteration ", n , ":(", it[n][[-1, -1]], ")\n", 
     Style["error: ", Red], Abs[it[n][[-1, 1]] - fp[[1]]]}]]

enter image description here

$\endgroup$
6
$\begingroup$

The literal way to do what you are requesting is:

Last /@ NestWhileList[{#[[2]], (2 - Exp[#[[1]]] + #[[1]]^2)/3}&, {0.,0.5}, Abs[Subtract @@ #] > 10^-4 &]

It isn't necessarily the fastest or best way, but it is precisely how you are envisioning the recursion. The output is the list of successive iterates $P_0, P_1, \ldots, P_n$. The built-in functions FixedPoint and FixedPointList are more efficient, but NestWhile and NestWhileList are more flexible.


The broad reason why your code fails to run as you expect is because you are attempting to use Mathematica as if it were a procedural programming language, when it is actually a functional programming language. The way Mathematica handles expressions, conditional statements, and assignment is different than languages like Fortran or C.

$\endgroup$
2
  • $\begingroup$ That code yields an error: Subtract::argr: Subtract called with 1 argument; 2 arguments are expected. $\endgroup$
    – corey979
    Commented Sep 10, 2016 at 9:06
  • $\begingroup$ @corey979 There was a missing ampersand after the 10^-4. $\endgroup$
    – heropup
    Commented Sep 10, 2016 at 14:37
5
$\begingroup$

Here's one simple way to approach this iteration:

f[x_] := (1/3)*(2 - Exp[x] + x^2);
NestList[f, 0.5, 20]

{0.5, 0.200426, 0.272749, 0.253607, 0.25855, 0.257266, 0.257599, 0.257512, 0.257535, 0.257529, 0.257531, 0.25753, 0.25753, 0.25753, 0.25753, 0.25753, 0.25753, 0.25753, 0.25753, 0.25753, 0.25753}

You can see that it settles to a constant value after about 11 or 12 iterations.

$\endgroup$
0
5
$\begingroup$

Like Nasser's comment

NestWhileList[1/3 (2 - Exp[#] + #^2) &, 0.5, Abs[#1 - #2] > 0.0001 &, 2] //N

{0.5, 0.200426, 0.272749, 0.253607, 0.25855, 0.257266, 0.257599, 0.257512}
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.