<jupyter_start><jupyter_text>Regula falsiFalse position (also called the linear interpolation method) is another well-known bracketing method. It is very similar to bisection with the exception that it uses a different strategyto come up with its new root estimate.In simple terms, the method is the trial and error technique of using test ("false") values for the variable and then adjusting the test value according to the outcome. This is sometimes also referred to as "guess and check".Using similar triangles, the intersection of the straight linewith the x axis can be estimated The first two iterations of the false position method. The red curve shows the function f and the blue lines are the secants.![](assets/false.png) $$x_r =x_u - \frac{f(x_u)}{f(x_l)-f(x_u)}(x_l-x_u) $$  The Effect of Non-linear FunctionsIf we cannot assume that a function may be interpolated by a linear function, then applying the false-position method can result in worse results than the bisection method. For example, the image above shows a function where the false-position method is significantly slower than the bisection method.![](assets/false_conv.png)The method may be written in pseudocode as follows:<jupyter_code>INPUT: Function f,
       endpoint values a, b
       tolerance TOL,
       maximum iterations NMAX

STEP 1 Set i = 1
                     FA = f(a).

STEP 2 While i ≤ N do Steps 3-6.

        STEP 3 Set p = (a*f(b) − b*f(a))/(f(b) − f(a))
                               FP = f(p)

        STEP 4 If FP = 0 or |f(p)| < TOL  then
                         STOP
                     else OUTPUT(P)
                 
        STEP 5 Set i = i + 1

       STEP 6 If FA×FP>0 then set a = p;
                          FA = FP
                     else set b = p.

STEP 7 OUTPUT("Number max of interetions exceeded")<jupyter_output><empty_output><jupyter_text>A Case Where Bisection Is Preferable to False PositionUsing the two methods to find the root of $f(x) = x^{10} - 1$, between $[0, 1.3]$  Bisection|Interation|$a$|$b$|$x_r$|$|\epsilon_a|$% ||---|---|---|---|---||1|0|1.3|0.65|100||2|0.65|1.3|0.975|33.3||3|0.975|1.3|1.1375|14.3||4|0.975|1.1375|1.05625|7.7||5|0.975|1.05625|1.015626|4|  False Position|Interation|$a$|$b$|$x_r$|$|\epsilon_a|$% ||---|---|---|---|---||1|0|1.3|0.0943|----||2|0.0943|1.3|0.918176|48.1||3|0.18176|1.3|0.26287|30.9||4|0.26287|1.3|0.33811|22.3||5|0.33811|1.3|0.40788|17.1| The foregoing example illustrates that blanket generalizations regarding root location methods are usually not possible. Although a method such as false position isoften superior to bisection, there are invariably cases that violate this general conclusion.<jupyter_code>import numpy as np
import scipy as sc
import matplotlib.pyplot as plt
def false_position(f, a, b, tol, N):
    """
    Find root of a function within an interval using false position.
    
    Basic false position routine to find a zero of the function `f` between the
    arguments `a` and `b`. `f(a)` and `f(b)` cannot have the same signs.
    
    Parameters
    ----------
    Input:
        f = name of function
        a, b = lower and upper guesses
        tol = desired relative error (epsilon)
        N = maximum allowable interations
        
        
    Returns
    -------
    root = real root
    fx = value at root
    interation = Number of interations
        
    """
    if f(a)*f(b) >= 0: 
        print("You have not assumed right a and b") 
        return -1
      
    root = a #
    interation = 0
    for i in range(N): 
        interation += 1
        
        root = (a*f(b) - b*f(a))/ (f(b) - f(a)) 
          
        if ((f(root) == 0) or (np.abs(f(root)) < tol)):  
            fx = f(root)
            return root, fx, interation   
        
        elif f(root)*f(a)< 0: 
            b = root
        else: 
            a = root
        
    raise NameError("Number max of interetions exceeded")
f = lambda x: np.sin(10*x) + np.cos(3*x)
a = 3
b = 4
root,fx, interation = false_position(f, a, b, tol=1e-10, N=50)

print("The root is: "+ str(root))
print("The value of f is: "+ str(fx))
print("The number of interations is: "+ str(interation))<jupyter_output>The root is: 3.7457450869720232
The value of f is: -5.333011809938171e-12
The number of interations is: 8
{'fraction_non_alphanumeric': 0.12064531213467383, 'fraction_numerical': 0.053074584989478604, 'mean_word_length': 2.544324772162386, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 10, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '2', 'dir': 'jupyter-structured-clean-dedup', 'id': '636662', 'license': 'MIT', 'n_tokens_mistral': 1527, 'n_tokens_neox': 1372, 'n_words': 502, 'path': 'src/02_roots_optimization/01_bracketing_methods/.ipynb_checkpoints/false_position-checkpoint.ipynb', 'repo_name': 'joaomh/numerical-methods', 'size': '4277'}