3
$\begingroup$

I wonder if you can help me with my program - it involves using Newton's Method but my main issue is getting a defined function to return a given value.

Essentially, I want to get my function findRoot to return the value of the root or Null if it doesn't find one. Here is the code for this function:

findRoot[x0_] := Module[{Root},
(*Initialise dummy variable and counter index thing *)
dumx = x0;
l = 0;

While[l < 100,
Root = Iter[dumx];
If[Norm[dumx - Root] < TOL, Break[], dumx = Root]

 (*If true, break the while loop and return root, if false let dumx=Root*)
 ; l++]


If[l == 100, Null, Root]
];

Iter[] is just another function that performs iterations of Newton's method, I made it separate to allow ease of debugging!

Essentially, if I plug

{-0.3,-0.3,-0.3,-0.3}

into this algorithm, (With certain global variables set in ways where I already know what roots should come out of this function) I get

{-0.2Null,-0.2Null,-0.2Null,-0.2Null}

and I have no idea where the null is coming from. The result should read {-0.2,-0.2,-0.2,-0.2}. I suspect the semi-colon on line 7 is responsible for this Null, but removing it causes greater issues.

$\endgroup$
  • $\begingroup$ You should try to provide a minimal example where everything is defined. As it stands now, your question is not easy to interpret. $\endgroup$ – dionys Sep 4 '15 at 13:36
  • 1
    $\begingroup$ Maybe you are missing a ; at the penultimate "if" condition i.e. after l++] $\endgroup$ – demm Sep 4 '15 at 13:40
  • $\begingroup$ @dionys Sorry, thank you for the advice. I should have lurked more before posting but I am in a slight rush to move on from this glitch. $\endgroup$ – Mathew Vaughan Sep 4 '15 at 14:05
  • $\begingroup$ A more idiomatic way of doing what you're doing is FixedPoint[{#[[1]] + 1, iter[#[[2]]]} &, {0, x0}, 100, SameTest -> (Abs[#1[[2]] - #2[[2]]] < tol &)] /. {{100,x_} :> Null, {a_, b_} :> b }, by the way. $\endgroup$ – Patrick Stevens Sep 4 '15 at 14:10
6
$\begingroup$

Here's an attempt at a clean example using a stand-in definition for Iter. Note: it's generally better to avoid creating symbols that start with a capital letter or shadow built-in functions, so I've changed a couple variable names in obvious ways:

findRoot[x0_] := Module[{myRoot, iter, tol, result},
  iter[x_] = RandomReal[];
  dumx = x0;
  tol = 1;
  l = 0;
  While[l < 100,
        myRoot = iter[dumx];
        If[Norm[dumx - myRoot] < tol, Break[], dumx = myRoot]; l++];
        result = If[l == 100, Null, myRoot]]

findRoot[10]
(*0.371588*)

Newton's method is the default approach implemented in the built-in function FindRoot, so the following is analogous to your code above, operating on the function Sin[x - 10] - x + 10:

Module[{f},
  f[x_] = Sin[x - 10] - x + 10;
  FindRoot[f[x], {x, 0}, Method -> "Newton", AccuracyGoal -> 1, PrecisionGoal -> 1]]
$\endgroup$
  • $\begingroup$ So you are allowed as many semi-colons as you wish in the body of the while loop? It wasn't entirely clear from when I was reading the online documentation. $\endgroup$ – Mathew Vaughan Sep 4 '15 at 14:06
  • $\begingroup$ @MathewVaughan It's a little more complicated than that, you should have a look at the answer here: Understand that semicolon (;) is not a delimiter. $\endgroup$ – dionys Sep 4 '15 at 14:08
  • $\begingroup$ This helped me, turns out it was a syntax issue whilst using 'While'. Also, thanks for your advice! $\endgroup$ – Mathew Vaughan Sep 4 '15 at 16:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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