<jupyter_start><jupyter_text>Numerical computation using Numpy The Newton Raphson root finding methodFind the square root of 7 by numerically solving the equation: $x^2 - 7 = 0$Let's assume that there is a function, $f(x) = x^2 - 7$Now, we need to find the roots of this function $f(x)$, that is the values of $x : f(x) = 0$, which will give us the value $x = \sqrt{7}$Let's begin with an initial guess, $x_1$ as the root of $f(x)$The slope of the tangent to $f(x)$ at $x_1$ is: $$ f'(x_1) =  \frac{f(x_2) - f(x_1)}{(x_2 - x_1)}$$To find the intercept of this slope on the X axis, we input $f(x_2) = 0$ in the above equation to obtain:$$ x_2 = x_1 - \frac{f(x_1)}{f'(x_1)}$$We repeat this operation iteratively, and the method converges towards the root of the function. An illustration from the Wikipedia page on the [Newton's method](https://en.wikipedia.org/wiki/Newton's_method).<jupyter_code>import numpy as np
import matplotlib.pyplot as plt<jupyter_output><empty_output><jupyter_text>We begin by defining the number line<jupyter_code>N = 20 # number of divisions, increase this to increase the resolution of your number line
x = np.linspace(-5, 5, N)
f = x**2 - 7
plt.plot(x, f, marker="o")
plt.axhline(0, color="k")

plt.xticks(np.arange(-5,5.1,1))
plt.grid()<jupyter_output><empty_output><jupyter_text>Visually, we see that the function intersects the X axis close to $x = 2.6$<jupyter_code>2.6475**2<jupyter_output><empty_output><jupyter_text>We got quite close the the square root of 7 there Let's find out the index of the array f where $|f(x)|$ has the least value<jupyter_code>i_root = np.argmin(np.abs(f))
print(f[i_root])<jupyter_output>1.37950138504155<jupyter_text>We are not close to Zero unfortunately, 1.379 is the lowest value.<jupyter_code>x[i_root]
x[i_root]**2<jupyter_output><empty_output><jupyter_text>We got close to the answer, try the above method by increasing the resolution along the number line and see if the solution get's any better! A traditional way of computing the root would involve loops (which is usually a bad idea in Python). But in this case, we are lucky that there aren't too many steps to reach the answer and we are not looping over large arrays.<jupyter_code>x_n = -4
count = 0
while count < 5:
    f_n = x_n**2 - 7
    f_n_dx = 2*x_n # f'(x) = 2x
    
    x_np1 = x_n - f_n/f_n_dx
    
    print(count, x_n, x_np1)
    x_n = x_np1
    count += 1
print(x_np1)<jupyter_output>0 -4 -2.875
1 -2.875 -2.654891304347826
2 -2.654891304347826 -2.6457670441902894
3 -2.6457670441902894 -2.6457513111113693
4 -2.6457513111113693 -2.6457513110645907
-2.6457513110645907<jupyter_text>But fear not, there are optimization functions available from scipy! See more advanced [optimization functions here](https://docs.scipy.org/doc/scipy/reference/optimize.html). These functions are more efficient than using loops in pure Python.<jupyter_code>from scipy import optimize
def myfunc(x):
    return x**2 - 7
root = optimize.newton(myfunc, 1.5)
root
root = optimize.newton(myfunc, -1.5)
root<jupyter_output><empty_output><jupyter_text>Optimization: Iterative solvers Exercise 06: Iteratively solve the water wave dispersion relationship$$ \omega^2 = gk \tanh(kh) $$Where $\omega = \frac{2 \pi}{T}$ is the wave frequency (in radians per second) and $T = 10$s is the time period (s), $g = 9.81 \textrm{ms}^{-2}$ is the acceleration due to gravity, $k = \frac{2 \pi}{L}$ is the wave number with $L$ being the wavelength (m), $h = 10$m is the height of the water column.Write a solver using loops where:$$ k_{n+1} = \frac{\omega^2}{g \tanh(k_n h)}$$Then try solving the same with an optimization function in scipy, optimizing values of k for the function:$$ \omega^2 - gk \tanh (kh)$$<jupyter_code># %load ./solutions/sol_dispersion.py
# %load ./solutions/sol_disp_scipy.py<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.11684924360980699, 'fraction_numerical': 0.06338028169014084, 'mean_word_length': 4.828267477203648, 'pattern_counts': {'":': 0, '<': 32, '<?xml version=': 0, '>': 31, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '8', 'dir': 'jupyter-structured-clean-dedup', 'id': '72366', 'license': 'MIT', 'n_tokens_mistral': 1509, 'n_tokens_neox': 1356, 'n_words': 470, 'path': '03_Numpy_Computation.ipynb', 'repo_name': 'adityarn/MAV110_PythonModule', 'size': '3834'}