4.6 曲線擬合
在上一節,已經介紹了數據插值,它要求原始數據是精確的,或具有較小的誤差。事實上,由於種種原因,實驗或測量中所獲得的數據總會有一定的誤差。在這種情況下,如果強求構造的函數(曲線)通過各插值節點,顯然是不合理的。為此,人們設想構造一個函數(曲線)y=g(x)去擬合f(x),但它不必通過各插值節點,而只是使該曲線從這些插值節點中穿過,且使它在某種意義下最優。
MATLAB的曲線擬合是用常見的最小二乘原理,所構造的g(x)是一個次數小於擬合節點個數的多項式。
4.6.1 最小二乘原理及其曲線擬合算法
設測得離散的n+1個節點的數據如下:
構造一個如下的m次擬合多項式函數g(x)為 (m≤n):
所謂曲線擬合的最小二乘原理,就是使上述擬合多項式在各數據點處的偏差的平方之和達最小。
上式中的均為已知值,而式中的係數為個未知數,故可以將其看做是的函數,即。於是我們可以把上述曲線擬合歸結成對多元函數的求極值問題。為使取極小值,必須滿足以下方程組:
經過簡單的推導,可以得到一個m+1階線性代數方程組Sa=t,其中S為m+1階係數矩陣,t為右端項,而a為未知數向量,即欲求的m次擬合多項式的m+1個係數。這個方程組也稱為正則方程組。至於正則方程組的具體推導,可參閱有關數值計算方法的教材。
4.6.2 曲線擬合的實現
在MATLAB中,可以用polyfit函數來求最小二乘擬合多項式的係數,另外可以用polyval函數按所得的多項式計算指定值。
polyfit函數的調用語法是:
[p,s]=polyfit(x,y,m)
輸入參數x,y為測量而得的原始數據,為向量;m為欲擬合的多項式的次數。polyfit (x,y,m)將根據原始數據x、y得到一個m次擬合多項式P(x)的係數,該多項式能在最小二乘意義下最優地近似函數f(x),即有p(xi)≈f(xi)≈yi。
返回的結果中p為m次擬合多項式的係數,而s中的數據則是一個結構數組,代入polyval函數後可以得到擬合多項式相關的誤差估計。s最常用的寫法可以是:p=polyfit(x,y,M)。
polyval的函數功能是按多項式的係數計算指定點所對應的函數值。
【例4-43】 曲線擬合示例。
本例首先在多項式的基礎上加入隨機噪聲,產生測試數據,然後對測試數據進行數據曲線擬合:
>> clear
>> rand('state',0)
>> x=1:1:10;
>> y=-0.9*x.^2+10*x+20+rand(1,10).*5; % 產生測試數據
>> plot(x,y,'o') % 繪圖並標出原始數據點
>> p=polyfit(x,y,2)
>> xi=1:0.5:10;
>> yi=polyval(p,xi); % 計算擬合的結果
>> hold on
>> plot(xi,yi); % 繪製擬合結果圖
>> hold off
運行以上命令,得到的結果如圖4-10所示。另外得到的多項式係數為:
p =
-0.8923 9.8067 23.6003
也就是說通過曲線擬合,得到了多項式。通過比較係數和觀察圖形,可以看出本次曲線擬合結果的精度是比較高的。
圖4-10 曲線擬合
4.7 Fourier分析
傅立葉(Fourier)分析在信號處理領域有著廣泛的應用,現實生活中大部分的信號都包含有多個不同的頻率組件,這些信號組件頻率會隨著時間或快或慢的變化。傅立葉級數和傅立葉變換是用來分析周期或者非周期信號的頻率特性的數學工具。從時間的角度來看,傅立葉分析包括連續時間和離散時間的傅立葉變換,總共有4種不同的傅立葉分析類型:連續時間的傅立葉級數、連續時間的傅立葉變換、離散時間的傅立葉級數、離散時間的傅立葉變換等。
頻譜分析是在數據中識別頻率組成的處理過程。對於離散數據,頻譜分析的計算基礎是離散傅立葉變換(DFT)。DFT將time-based或者space-based數據轉換為frequency-based數據。
一個長度為n的向量x的DFT,也是一個長度為n的向量:
其中是n階複數根:
在此表達式中,i表示虛數單位 。
DFT有一種快速算法FFT,稱為快速傅立葉變換。FFT並不是與DFT不同的另一種變換,而是為了減少DFT運算次數的一種快速算法。它是對變換式進行一次分解,使其成為若干個小數點的組合,從而減少運算量。常用的FFT是以2為基數的,其長度用N表示,N為2的整數倍。
MATLAB中採用的就是FFT算法。MATLAB提供了函數fft和ifft等來進行傅立葉分析。
1.函數fft和ifft
函數fft和ifft對數據作一維快速傅立葉變換和傅立葉反變換,函數fft的調用語法有如下幾種。
(1)Y=fft(X):如果X是向量,則採用快速傅立葉變換算法作X的離散傅立葉變換;如果X是矩陣,則計算矩陣每一列的傅立葉變換。
(2)Y=fft(X,n):用參數n限制X的長度,如果X的長度小於n,則用0補足;如果X的長度大於n,則去掉長出的部分。
(3)Y=fft(X,[ ],n)或Y=fft(X,n,dim):在參數dim指定的維上進行操作。
函數ifft的用法和fft完全相同。
2.fft2和ifft2
函數fft2和ifft2對數據作二維快速傅立葉變換和傅立葉反變換。數據的二維傅立葉變換fft2(X)相當於fft(fft(X)』)』,即先對X的列做一維傅立葉變換,然後對變換結果的行做一維傅立葉變換。函數fft2的調用語法有如下幾種。
(1)Y=fft2(X):二維快速傅立葉變換。
(2)Y=fft2(X,MROWS,NCOLS):通過截斷或用0補足,使X成為MROWS*NCOLS的矩陣。
函數ifft2的用法和fft2完全相同。
3.fftshift和ifftshift
函數fftshift(Y)用於把傅立葉變換結果Y(頻域數據)中的直流分量(頻率為0處的值)移到中間位置:
(1)如果Y是向量,則交換Y的左右半邊;
(2)如果Y是矩陣,則交換其一三象限和二四象限;
(3)如果Y是多維數組,則在數組的每一維交換其「半空間」。
函數ifftshift相當於把fftshift函數的操作逆轉,用法相同。
【例4-44】 生成一個正弦衰減曲線,進行快速傅立葉變換,並畫出幅值(amplitude)圖、相位(phase)圖、實部(real)圖和虛部(image)圖。
>> tp=0:2048; % 時域數據點數N
>> yt=sin(0.08*pi*tp).*exp(-tp/80); % 生成正弦衰減函數
>> plot(tp,yt), axis([0,400,-1,1]), % 繪正弦衰減曲線
>> t=0:800/2048:800; % 頻域點數Nf
>> f=0:1.25:1000;
>> yf=fft(yt); % 快速傅立葉變換
>> ya=abs(yf(1:801)); % 幅值
>> yp=angle(yf(1:801))*180/pi; % 相位
>> yr=real(yf(1:801)); % 實部
>> yi=imag(yf(1:801)); % 虛部
>> figure
>> subplot(2,2,1)
>> plot(f,ya),axis([0,200,0,60]) % 繪製幅值曲線
>> title('幅值曲線')
>> subplot(2,2,2)
>> plot(f,yp),axis([0,200,-200,10]) % 繪製相位曲線
>> title('相位曲線')
>> subplot(2,2,3)
>> plot(f,yr),axis([0,200,-40,40]) % 繪製實部曲線
>> title('實部曲線')
>> subplot(2,2,4)
>> plot(f,yi),axis([0,200,-60,10]) % 繪製虛部曲線
>> title('虛部曲線')
本例首先生成正弦衰減函數yt,繪製的正弦衰減曲線如圖4-11所示。然後對yt進行了快速傅立葉變換,結果如圖4-12所示。
圖4-11 正弦衰減曲線圖
圖4-12 傅立葉變換結果