- Let's import NumPy, SciPy, scipy.optimize, and matplotlib.

In [ ]:

```
import numpy as np
import scipy as sp
import scipy.optimize as opt
import matplotlib.pyplot as plt
%matplotlib inline
```

In [ ]:

```
f = lambda x: np.cos(x) - x
```

- Let's plot this function on the interval $[-5, 5]$.

In [ ]:

```
x = np.linspace(-5, 5, 1000)
y = f(x)
plt.figure(figsize=(5,3));
plt.plot(x, y);
plt.axhline(0, color='k');
plt.xlim(-5,5);
```

- We see that this function has a unique root on this interval (this is because the function's sign changes on this interval). The scipy.optimize module contains a few root-finding functions that are adapted here. For example, the
`bisect`

function implements the**bisection method**(also called the**dichotomy method**). It takes as input the function and the interval to find the root in.

In [ ]:

```
opt.bisect(f, -5, 5)
```

Let's visualize the root on the plot.

In [ ]:

```
plt.figure(figsize=(5,3));
plt.plot(x, y);
plt.axhline(0, color='k');
plt.scatter([_], [0], c='r', s=100);
plt.xlim(-5,5);
```

- A faster and more powerful method is
`brentq`

(Brent's method). This algorithm also requires that $f$ is continuous and that $f(a)$ and $f(b)$ have different signs.

In [ ]:

```
opt.brentq(f, -5, 5)
```

`brentq`

method is faster than `bisect`

. If the conditions are satisfied, it is a good idea to try Brent's method first.

In [ ]:

```
%timeit opt.bisect(f, -5, 5)
%timeit opt.brentq(f, -5, 5)
```

You'll find all the explanations, figures, references, and much more in the book (to be released later this summer).

IPython Cookbook, by Cyrille Rossant, Packt Publishing, 2014 (500 pages).