2 years ago

#26336

test-img

123iamking

Generate initial guess for any function?

Here is the Newton's method code from Wikipedia page:

x0            = 1         # The initial guess
f(x)          = x^2 - 2   # The function whose root we are trying to find
fprime(x)     = 2x        # The derivative of the function
tolerance     = 1e-7      # 7 digit accuracy is desired
epsilon       = 1e-14     # Do not divide by a number smaller than this
maxIterations = 20        # Do not allow the iterations to continue indefinitely
solutionFound = false     # Have not converged to a solution yet

for i = 1:maxIterations
  y      = f(x0)
  yprime = fprime(x0)

  if abs(yprime) < epsilon            # Stop if the denominator is too small
    break
  end

  global x1 = x0 - y/yprime           # Do Newton's computation

  if abs(x1 - x0) <= tolerance        # Stop when the result is within the desired tolerance
    global solutionFound = true
    break
  end

  global x0 = x1                      # Update x0 to start the process again
end

if solutionFound
  println("Solution: ", x1)           # x1 is a solution within tolerance and maximum number of iterations
else
  println("Did not converge")         # Newton's method did not converge
end

When I implement this I see that there are cases I need to apply new initial guess:

  • When functions (i.e: f, fPrime) give Infinity or NaN result (e.g in C#, this happens when result = 1/x when x=0, result = √x when x=-1,...)
  • When abs(yprime) < epsilon
  • When x0 is too large for y/yprime (e.g x0 = 1e99 but y/yprime = 1e25, this will make x1 = x0 while it's mathematically wrong, this will make the algorithm leads to nowhere).

My app allows user to input the math function and the initial guess, (e.g: Initial guess for x can be 1e308, function can be 9=√(-81+x), 45=InverseSin(x), 3=√(x-1e99),... ).

So when the initial guess is bad, my app will automatically apply the new initial guess with hope that it can give the result.

My current solution: the initial guess is the array of values:

double[] arrInitialGuess = 
{
[User's initial guess], 0, 1, -1, 2, -2,... (you know, Factorial n!)..., 7.257416E+306, -7.257416E+306,
}

I have the following questions:

  1. Is the big number (e.g 7.257416E+306) even needed? because I see that in x1 = x0 - y/yprime, if the initial guess x0 is too big compare to y/yprime, it programmatically leads to nowhere. If the big number is pointless, what is the cap for initial guess (e.g 1e17?)

2. What is better for the array of initial guess: the factorial n! {+-1, +-2, +-6,...}, or 2^x {+-2^0, +-2^1, +-2^2,...}, or 10^x {+-1e0, +-1e1, +-1e2,...},...

  1. If my predefined-array-initial-guess method is not good, is there any better way to get new initial guess for Newton's method? (e.g an algorithm to get next initial-guess?)

Update:

Change of thought, the pre-defined array of initial guess doesn't work. For example, I have the formula: 8=3/x => y=8-3/x which gives this graph Graph y=8-3/x In this case, I can find the solution when initial guess is in the range [ 0.1 ; 0.7 ], so if I have the pre-defined initial guess arrray = {0, 1, 2,..., Inf}, it won't do me any good but wasting my precious resource.

So my new thought now is: steering the next initial guess base on the graph. The idea is: applying the last guess and compare with current guess to see that the value of y is heading toward 0 or not, so that I can determine to increase or decrease the next initial guess to steer the y toward 0. But I still consider the pre-defined initial guess idea in case the guesses all give Infinity value.

Update 2:

New thought: pick the new initial guess in the range [ x0; x1 ] where

  1. there is no error between x0 and x1 (e.g there is no error divide by zero when apply a value in the range [ x0; x1 ]). So I can form the line AB: A(x0, y0) and B(x1, y1).

  2. y0 and y1 have different sign: (y0 > 0 && y1 < 0) || (y0 < 0 && y1 > 0). So that the line AB can cut the x axis (which cause a big possibility there is an y = 0 somewhere between y0 and y1, if the graph isn't too weird).

Try to narrow the range [ x0; x1 ] as small as possible, then run a few initial guesses between the range.

algorithm

math

newtons-method

0 Answers

Your Answer

Accepted video resources