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
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)
- 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)