任意波形的生成 (geneartion of arbitrary waveform) 在商業,軍事等領域都有著重要的應用,諸如空間光通訊 (free-space optics communication), 高速訊號處理 (high-speed signal processing),雷達 (radar) 等。在任意波形生成後,如何評估生成的任意波形成為另外一個重要的話題。
scipy.optimize.leastsq
假設有一組實驗資料,已知他們之間的函式關係:y=f(x),通過這些資訊,需要確定函式中的一些引數項。例如,f 是一個線型函式 f(x)=k*x+b,那麼引數 k 和 b 就是需要確定的值。如果這些引數用 p 表示的話,那麼就需要找到一組 p 值使得如下公式中的 S 函式最小:
這種演算法被稱之為最小二乘擬合 (least-square fitting)。scipy 中的子函式庫 optimize 已經提供實現最小二乘擬合演算法的函式 leastsq。下面是 leastsq 函式匯入的方式:
1 |
from scipy.optimize import leastsq |
波形資料匯入
在 Python科學計算——Numpy.genfromtxt 一文中,使用 numpy.genfromtxt 對數字示波器採集的三角波資料匯入進行了介紹,今天,就以 4GHz三角波 波形的擬合為案例介紹任意波形的擬合方法。
1 2 3 4 5 6 7 8 9 10 11 |
Type: raw Points: 16200 Count: 1 ... Y Units: Volt XY Data: 2.4000000E-008, 1.4349E-002 2.4000123E-008, 1.6005E-002 2.4000247E-008, 1.5455E-002 2.4000370E-008, 1.5702E-002 ... |
1 |
data = np.genfromtxt('waveform.txt',delimiter=',',skip_header=18) |
模型的選擇
在 Python科學計算——如何構建模型? 一文中,討論瞭如何構建三角波模型。在標準三角波波形的基礎上新增了橫向,縱向的平移和伸縮特徵引數,最後新增了噪聲引數模擬了三角波幅度參差不齊的隨機性特徵。但在波形擬合時,並不是所有的特徵引數都要納入考量,例如,噪聲引數應是波形生成系統的固有特徵,正因為它的存在使得產生的波形存在瑕疵,因此,在進行波形擬合併評估時,不應將噪聲引數納入考量,最終模型如下:
1 2 3 4 5 |
def triangle_wave(x,p): a,b,c,T = p y = np.where(np.mod(x-b,T)<T/2, -4/T*(np.mod(x-b,T))+1+c/a, 0) y = np.where(np.mod(x-b,T)>=T/2, 4/T*(np.mod(x-b,T))-3+c/a, y) return a*y |
波形擬合
在呼叫 scipy.optimize.leastsq 函式時,需要構建誤差函式:
1 2 |
def residuals(p,y,x): return y - triangle_wave(x,p) |
有時候,為了使圖片有更好的效果,需要對資料進行一些處理:
1 2 3 |
x = data[:,0] x_fig = map(lambda x : (x-data[0,0])*1e12, data[:,0]) # 畫圖資料 y = data[:,1] |
leastsq 呼叫方式如下:
1 2 3 |
p0 = [1.056,215e-12,0.0108,2.51337e-10] # 初始引數 plsq = leastsq(residuals,p0,args=(y,x)) y2 = triangle_wave(x,plsq[0]) |
合理的設定 p0 可以減少程式執行時間,因此,可以在執行一次程式後,用擬合後的相應資料對 p0 進行修正。
資料視覺化
在對波形進行擬合後,呼叫 pylab 對擬合前後的資料進行視覺化:
1 2 3 4 5 6 7 |
pl.plot(x_fig, y, 'b', label='Experiment data', linewidth=3) pl.plot(x_fig, y2, 'r--',label='Fitting data', linewidth=2) pl.ylim(-1.5,2) pl.xlabel('Time(ps)') pl.ylabel('Amplitude[a.u.]') pl.legend() pl.show() |
擬合效果評估
均方根誤差 (root mean square error) 是一個很好的評判標準,它是觀測值與真值偏差的平方和觀測次數n比值的平方根,在實際測量中,觀測次數n總是有限的,真值只能用最可信賴(最佳)值來代替.方根誤差對一組測量中的特大或特小誤差反映非常敏感,所以,均方根誤差能夠很好地反映出測量的精密度。
RMSE 用程式實現如下:
1 2 3 |
variances = map(lambda x,y : (x-y)**2, y, y2) variance = np.sum(variances) RMSE = np.sqrt(variance/len(x)) |
擬合效果,模型引數輸出:
1 2 |
print RMSE,plsq[0] >>> 1.63442970685e-05 [ 1.05325324e+00 2.15580302e-10 1.07998635e-02 2.51337252e-10] |
其他模型
leastsq 函式適用於任何波形的擬合,下面就來介紹一些常用的其他波形:
方波
1 2 3 4 5 |
def square_wave(x,p): a, b, c, T = p y = np.where(np.mod(x-b,T)<T/2, 1+c/a, 0) y = np.where(np.mod(x-b,T)>T/2, -1+c/a, y) return a*y |
高斯波形
1 2 3 |
def gaussian_wave(x,p): a, b, c, d= p return a*np.exp(-(x-b)**2/(2*c**2))+d |