Post Reply 
Newton's method
12-27-2017, 03:41 AM (This post was last modified: 12-27-2017 04:20 AM by Namir.)
Post: #1
Newton's method
This is a version of Newton's method for the HP Prime where you specify a string representing f(x), along with the initial guess for the root, and the tolerance value. Thus you can solve for different functions without having to hard code these functions in the RPL code. Here is the source code:

Code:
EXPORT NEWTON(sfx, x, toler)
BEGIN
  LOCAL x0, h, f, diff, i, maxiter;
  
  sfx := LOWER(sfx);
  maxiter :=100;
  i := 0;
  diff := 2*toler;
  WHILE ABS(diff) > toler AND i < maxiter DO
    h := 0.01*(1 +ABS(x));
    f := EXPR(sfx);
    x0 := x;
    x := x + h;
    diff := h *f / (EXPR(sfx) - f);
    x := x0 - diff;
  END;
  RETURN x;
END;

Examples of using function NEWTON are:

NEWTON("exp(x)-3*x^2",4,0.0000001)
NEWTON("ln(100)-x",4,0.0000001)

The code convert the string of the expression into lowercase to make sure it uses variable x in lowercase, to match the lowercase parameter x. Also, the code controls the number of iterations not to exceed 99.

You can insert several function declarations with the above code and then pass a string containing the call to a particular function. For example, if we insert the following code before NEWTON:

Code:
EXPORT fx1(x)
BEGIN
  RETURN EXP(x)-3*x^2;
END;

EXPORT fx2(x)
BEGIN
  RETURN ln(100)-x;
END;

Then you can make the following calls:

NEWTON("fx1(x),4,0.0000001)
NEWTON("fx2(x)",4,0.0000001)

Which give the same results as before. This approach allows you to insert a catalogue of functions you frequently work and then invoke the solution for their roots by specifying the function's name instead of its expression. In the case the function requires more than a single statement to calculate the result, then this approach is definitely the one to choose!

If you comment out the statement that converts parameter sfx to lower case, then you can specify the Functions App's F0 through F9. Make sure that you use formats like "F1(x)" with the lowercase x.

Enjoy!

Namir
Find all posts by this user
Quote this message in a reply
01-01-2018, 03:49 PM
Post: #2
RE: Newton's method
Hi Namir, I like the compactness of the solution! I hope you don't mind a few tweaks that perhaps make it better:
  • Added incrementing i so that the program doesn't loop indefinitely
  • Removed conversion of sfx to lowercase to make it compatible with the Function App
  • Changed x to X to make it compatible with functions stored in F0-F9 in the Function App
  • Added a test that if maxiter is reached, it returns "No root found" rather than the last (possibly inaccurate) estimate

Code:

EXPORT NEWTON(sfx, X, toler)
BEGIN
  LOCAL x0, h, f, diff, i, maxiter;
  
  maxiter :=100;
  i := 0;
  diff := 2*toler;
  WHILE ABS(diff) > toler AND i < maxiter DO
    h := 0.01*(1 +ABS(X));
    f := EXPR(sfx);
    x0 := X;
    X := X + h;
    diff := h *f / (EXPR(sfx) - f);
    X := x0 - diff;
    i := i + 1;
  END;
  IF i==maxiter THEN
    RETURN("Root not found");
  ELSE
    RETURN(X);
  END;
END;

With these changes, if you have functions in the Function App that plot nicely like for example F1(X)=17*SIN(1.26*X-90)-5, then you can run NEWTON("F1(X)",1,0.00000001) and find the root 1.85233166719.
Find all posts by this user
Quote this message in a reply
Post Reply 




User(s) browsing this thread: 2 Guest(s)