Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Root Finding
Suppose that you want to find the solution(s) of a transcendental equation. For example, you might want to know what values of that solve the equation The graphical approach is to plot both sides of the equation and see where they cross as shown below.
From the graph above, it is possible to find approximate solutions. There is a solution at . You can also see that there are solutions between and for integer values of . Another way to find the solution graphically is to plot the difference of the two sides of the original equation. If we define the function then the original equation has a solution where . These are known as the roots of . It is slightly easier to find the solutions by looking at a graph of this funciton as shown below.
There are several functions in the scipy.optimize library for finding the roots of a function. For all of the methods, you must define the function whose roots you want to find. In general, you must know the approximate location of the root.
First, you can use the optimize.brentq function if you know values that bracket the root. As mentioned above, the roots of the example function are between and for integer values of .
Notice that for the range 0 to , the function found the root , so it stopped searching and missed the root near . The other root can be found by changing the lower limit of the range slightly as shown below. This is an example of why it is important to check that the results match with a graph of the function.
The function must have opposite signs at the two limits given or the the root-finding function will fail as shown below.
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
Cell In[7], line 1
----> 1 print(opt.brentq(f,4,8))
, in brentq(f, a, b, args, xtol, rtol, maxiter, full_output, disp)
800 raise ValueError(f"rtol too small ({rtol:g} < {_rtol:g})")
801 f = _wrap_nan_raise(f)
--> 802 r = _zeros._brentq(f, a, b, xtol, rtol, maxiter, args, full_output, disp)
803 return results_c(full_output, r)
ValueError: f(a) and f(b) must have different signs
Second, you can use the optimize.fsolve function if you know approximate values of the roots. In the example below, initial guesses of for integers from 0 to 9 are used. This guesses a point in the middle of each range of to
Note that this doesn't find the root .