Home python in Python Finding the roots by the method of dichotomy ^ How...

in Python Finding the roots by the method of dichotomy ^ How to get rid of infinite branching?

Author

Date

Category

I am writing a root search function in an equation with one variable by the method of dichotomy. And that’s what kind of thing: the essence of the method – we divide the specified segment of the axis x in half, look something (or immediately see the root, or continue), then once again in half, also. As long as it does not reach the boundaries of the error.
Dividing on any iteration in half, for which we pay attention: 1) on the error; 2) to other points:

  • If the function in the middle of the segment is zero or less than the specified error, the root is the middle of the segment;
  • Otherwise, if the product of the function in the middle of the segment F (MID) and at its beginning F (a) is less than zero, then the segment acquires parsenned boundaries from A to MID (and MID becomes the right border of the segment (that is, B = MID)). We divide further until we obtain zero at the MID point (F (Mid) = 0) or the next value will not be less than the error. Moreover, the MID value may become the boundary A, the boundary B (depending on the sign of the piece of functions f (MID) * F (a) & lt; 0 or f (Mid) * F (a) & gt; 0).
  • If the product of the function in the middle of the segment F (MID) and at its beginning f (a) is greater than zero, then the segment acquires the folded boundaries from MID to b. We continue to divide. As in the previous paragraph, the MID value may become the boundary A, then the border B (until the root reach).

Trying to implement it in the code. What is wrong?

import numpy as np
# Print (np.log (0))
DEF F (X):
  RETURN 1.2-NP.LOG (X) -4 * NP.COS (2 * x)
# Function of the Dichotomy method:
Def Dyhotomy (A, B, ε):
  Assert A! = 0, 'A is 0'
  Assert B! = 0, 'B is 0'
  args = np.arange (a, b, 0.001) # 0.001 - step; Set the grid of values ​​on the segment
  ROOT = 0.
  # To improve the method of half division (bisection), which takes into account only the change
  # Function sign,
  It is compatible with the chord method, taking into account the deviation (absolute value). It accelerates
  # Approach to the root (after all, the less (by absolute value) the value of the function, the closer we are to the root)
  korni = []
  For root in len (Args):
    While ABS (F (B) -f (a)) & gt; ε: # While the cut is more than a given error, carry out the subordination operations:
      MID = (A + B) / 2 # Get the middle of the segment
      if f (MID) == 0 or F (MID) & lt; ε: # If the function in the middle of the segment is zero or less error:
        root = MID # root equal to the middle value
        korni.append (root)
        Break
      ELIF (F (MID) * F (a)) & lt; 0: # other than the product of the function in the middle of the segment on the function in t. A & LT; 0
        B = Mid # Mid Segment becomes the right border b
        Mid = (A + B) / 2
        if f (MID) == 0 or F (MID) & lt; ε:
          ROOT = MID.
          korni.append (root)
          Break
        ELIF (F (MID) * F (a)) & lt; 0:
          B = Mid.
          # ... Here you can branch and branch again, but how to stop?
      ELSE:
        a = Mid # in another case - point A
        IF F (a) == 0 or F (a) & lt; ε:
          root = A.
          korni.append (root)
          Break
        # Here will also go infinite branching: how to get up on the stop?
  #ROot = (A + B) / 2
  Print (F'Korin Functions According to the method of dichotomy is at point x = {root} ')
dyhotomy (0.0001,200, 0.0009)

Answer 1

  1. Assert it is better to do in the function itself, and not the root search method.
def (x):
  Assert X! = 0, 'argument can not be zero'
  RETURN 1.2 - NP.LOG (X) - 4 * NP.COS (2 * X)
  1. so you can:
def dyhotomy (a, b, eps):
  root = none
  While ABS (F (B) -f (a)) & gt; EPS:
    Mid = (A + B) / 2
    IF F (MID) == 0 or ABS (F (MID)) & lt; EPS:
      ROOT = MID. 
Break
    elif f (a) * f (mid) & lt; 0:
      b = mid
    ELSE:
      a = mid
  if root is None:
    print ( 'root not found')
  ELSE:
    print (f'Koren dichotomy by the method is in the point x = {root} ')

Or so (not much more):

def dyhotomy (a, b, eps):
  while abs (f (b) -f (a)) & gt; eps:
    mid = (a + b) / 2
    if f (mid) == 0 or abs (f (mid)) & lt; eps:
      print (f'Koren dichotomy by the method is in the point x = {mid} ')
      Break
    elif f (a) * f (mid) & lt; 0:
      b = mid
    ELSE:
      a = mid
  ELSE:
    print ( 'root not found')

Call:
dyhotomy (0.0001, 200, 0.0009)


For the overall development here recursive function:

def rec_dyhotomy (a, b, eps):
  if abs (f (b) - f (a)) & lt; eps:
    print ( 'root not found')
    Return.
  mid = (a + b) / 2
  if f (mid) == 0 or abs (f (mid)) & lt; eps:
    print (f'Koren dichotomy by the method is in the point x = {mid} ')
  elif f (a) * f (mid) & lt; 0:
    rec_dyhotomy (a, mid, eps)
  ELSE:
    rec_dyhotomy (mid, b, eps)

Programmers, Start Your Engines!

Why spend time searching for the correct question and then entering your answer when you can find it in a second? That's what CompuTicket is all about! Here you'll find thousands of questions and answers from hundreds of computer languages.

Recent questions