import numpy as np
import plotly.graph_objects as go
from scipy.optimize import root
try:
import executable_engineering as exe
except ImportError:
%pip install -q executable_engineering
import executable_engineering as exe
from executable_engineering import weierstrass, plot_and_find_roots, complex_plot_with_shadow
Roots of some nonlinear functions¶
Let’s build some intuition by exploring some type of roots in 1D functions using the graphical method: Plot the function and examine where it crosses the x-axis.
NB: Note the structure of the code below - Since we don’t know a priori where the roots will be, we have to take a series of initial guesses and cross our finger.... and even then we may fail to find them all!
Example 1: Real roots - ¶
plot_and_find_roots(lambda x: x**2-4)Example 2: No roots - ¶
(Noting that the vertical line is a plotting artifact).
plot_and_find_roots(lambda x: 1/x)Example 3: Infinite roots ¶
Only the roots closest to the initial guesses are found!
plot_and_find_roots(lambda x: np.sin(x**2))Complex roots - ¶
Even the graphical method is not completely reliable due to the existence of complex roots.
But this is wrong! The quadratic has 2 roots but we need to use a different method.
def fun(x):
return x**2 + 1
# Wrong!
plot_and_find_roots(fun)
# Find roots using krylov
root(lambda x: x**2+1, x0 = [1+1j, 1-1j], method = "krylov")Visualizing complex roots¶
DON’T WORRY - We won’t be dealing with complex numbers in general in this course :-)
# Find roots and plot the complex surface with a 2D shadow
complex_plot_with_shadow(lambda z: z**2 + 1, roots=[1j, -1j])Pathological / well-behaved functions¶
Some functions can be very tricky indeed, such as the Weierstrass Function,
which looks like:
This is a classic example of a continuous but nowhere differentiable function! It is a fractal, and yet roots do exist and may be on interest. It is a classic example of a pathological function.
Different applications will have different criteria for pathological vs well behaved functions, and no general definition exists although there is seldom disagreement among non-mathematicians about which is which.
Generally, well-behaved functions don’t have sharp corners, singularities, discontinuities, etc.
import plotly.graph_objects as go
import numpy as np
x_vals = np.linspace(-2, 2, 2000)
y_vals = weierstrass(x_vals, a=0.5, b=13)
fig = go.Figure()
fig.add_trace(go.Scatter(x=x_vals, y=y_vals, mode='lines', name='Weierstrass'))
fig.update_layout(title='Weierstrass Function (a=0.5, b=13)', xaxis_title='x', yaxis_title='f(x)')
fig.show()