日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

AR模型在信号处理中的应用

發(fā)布時間:2025/5/22 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 AR模型在信号处理中的应用 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

本文目標:分析AR模型并求解AR模型的輸出x(n)的功率譜。


1. AR模型概念觀

數(shù)字信號處理功率譜估計方法分經(jīng)典功率譜估計和現(xiàn)代功率譜估計,現(xiàn)代功率譜估計以參數(shù)模型功率譜估計為代表,參數(shù)功率譜模型如下:? ? ? ? ? ? ?

u(n)?——> ?H(z) ? ——>?x(n)

參數(shù)模型的基本思路是:

—— 參數(shù)模型假設研究過程是由一個輸入序列u(n)激勵一個線性系統(tǒng)H(z)的輸出。

—— 由假設參數(shù)模型的輸出x(n)或其自相關函數(shù)來估計H(z)的參數(shù)

—— 由H(z)的參數(shù)估計x(n)的功率譜

因此,參數(shù)模型功率譜的求解有兩步:

(1)H(z)模型參數(shù)估計

(2)依據(jù)模型參數(shù)求功率譜

AR模型(自回歸模型,Auto Regression Model)是典型的現(xiàn)代參數(shù)功模型。其定義為

其中,輸入設定為方差為的白噪聲序列,ak是模型的參數(shù),p是模型的階數(shù),Px為x(n)功率譜,也即本文要求解的目標。

AR模型是一個全極點模型,“自回歸”的含義是:現(xiàn)在的輸出是現(xiàn)在的輸入和過去p個輸出的加權(quán)和。

現(xiàn)在我們希望建立AR參數(shù)模型和x(n)的自相關函數(shù)的關系,也即AR模型的正則方程:


上面的正則方程也稱Yule-Walker方程,其中的rx為自相關函數(shù)。由方程可以看出,一個p階的AR模型有p+1個參數(shù)()。

通過推導可以發(fā)現(xiàn),AR模型與線性預測器是等價的,AR模型是在最小平方意義上對數(shù)據(jù)的擬合。

2. AR模型參數(shù)求解——Levinson-Durbin Algorithm

定義為p階AR模型在m階次時的第k個系數(shù),k=1,2,...,m。定義為m階系統(tǒng)時的,這也是線性預測器中前向預測的最小誤差功率。此時,一階AR模型時有



我們定義初始時,則


由PART1中矩陣的對稱性質(zhì),將上面的公式推廣到高階AR模型,可以推導出Levinson-Durbin遞推算法:




Levinson-Durbin遞推算法從低階開始遞推,,給出了每一階次時所有參數(shù),。這一特點有利于我們選擇合適的AR模型階次。

因為必須大于0,由式知,如果,遞推應該停止。

到此,選擇最佳階次的參數(shù)代入到中,求得功率譜。


3. matlab實現(xiàn)

matlab工具箱中提供了現(xiàn)成的函數(shù)實現(xiàn)AR模型功率譜計算。參考[2],我們將內(nèi)容摘錄如下:


AR模型的譜估計是現(xiàn)代譜估計的主要內(nèi)容。

1.AR模型的Yule—Walker方程和Levinson-Durbin遞推算法:在MATLAB中,函數(shù)levinson和aryule都采用Levinson-Durbin遞推算法來求解AR模型的參數(shù)a1,a2,……,ap及白噪聲序列的方差,只是兩者的輸入?yún)?shù)不同,它們的格式為:

A=LEVINSON(R,ORDER) A=ARYULE(x,ORDER)

兩函數(shù)均為定階ORDER的求解,但是函數(shù)levinson的輸入?yún)?shù)要求是序列的自相關函數(shù),而函數(shù)aryule的輸入?yún)?shù)為采樣序列。

下面語句說明函數(shù)levinson和函數(shù)aryule的功能是相同的:

例子:

randn('seed',0)

a=[1 0.1 0.2 0.3 0.4 0.5];

x=impz(1,a,20)+randn(20,1)/20;

r=xcorr(x,'biased');

r(1:length(x)-1)=[];

A=levinson(r,5)

B=aryule(x,5)

2.Burg算法:

格式為:A=ARBURG(x,ORDER); 其中x為有限長序列,參數(shù)ORDER用于指定AR模型的階數(shù)。以上面的例子為例:

randn('seed',0)

a=[1 0.1 0.2 0.3 0.4 0.5];

x=impz(1,a,20)+randn(20,1)/20;

A=arburg(x,5)

3.改進的協(xié)方差法:

格式為:A=ARMCOV(x,ORDER); 該函數(shù)用來計算有限長序列x(n)的ORDER階AR模型的參數(shù)。例如:輸入下面語句:

randn('seed',0)

a=[1 0.1 0.2 0.3 0.4 0.5];

x=impz(1,a,20)+randn(20,1)/20;

A=armcov(x,5)

AR模型階數(shù)P的選擇:

AR模型階數(shù)P一般事先是不知道的,需要事先選定一個較大的值,在遞推的過程中確定。在使用Levinson—Durbin遞推方法時,可以給出由低階到高階的每一組參數(shù),且模型的最小預測誤差功率Pmin(相當于白噪聲序列的方差)是遞減的。直觀上講,當預測誤差功率P達到指定的希望值時,或是不再發(fā)生變化時,這時的階數(shù)即是應選的正確階數(shù)。

因為預測誤差功率P是單調(diào)下降的,因此,該值降到多少才合適,往往不好選擇。比較常見的準則是:

最終預測誤差準則:FPE(r)=Pr{[N+(r+1)]/ [N-(r+1)]}

信息論準則:AIC(r)=N*log(Pr)+2*r

上面的N為有限長序列x(n)的長度,當階數(shù)r由1增加時,FPE(r) 和AIC(r)都將在某一r處取得極小值。將此時的r定為最合適的階數(shù)p。

MATLAB中AR模型的譜估計的函數(shù)說明:

1. Pyulear函數(shù):

功能:利用Yule--Walker方法進行功率譜估計.

格式: Pxx=Pyulear(x,ORDER,NFFT)

[Pxx,W]=Pyulear(x,ORDER,NFFT)

[Pxx,W]=Pyulear(x,ORDER,NFFT,Fs)

Pyulear(x,ORDER,NFFT,Fs,RANGE,MAGUNITS)

說明:Pxx =Pyulear(x,ORDER,NFFT)中,采用Yule--Walker方法估計序列x的功率譜,參數(shù)ORDER用來指定AR模型的階數(shù),NFFT為FFT算法的長度,默認值為256,若NFFT為偶數(shù),則Pxx為(NFFT/2 + 1)維的列矢量,若NFFT為奇數(shù),則Pxx為(NFFT + 1)/2維的列矢量;當x為復數(shù)時,Pxx長度為NFFT。

[Pxx,W]=Pyulear(x,ORDER,NFFT)中,返回一個頻率向量W.

[Pxx,W]=Pyulear(x,ORDER,NFFT,Fs)中,可以在F向量得到功率譜估計的頻率點,Fs指定采樣頻率。

Pyulear(x,ORDER,NFFT,Fs,RANGE,MAGUNITS)中,直接畫出功率譜估計的曲線圖。

2. Pburg函數(shù):

功能:利用Burg方法進行功率譜估計。

格式:Pxx=Pburg(x,ORDER,NFFT)

[Pxx,W]=Pburg(x,ORDER,NFFT)

[Pxx,W]=Pburg(x,ORDER,NFFT,Fs)

Pburg(x,ORDER,NFFT,Fs,RANGE,MAGUNITS)

說明:Pburg函數(shù)與Pyulear函數(shù)格式相同,只是計算AR模型時所采用的方法不同,因此格式可以參照Pyulear函數(shù)。

3. Pcov函數(shù):

功能:利用協(xié)方差方法進行功率譜估計。

格式:Pxx=Pcov(x,ORDER,NFFT)

[Pxx,W]=Pcov(x,ORDER,NFFT)

[Pxx,W]=Pcov(x,ORDER,NFFT,Fs)

Pcov(x,ORDER,NFFT,Fs,RANGE,MAGUNITS)

說明:Pcov函數(shù)采用協(xié)方差法估計AR模型的參數(shù),然后計算序列x的功率譜。協(xié)方差法與改進的協(xié)方差法相比,前者僅令前向預測誤差為最小,其他步驟是一樣的。:Pcov函數(shù)與Pyulear函數(shù)格式相同,只是計算AR模型時所采用的方法不同,因此格式可以參照Pyulear函數(shù).

4.Pmcov:

功能:利用改進的協(xié)方差方法進行功率譜估計。

格式:Pxx=Pmcov(x,ORDER,NFFT)

[Pxx,W]=Pmcov(x,ORDER,NFFT)

[Pxx,W]=Pmcov(x,ORDER,NFFT,Fs)

Pmcov(x,ORDER,NFFT,Fs,RANGE,MAGUNITS)

例如:輸入下面語句:

figure 8.10--8.11

Fs=1000; %采樣頻率

n=0:1/Fs:3;

xn=cos(2*pi*n*200)+randn(size(n));

%設置參數(shù)

order=20;

nfft=1024;

%Yule-Walker方法

figure(1)

pyulear(xn,order,nfft,Fs);

%Burg方法

figure(2)

pburg(xn,order,nfft,Fs);

%協(xié)方差法

figure(3)

pcov(xn,order,nfft,Fs);

%改進協(xié)方差方法

figure(4)

pmcov(xn,order,nfft,Fs);


AR譜的分辨率:

經(jīng)典譜估計的分辨率反比與信號的有效長度,但是現(xiàn)代譜估計的分辨率可以不受此限制. 這是因為對于給定的N點有限長序列x(n),雖然其估計出的相關函數(shù)也是有限長的,但是現(xiàn)代譜估計的一些方法隱含著數(shù)據(jù)和自相關函數(shù)的外推,使其可能的長度超過給定的長度,因而AR譜的分辨率較高。

例如:序列x(n)由兩個正鉉信號組成,其頻率分別為f1=20Hz和f2=21Hz,并含有一定的噪聲量。試分別用周期圖法,Burg方法與改進的協(xié)方差法估計信號的功率譜,且AR模型的階數(shù)取30和50兩種情況討論。

上面的例子可以通過下面程序?qū)崿F(xiàn):

Fs=200;

n=0:1/Fs:1;

xn=sin(2*pi*20*n)+sin(2*pi*21*n)+0.1*randn(size(n));

window=boxcar(length(xn));

nfft=512;

[Pxx,f]=periodogram(xn,window,nfft,Fs);

figure(1)

plot(f,10*log10(Pxx)),grid

xlabel('Frequency(Hz)')

ylabel('Power Spectral Density(dB/Hz)')

title('Periodogram PSD Estimate')

order1=30;

order2=50;

figure(2)

pburg(xn,order1,nfft,Fs)

figure(3)

pburg(xn,order2,nfft,Fs)

figure(4)

pmcov(xn,order1,nfft,Fs)

figure(5)

pmcov(xn,order1,nfft)


4. C語言實現(xiàn)

[cpp] view plaincopy print?
  • /*?
  • ?*?ar_model.h?
  • ?*?
  • ?*??Created?on:?2013-8-11?
  • ?*??????Author:?monkeyzx?
  • ?*/??
  • ??
  • #ifndef?AR_MODEL_H_??
  • #define?AR_MODEL_H_??
  • ??
  • typedef?struct?{??
  • ????float?real;??
  • ????float?imag;??
  • }?complex;??
  • ??
  • extern?void?maryuwa(complex?x[],complex?a[],complex?r[],int?n,int?ip,??
  • ????????float?*ep,int?*ierror);??
  • extern?void?mpsplot(float?psdr[],float?psdi[],int?mfre,float?ts);??
  • ??
  • extern?void?zx_ar_model(void);??
  • ??
  • #endif?/*?AR_MODEL_H_?*/??
  • /** ar_model.h** Created on: 2013-8-11* Author: monkeyzx*/#ifndef AR_MODEL_H_ #define AR_MODEL_H_typedef struct {float real;float imag; } complex;extern void maryuwa(complex x[],complex a[],complex r[],int n,int ip,float *ep,int *ierror); extern void mpsplot(float psdr[],float psdi[],int mfre,float ts);extern void zx_ar_model(void);#endif /* AR_MODEL_H_ */
    [cpp] view plaincopy print?
  • /*?
  • ?*?ar_model.c?
  • ?*?
  • ?*??Created?on:?2013-8-11?
  • ?*??????Author:?monkeyzx?
  • ?*/??
  • ??
  • #include?<stdio.h>??
  • #include?<stdlib.h>??
  • #include?<math.h>??
  • #include?<stdlib.h>??
  • //#include?"msp.h"??
  • #include?"ar_model.h"??
  • #include?"time.h"??
  • ??
  • float?mabs(complex?a)??
  • {??
  • ?????float?m;??
  • ??
  • ?????m=a.real*a.real+a.imag*a.imag;??
  • ?????m=sqrt(m);??
  • ??
  • ?????return(m);??
  • }??
  • ??
  • /*---------------------------------------------------------------------?
  • ??Routine?MCORRE1:To?estimate?the?biased?cross-correlation?function?
  • ??of?complex?arrays?x?and?y.?If?y=x,then?it?is?auto-correlation.?
  • ??input?parameters:?
  • ?????x??:n?dimensioned?complex?array.?
  • ?????y??:n?dimensioned?complex?array.?
  • ?????n??:the?dimension?of?x?and?y.?
  • ?????lag:point?numbers?of?correlation.?
  • ??output?parameters:?
  • ?????r??:lag?dimensioned?complex?array,?the?correlation?function?is?
  • ?????????stored?in?r(0)?to?r(lag-1).?
  • ??????????????????????????????????????in?Chapter?1?and?11?
  • ---------------------------------------------------------------------*/??
  • void?mcorre1(complex?x[],complex?y[],complex?r[],int?n,int?lag)??
  • {??
  • ????int?m,j,k;??
  • ??
  • ????for(k=0;k<lag;k++)?{??
  • ????????m=n-1-k;??
  • ????????r[k].real=0.0f;??
  • ????????r[k].imag=0.0f;??
  • ????????for(j=0;j<=m;j++)?{??
  • ????????????r[k].real+=y[j+k].real*x[j].real+y[j+k].imag*x[j].imag;??
  • ????????????r[k].imag+=y[j+k].imag*x[j].real-y[j+k].real*x[j].imag;??
  • ????????}??
  • ????????r[k].real=r[k].real/n;??
  • ????????r[k].imag=r[k].imag/n;??
  • ????}??
  • ????return;??
  • }??
  • ??
  • /*---------------------------------------------------------------------?
  • ??Routine?maryuwa:?To?determine?the?autoregressive?coefficients?by?
  • ??????????solving?Yule-Walker?equation?with?Levinson?algorithm.?
  • ??Input?Parameters:?
  • ?????n?????:?Number?of?data?samples?(integer)?
  • ?????ip????:?Order?of?autoregressive?model?
  • ?????x?????:?Array?of?complex?data?values,?x(0)?to?x(n-1)?
  • ??Output?Parameters:?
  • ?????ep????:?Driving?noise?variance?(real)?
  • ?????a?????:?Array?of?complex?autoregressive?coefficients,?a(0)?to?
  • ?????????????a(ip)?
  • ??ierror=0?:?No?error?
  • ????????=1?:?ep<=0?.?
  • ?
  • ????????r??:?complex?work?array,?auto-correlation?
  • ???????????????????????????????????????in?chapter?12?
  • --------------------------------------------------------------------*/??
  • void?maryuwa(complex?x[],complex?a[],complex?r[],int?n,int?ip,??
  • float?*ep,int?*ierror)??
  • {??
  • ????complex?sum;??
  • ????int?i,k;??
  • ????float?r0;??
  • ??
  • ????*ierror=1;??
  • ????mcorre1(x,x,r,n,ip+1);??
  • ????a[0].real=1.0;??
  • ????a[0].imag=0.0;??
  • ????r0=r[0].real;??
  • ????a[1].real=-r[1].real/r0;??
  • ????a[1].imag=-r[1].imag/r0;??
  • ????*ep=r0*(1.0f-pow(mabs(a[1]),2));??
  • ????for(k=2;k<=ip;k++)?{??
  • ????????sum.real=0.;??
  • ????????sum.imag=0.;??
  • ????????for(i=1;i<k;i++)?{??
  • ????????????sum.real+=r[k-i].real*a[i].real-r[k-i].imag*a[i].imag;??
  • ????????????sum.imag+=r[k-i].real*a[i].imag+r[k-i].imag*a[i].real;??
  • ????????}??
  • ????????sum.real+=r[k].real;??
  • ????????sum.imag+=r[k].imag;??
  • ????????a[k].real=-sum.real/(*ep);??
  • ????????a[k].imag=-sum.imag/(*ep);??
  • ????????(*ep)*=1.-pow(mabs(a[k]),2);??
  • ????????if(*ep<=0.0)??
  • ????????????return;??
  • ????????for(i=1;i<k;i++)?{??
  • ????????????x[i].real=a[i].real+a[k-i].real*a[k].real+??
  • ????????????????????a[k-i].imag*a[k].imag;??
  • ????????????x[i].imag=a[i].imag+a[k-i].real*a[k].imag-??
  • ????????????????????a[k-i].imag*a[k].real;??
  • ????????}??
  • ????????for(i=1;i<k;i++)?{??
  • ????????????a[i].real=x[i].real;??
  • ????????????a[i].imag=x[i].imag;??
  • ????????}??
  • ????}??
  • ????*ierror=0;??
  • }??
  • ??
  • /*----------------------------------------------------------------------?
  • ??routinue?mrelfft:To?perform??split-radix?DIF?fft?algorithm.?
  • ?
  • ??input?parameters:?
  • ???xr,xi:real?and?image?part?of?complex?data?for?DFT/IDFT,n=0,...,N-1?
  • ???N????:Data?point?number?of?DFT?compute?.?
  • ???isign:Transform?direction?disignator?,?
  • ???????????????isign=-1:?For?Forward?Transform.?
  • ???????????????isign=+1:?For?Inverse?Transform.?
  • ?
  • ??output?parameters:?
  • ???xr,xi:real?and?image?part?of?complex?result?of?DFT/IDFT,n=0,...,N-1?
  • ?
  • ??Note:?N??must?be?a?power?of?2?.?
  • ???????????????????????????????????????in?chapter?5?
  • ---------------------------------------------------------------------*/??
  • void?mrelfft(float?xr[],float?xi[],int?n,int?isign)??
  • {??
  • ????float?e,es,cc1,ss1,cc3,ss3,r1,s1,r2,s2,s3,xtr,xti,a,a3;??
  • ????int?m,n2,n4,j,k,is,id,i0,i1,i2,i3,n1,i,nn;??
  • ??
  • ????for(m=1;m<=16;m++)?{??
  • ????????nn=pow(2,m);??
  • ????????if(n==nn)break;??
  • ????}??
  • ????if(m>16)?{??
  • #ifdef?_DEBUG??
  • ????????printf("?N?is?not?a?power?of?2?!?\n");??
  • #endif??
  • ????????return;??
  • ????}??
  • ????n2=n*2;??
  • ????es=-isign*atan(1.0)*8.0;??
  • ????for(k=1;k<m;k++)?{??
  • ????????n2=n2/2;??
  • ????????n4=n2/4;??
  • ????????e=es/n2;??
  • ????????a=0.0;??
  • ????????for(j=0;j<n4;j++)?{??
  • ????????????a3=3*a;??
  • ????????????cc1=cos(a);??
  • ????????????ss1=sin(a);??
  • ????????????cc3=cos(a3);??
  • ????????????ss3=sin(a3);??
  • ????????????a=(j+1)*e;??
  • ????????????is=j;??
  • ????????????id=2*n2;??
  • ????????????do?{??
  • ????????????????for(i0=is;i0<n;i0+=id)?{??
  • ????????????????????i1=i0+n4;??
  • ????????????????????i2=i1+n4;??
  • ????????????????????i3=i2+n4;??
  • ????????????????????r1=xr[i0]-xr[i2];??
  • ????????????????????s1=xi[i0]-xi[i2];??
  • ????????????????????r2=xr[i1]-xr[i3];??
  • ????????????????????s2=xi[i1]-xi[i3];??
  • ????????????????????xr[i0]+=xr[i2];??
  • ????????????????????xi[i0]+=xi[i2];??
  • ????????????????????xr[i1]+=xr[i3];??
  • ????????????????????xi[i1]+=xi[i3];??
  • ????????????????????if(isign!=1)?{??
  • ????????????????????????s3=r1-s2;??
  • ????????????????????????r1=r1+s2;??
  • ????????????????????????s2=r2-s1;??
  • ????????????????????????r2=r2+s1;??
  • ????????????????????}?else?{??
  • ????????????????????????????s3=r1+s2;??
  • ????????????????????????????r1=r1-s2;??
  • ????????????????????????????s2=-r2-s1;??
  • ????????????????????????????r2=-r2+s1;??
  • ????????????????????}??
  • ????????????????????xr[i2]=r1*cc1-s2*ss1;??
  • ????????????????????xi[i2]=-s2*cc1-r1*ss1;??
  • ????????????????????xr[i3]=s3*cc3+r2*ss3;??
  • ????????????????????xi[i3]=r2*cc3-s3*ss3;??
  • ????????????????}??
  • ????????????????is=2*id-n2+j;??
  • ????????????????id=4*id;??
  • ????????????}while(is<n-1);??
  • ????????}??
  • ????}??
  • /*???------------?special?last?stage?-------------------------*/??
  • ????is=0;??
  • ????id=4;??
  • ????do?{??
  • ????????for(i0=is;i0<n;i0+=id)?{??
  • ????????????i1=i0+1;??
  • ????????????xtr=xr[i0];??
  • ????????????xti=xi[i0];??
  • ????????????xr[i0]=xtr+xr[i1];??
  • ????????????xi[i0]=xti+xi[i1];??
  • ????????????xr[i1]=xtr-xr[i1];??
  • ????????????xi[i1]=xti-xi[i1];??
  • ????????}??
  • ????????is=2*id-2;??
  • ????????id=4*id;??
  • ????}?while(is<n-1);??
  • ????j=1;??
  • ????n1=n-1;??
  • ????for(i=1;i<=n1;i++)?{??
  • ????????if(i<j)?{??
  • ????????????xtr=xr[j-1];??
  • ????????????xti=xi[j-1];??
  • ????????????xr[j-1]=xr[i-1];??
  • ????????????xi[j-1]=xi[i-1];??
  • ????????????xr[i-1]=xtr;??
  • ????????????xi[i-1]=xti;??
  • ????????}??
  • ????????k=n/2;??
  • ????????while(1)?{??
  • ????????????if(k>=j)break;??
  • ????????????j=j-k;??
  • ????????????k=k/2;??
  • ????????}??
  • ????????j=j+k;??
  • ????}??
  • ????if(isign==-1)?return;??
  • ????for(i=0;i<n;i++)?{??
  • ????????xr[i]/=n;??
  • ????????xi[i]/=n;??
  • ????}??
  • }??
  • ??
  • /*---------------------------------------------------------------------?
  • ???Routine?mpsplot:?To?plot?the?normalized?power?spectum?curve?on?the?
  • ???normalized?frequency?axis?from?-.5?to??+.5?.?
  • ????????mfre?:?Points?in?frequency?axis?and?must?be?the?power?of?2.?
  • ????????ts???:?Sample?interval?in?seconds?(real).?
  • ????????psdr?:?Real?array?of?power?spectral?density?values.?
  • ????????psdi?:?Real?work?array.?
  • ???????????????????????????????????????in?chapter?11,12?
  • --------------------------------------------------------------------*/??
  • void?mpsplot(float?psdr[],float?psdi[],int?mfre,float?ts)??
  • {??
  • ????FILE?*fp;??
  • ????char?filename[30];??
  • ????int?k,m2;??
  • ????float?pmax,fs,faxis;??
  • ??
  • ????m2=mfre/2;??
  • ????for(k=0;k<m2;k++){??
  • ????????psdi[k]=psdr[k];??
  • ????????psdr[k]=psdr[k+m2];??
  • ????????psdr[k+m2]=psdi[k];??
  • ????}??
  • ????pmax=psdr[0];??
  • ????for(k=1;k<mfre;k++)??
  • ????????if(psdr[k]>pmax)??
  • ????????????pmax=psdr[k];??
  • ????????for(k=0;k<mfre;k++)?{??
  • ????????????psdr[k]=psdr[k]/pmax;??
  • ????????if(psdr[k]<=0.0)??
  • ????????????psdr[k]=.000001;??
  • ????}??
  • ????fs=1./ts;??
  • ????fs=fs/(float)(mfre);??
  • ????printf("Please?input?filename:\n");??
  • ????scanf("%s",filename);??
  • ????if((fp=fopen(filename,"w"))==NULL)?{??
  • ????????printf("cannot?open?file\n");??
  • ????????exit(0);??
  • ????}??
  • ????for(k=0;k<mfre;k++)?{??
  • ????????faxis=fs*(k-m2);??
  • ????????fprintf(fp,"%f,%f\n",faxis,10.*log10(psdr[k]));??
  • ????}??
  • ????fclose(fp);??
  • ????return;??
  • }??
  • ??
  • /*----------------------------------------------------------------------?
  • ???Routine?mar1psd:?To?compute?the?power?spectum?by?AR-model?parameters.?
  • ???Input?parameters:?
  • ??????????ip?:?AR?model?order?(integer)?
  • ??????????ep???:?White?noise?variance?of?model?input?(real)?
  • ??????????ts???:?Sample?interval?in?seconds?(real)?
  • ??????????a????:?Complex?array?of?AR??parameters?a(0)?to?a(ip)?
  • ???Output?parameters:?
  • ??????????psdr?:?Real?array?of?power?spectral?density?values?
  • ??????????psdi?:?Real?work?array?
  • ????????????????????????????????????????in?chapter?12?
  • ---------------------------------------------------------------------*/??
  • void?mar1psd(complex?a[],int?ip,int?mfre,float?*ep,float?ts)??
  • {??
  • ????static?float?psdr[4096];??
  • ????static?float?psdi[4096];??
  • ????int?k;??
  • ????float?p;??
  • ??
  • ????for(k=0;k<=ip;k++)?{??
  • ????????psdr[k]=a[k].real;??
  • ????????psdi[k]=a[k].imag;??
  • ????}??
  • ????for(k=ip+1;k<mfre;k++)?{??
  • ????????psdr[k]=0.;??
  • ????????psdi[k]=0.;??
  • ????}??
  • ????mrelfft(psdr,psdi,mfre,-1);??
  • ????for(k=0;k<mfre;k++)?{??
  • ????????p=pow(psdr[k],2)+pow(psdi[k],2);??
  • ????????psdr[k]=(*ep)*ts/p;??
  • ????}??
  • ??
  • ????mpsplot(psdr,psdi,mfre,ts);??
  • ??
  • ????return;??
  • }??
  • ??
  • ??
  • /*?
  • ?*?Below?are?examples?for?using?@maryuwa?and?@mar1psd?
  • ?*/??
  • #define?PI????????????(3.1415926)??
  • #define?N?????????????(1024)??
  • #define?AN????????????(10)??
  • complex?x[N];??
  • complex?r[N];??
  • complex?a[AN];??
  • ??
  • /*?
  • ?*?generate?random?number?which?satify?guass?distribution?
  • ?*/??
  • double?guass_rand(void)??
  • {??
  • ????static?double?V1,?V2,?S;??
  • ????static?int?phase?=?0;??
  • ????double?X;??
  • ??
  • ????if?(?phase?==?0?)?{??
  • ????????do?{??
  • ????????????double?U1?=?(double)rand()?/?RAND_MAX;??
  • ????????????double?U2?=?(double)rand()?/?RAND_MAX;??
  • ??
  • ????????????V1?=?2?*?U1?-?1;??
  • ????????????V2?=?2?*?U2?-?1;??
  • ????????????S?=?V1?*?V1?+?V2?*?V2;??
  • ????????}?while(S?>=?1?||?S?==?0);??
  • ??
  • ????????X?=?V1?*?sqrt(-2?*?log(S)?/?S);??
  • ????}?else?{??
  • ????????X?=?V2?*?sqrt(-2?*?log(S)?/?S);??
  • ????}??
  • ??
  • ????phase?=?1?-?phase;??
  • ??
  • ????return?X;??
  • }??
  • ??
  • void?zx_ar_model(void)??
  • {??
  • ????int?i=0;??
  • ????float?ep?=?0;??
  • ????int?ierror?=?0;??
  • ??
  • ????/*?
  • ?????*?generate?x[N]?
  • ?????*/??
  • ????srand(time(NULL));??
  • ????for?(i=0;?i<N;?i++)?{??
  • ????????x[i].real?=?sin(2*PI*i/N)?+?guass_rand();??
  • ????????x[i].imag?=?0;??
  • ????}??
  • ??
  • ????/*?Find?parameters?for?AR?model?*/??
  • ????maryuwa(x,?a,?r,?N,?AN,?&ep,?&ierror);??
  • ??
  • ????/*?Calculate?power?spectum?using?parameters?of?AR?model?*/??
  • ????mar1psd(a,?AN,?N,?&ep,?1);??
  • }??
  • /** ar_model.c** Created on: 2013-8-11* Author: monkeyzx*/#include <stdio.h> #include <stdlib.h> #include <math.h> #include <stdlib.h> //#include "msp.h" #include "ar_model.h" #include "time.h"float mabs(complex a) {float m;m=a.real*a.real+a.imag*a.imag;m=sqrt(m);return(m); }/*---------------------------------------------------------------------Routine MCORRE1:To estimate the biased cross-correlation functionof complex arrays x and y. If y=x,then it is auto-correlation.input parameters:x :n dimensioned complex array.y :n dimensioned complex array.n :the dimension of x and y.lag:point numbers of correlation.output parameters:r :lag dimensioned complex array, the correlation function isstored in r(0) to r(lag-1).in Chapter 1 and 11 ---------------------------------------------------------------------*/ void mcorre1(complex x[],complex y[],complex r[],int n,int lag) {int m,j,k;for(k=0;k<lag;k++) {m=n-1-k;r[k].real=0.0f;r[k].imag=0.0f;for(j=0;j<=m;j++) {r[k].real+=y[j+k].real*x[j].real+y[j+k].imag*x[j].imag;r[k].imag+=y[j+k].imag*x[j].real-y[j+k].real*x[j].imag;}r[k].real=r[k].real/n;r[k].imag=r[k].imag/n;}return; }/*---------------------------------------------------------------------Routine maryuwa: To determine the autoregressive coefficients bysolving Yule-Walker equation with Levinson algorithm.Input Parameters:n : Number of data samples (integer)ip : Order of autoregressive modelx : Array of complex data values, x(0) to x(n-1)Output Parameters:ep : Driving noise variance (real)a : Array of complex autoregressive coefficients, a(0) toa(ip)ierror=0 : No error=1 : ep<=0 .r : complex work array, auto-correlationin chapter 12 --------------------------------------------------------------------*/ void maryuwa(complex x[],complex a[],complex r[],int n,int ip, float *ep,int *ierror) {complex sum;int i,k;float r0;*ierror=1;mcorre1(x,x,r,n,ip+1);a[0].real=1.0;a[0].imag=0.0;r0=r[0].real;a[1].real=-r[1].real/r0;a[1].imag=-r[1].imag/r0;*ep=r0*(1.0f-pow(mabs(a[1]),2));for(k=2;k<=ip;k++) {sum.real=0.;sum.imag=0.;for(i=1;i<k;i++) {sum.real+=r[k-i].real*a[i].real-r[k-i].imag*a[i].imag;sum.imag+=r[k-i].real*a[i].imag+r[k-i].imag*a[i].real;}sum.real+=r[k].real;sum.imag+=r[k].imag;a[k].real=-sum.real/(*ep);a[k].imag=-sum.imag/(*ep);(*ep)*=1.-pow(mabs(a[k]),2);if(*ep<=0.0)return;for(i=1;i<k;i++) {x[i].real=a[i].real+a[k-i].real*a[k].real+a[k-i].imag*a[k].imag;x[i].imag=a[i].imag+a[k-i].real*a[k].imag-a[k-i].imag*a[k].real;}for(i=1;i<k;i++) {a[i].real=x[i].real;a[i].imag=x[i].imag;}}*ierror=0; }/*----------------------------------------------------------------------routinue mrelfft:To perform split-radix DIF fft algorithm.input parameters:xr,xi:real and image part of complex data for DFT/IDFT,n=0,...,N-1N :Data point number of DFT compute .isign:Transform direction disignator ,isign=-1: For Forward Transform.isign=+1: For Inverse Transform.output parameters:xr,xi:real and image part of complex result of DFT/IDFT,n=0,...,N-1Note: N must be a power of 2 .in chapter 5 ---------------------------------------------------------------------*/ void mrelfft(float xr[],float xi[],int n,int isign) {float e,es,cc1,ss1,cc3,ss3,r1,s1,r2,s2,s3,xtr,xti,a,a3;int m,n2,n4,j,k,is,id,i0,i1,i2,i3,n1,i,nn;for(m=1;m<=16;m++) {nn=pow(2,m);if(n==nn)break;}if(m>16) { #ifdef _DEBUGprintf(" N is not a power of 2 ! \n"); #endifreturn;}n2=n*2;es=-isign*atan(1.0)*8.0;for(k=1;k<m;k++) {n2=n2/2;n4=n2/4;e=es/n2;a=0.0;for(j=0;j<n4;j++) {a3=3*a;cc1=cos(a);ss1=sin(a);cc3=cos(a3);ss3=sin(a3);a=(j+1)*e;is=j;id=2*n2;do {for(i0=is;i0<n;i0+=id) {i1=i0+n4;i2=i1+n4;i3=i2+n4;r1=xr[i0]-xr[i2];s1=xi[i0]-xi[i2];r2=xr[i1]-xr[i3];s2=xi[i1]-xi[i3];xr[i0]+=xr[i2];xi[i0]+=xi[i2];xr[i1]+=xr[i3];xi[i1]+=xi[i3];if(isign!=1) {s3=r1-s2;r1=r1+s2;s2=r2-s1;r2=r2+s1;} else {s3=r1+s2;r1=r1-s2;s2=-r2-s1;r2=-r2+s1;}xr[i2]=r1*cc1-s2*ss1;xi[i2]=-s2*cc1-r1*ss1;xr[i3]=s3*cc3+r2*ss3;xi[i3]=r2*cc3-s3*ss3;}is=2*id-n2+j;id=4*id;}while(is<n-1);}} /* ------------ special last stage -------------------------*/is=0;id=4;do {for(i0=is;i0<n;i0+=id) {i1=i0+1;xtr=xr[i0];xti=xi[i0];xr[i0]=xtr+xr[i1];xi[i0]=xti+xi[i1];xr[i1]=xtr-xr[i1];xi[i1]=xti-xi[i1];}is=2*id-2;id=4*id;} while(is<n-1);j=1;n1=n-1;for(i=1;i<=n1;i++) {if(i<j) {xtr=xr[j-1];xti=xi[j-1];xr[j-1]=xr[i-1];xi[j-1]=xi[i-1];xr[i-1]=xtr;xi[i-1]=xti;}k=n/2;while(1) {if(k>=j)break;j=j-k;k=k/2;}j=j+k;}if(isign==-1) return;for(i=0;i<n;i++) {xr[i]/=n;xi[i]/=n;} }/*---------------------------------------------------------------------Routine mpsplot: To plot the normalized power spectum curve on thenormalized frequency axis from -.5 to +.5 .mfre : Points in frequency axis and must be the power of 2.ts : Sample interval in seconds (real).psdr : Real array of power spectral density values.psdi : Real work array.in chapter 11,12 --------------------------------------------------------------------*/ void mpsplot(float psdr[],float psdi[],int mfre,float ts) {FILE *fp;char filename[30];int k,m2;float pmax,fs,faxis;m2=mfre/2;for(k=0;k<m2;k++){psdi[k]=psdr[k];psdr[k]=psdr[k+m2];psdr[k+m2]=psdi[k];}pmax=psdr[0];for(k=1;k<mfre;k++)if(psdr[k]>pmax)pmax=psdr[k];for(k=0;k<mfre;k++) {psdr[k]=psdr[k]/pmax;if(psdr[k]<=0.0)psdr[k]=.000001;}fs=1./ts;fs=fs/(float)(mfre);printf("Please input filename:\n");scanf("%s",filename);if((fp=fopen(filename,"w"))==NULL) {printf("cannot open file\n");exit(0);}for(k=0;k<mfre;k++) {faxis=fs*(k-m2);fprintf(fp,"%f,%f\n",faxis,10.*log10(psdr[k]));}fclose(fp);return; }/*----------------------------------------------------------------------Routine mar1psd: To compute the power spectum by AR-model parameters.Input parameters:ip : AR model order (integer)ep : White noise variance of model input (real)ts : Sample interval in seconds (real)a : Complex array of AR parameters a(0) to a(ip)Output parameters:psdr : Real array of power spectral density valuespsdi : Real work arrayin chapter 12 ---------------------------------------------------------------------*/ void mar1psd(complex a[],int ip,int mfre,float *ep,float ts) {static float psdr[4096];static float psdi[4096];int k;float p;for(k=0;k<=ip;k++) {psdr[k]=a[k].real;psdi[k]=a[k].imag;}for(k=ip+1;k<mfre;k++) {psdr[k]=0.;psdi[k]=0.;}mrelfft(psdr,psdi,mfre,-1);for(k=0;k<mfre;k++) {p=pow(psdr[k],2)+pow(psdi[k],2);psdr[k]=(*ep)*ts/p;}mpsplot(psdr,psdi,mfre,ts);return; }/** Below are examples for using @maryuwa and @mar1psd*/ #define PI (3.1415926) #define N (1024) #define AN (10) complex x[N]; complex r[N]; complex a[AN];/** generate random number which satify guass distribution*/ double guass_rand(void) {static double V1, V2, S;static int phase = 0;double X;if ( phase == 0 ) {do {double U1 = (double)rand() / RAND_MAX;double U2 = (double)rand() / RAND_MAX;V1 = 2 * U1 - 1;V2 = 2 * U2 - 1;S = V1 * V1 + V2 * V2;} while(S >= 1 || S == 0);X = V1 * sqrt(-2 * log(S) / S);} else {X = V2 * sqrt(-2 * log(S) / S);}phase = 1 - phase;return X; }void zx_ar_model(void) {int i=0;float ep = 0;int ierror = 0;/** generate x[N]*/srand(time(NULL));for (i=0; i<N; i++) {x[i].real = sin(2*PI*i/N) + guass_rand();x[i].imag = 0;}/* Find parameters for AR model */maryuwa(x, a, r, N, AN, &ep, &ierror);/* Calculate power spectum using parameters of AR model */mar1psd(a, AN, N, &ep, 1); }
    [cpp] view plaincopy print?
  • /*?
  • ?*?main.c?
  • ?*?
  • ?*??Created?on:?2013-8-11?
  • ?*??????Author:?monkeyzx?
  • ?*/??
  • #include?"ar_model.h"??
  • ??
  • int?main(void)??
  • {??
  • ????zx_ar_model();??
  • ??
  • ????return?0;??
  • }??
  • /** main.c** Created on: 2013-8-11* Author: monkeyzx*/ #include "ar_model.h"int main(void) {zx_ar_model();return 0; }
    上面的實例中給定輸入信號為余弦信號,采樣點數(shù)為1024個點,通過計算后的功率譜通過mpsplot函數(shù)保存到文本文件output.txt中,保存格式如下:

    -0.500000,-15.334630
    -0.499023,-15.334833
    -0.498047,-15.335444
    -0.497070,-15.336456
    -0.496094,-15.337864
    -0.495117,-15.339655
    -0.494141,-15.341816
    -0.493164,-15.344331
    -0.492188,-15.347179
    -0.491211,-15.350342
    -0.490234,-15.353794
    -0.489258,-15.357505
    -0.488281,-15.361453
    -0.487305,-15.365603
    -0.486328,-15.369924
    -0.485352,-15.374381
    ......

    最后借助matlab讀取該文件,繪制出功率譜的圖形

    [plain] view plaincopy print?
  • data?=?load('output.txt');??
  • plot(data(:,1),data(:,2));??
  • data = load('output.txt'); plot(data(:,1),data(:,2));

    關于上面的C程序,這里只提與主題無關的,double guass_rand(void)是C語言中典型的生成高斯分布隨機數(shù)的發(fā)生器,這里用于在余弦函數(shù)上加上一個高斯的噪聲。關于更多的隨機數(shù)生成器可參考關于怎樣產(chǎn)生隨機數(shù)的徹底研究?[自行理解],我將該博文轉(zhuǎn)載過來,感謝作者。


    Refrences:

    [1] 胡廣書《數(shù)字信號處理——理論、算法與實現(xiàn) 第二版》

    [2] AR模型matlab相關函數(shù)描述http://blog.sina.com.cn/s/blog_62f573ad0100sfh1.html


    2015-06-01補充:

    更詳細,更正確,經(jīng)過驗證整理的代碼參考https://github.com/xiahouzuoxin/ar_model

    總結(jié)

    以上是生活随笔為你收集整理的AR模型在信号处理中的应用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。