練習:Sqrt函數可視化實現
本次練習主要是熟練numpy和matplotlib的使用,通過手寫Sqrt的實現,通過可視化對比手寫函數與系統自帶函數之間區別。
主要實現思路是:牛頓法
下面簡單介紹一下牛頓法:(參考博客,參考知乎) 首先,有函數f(x) = x2,假設num是f(x)的近似值,那么num最接近f(x),就有f(x)-num=0,也就是x2 - num = 0.
那么如果畫圖,就是要求g(x)=x2 - num 與g(x)=0 的最近點。
極限公式:

因此有:

從幾何圖形上看,因為導數是切線,通過不斷迭代,導數與x軸的交點會不斷逼近x0。

從上圖我們可以看出,第一次A點,畫出A的切線,在X軸上有交點,這個交點投影到曲線上,找到點B,同理,B點又做切線,找到一個交點,交點又投影到曲線得到點C,逐漸接近X0。
由前面的極限公式得出:
$$f'(x_n) = \frac{dy}{dx} = \frac{f(x_n)}{x_n - x_{n+1}}$$
推導得出:
$$x_{n+1} = x_n -\frac{f(x_n)}{f'(x_n)}$$
ok,到這里我們舉一個實例
假設m=2,那么就有:
最終得出以下圖例:手寫的sqrt函數與系統自帶的基本沒有區別
、
# -*- coding:utf-8 -*-
# /usr/bin/python
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
import math
def func(a):
if a < 1e-6: #小于0.000001,直接返回0
return 0
last = a
c = a / 2 #該值一定程度上影響迭代次數
while math.fabs(c - last) > 1e-6:#精度控制
last = c
c = (c + a/c) / 2
return c
if __name__ == '__main__':
mpl.rcParams['font.sans-serif'] = ['SimHei']
mpl.rcParams['axes.unicode_minus'] = False #保證win系統圖片上的中文顯示正常
x = np.linspace(0, 30, num=50) #0-30均分50份
func_ = np.frompyfunc(func, 1, 1) #轉換為ufunc函數方便使用
y_h = func_(x)
y_s = np.sqrt(x)#調用系統自帶函數求值
plt.figure(figsize=(10, 6), facecolor='w')#設置圖大小和背景色
plt.plot(x,y_h, 'ro-',label='手寫', lw=2, markersize=6)#(畫出x與y_h的曲線,用紅色小圓圈標記(x,y)在圖上的位置,
#label下面legend函數要調用的,相當于注明這條曲線的意義,lw線寬2,小圓點6)
plt.plot(x,y_s, 'b-',label='系統自帶', lw=2, markersize=6)
plt.grid(b=True, ls=':')#顯示網格
plt.legend(loc='lower right')#選取兩條曲線的注明所在方位
plt.xlabel('X', fontsize=16)#坐標軸上的內容及大小
plt.ylabel('Y', fontsize=16)
plt.title('牛頓法計算平方根', fontsize=18)
plt.show()
關于分母的取值影響迭代次數的研究
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
import math
def func(b):
if b < 1e-6:
return 0
a = 1000
last = a
c = a / b
count = 0
while math.fabs(c - last) > 1e-6:
last = c
c = (c + a/c) / 2
count = count + 1
return count
if __name__ == '__main__':
x = np.linspace(2, 500, num=100)
func_ = np.frompyfunc(func, 1, 1)
y = func_(x)
print(x,y)
>>>[9 7 6 5 5 4 3 4 5 5 5 5 6 6 6 6 6 6 6 6 6 6 6 7 7 7 7 7 7 7 7 7 7 7 7 7 7
7 7 7 7 7 7 7 7 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8
8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9]