10-09:課程小結(jié)-迭代收斂理論零院、自先關(guān)和功率譜估計(jì)

連著三天8:00上課,我真的是痩不了了呀村刨。

一告抄、迭代法收斂理論

1.結(jié)論:對(duì)角占優(yōu)(對(duì)角線元素大)似乎比較有利于收斂,且GS法收斂的更快嵌牺!

代碼驗(yàn)證一下打洼,用一個(gè)已知可以求解的例子,分別用雅克比和高斯賽德?tīng)柗椒ǖ蠼饽娲狻A钇鋵?duì)角元素逐漸增大募疮,繪制其迭代次數(shù)隨增大數(shù)值的變化曲線。

def Jocobi(A,b,initial,delta,isPrint=False):
    '''
    @author:zengwei
    輸入:A是系數(shù)矩陣僻弹,N階方陣
          b是N*1列向量
          initial是解的初始值阿浓,N*1大小
          delta是我給定的迭代值與真實(shí)值之間的誤差
    輸出:迭代后的求解結(jié)果
    '''
    D = np.diag(np.diag(A))             # 獲得D矩陣
    L = -np.tril(A,-1)                  # 獲得L矩陣
    U = -np.triu(A,1)                   # 獲得U矩陣
    try:
        d = np.linalg.inv(D)            # 對(duì)D矩陣求逆
    
        BJ = np.dot(d,L+U)              # 迭代矩陣BJ
        lamda,_ = np.linalg.eig(BJ)
        if np.max(np.abs(lamda))<1:     # 譜半徑小于1
            f = np.dot(d,b)
            X = np.dot(BJ,initial)+f    # 初次的解
            k = -np.log(delta)/-np.log(np.max(np.abs(lamda)))
            
            BJnorm = np.linalg.norm(BJ)
            times = 1                   # 因?yàn)榍懊嬗辛艘淮蔚?            while (BJnorm**k/(1-BJnorm))*np.linalg.norm(X - initial)> delta:
                initial = X
                X = np.dot(BJ,initial) + f
                times = times +1
            if isPrint==True:
                print('譜半徑為:',np.max(np.abs(lamda)))
                print('理論上的最大迭代次數(shù)為:%d次' %(int(k)+1))
                print("實(shí)際上的最大迭代次數(shù)為:%d次" %times)
            return X,times
        else:
            print('Sorry,不可收斂。')
            print('譜半徑為:',np.max(np.abs(lamda)))
    except:
        print('對(duì)角矩陣D沒(méi)有逆矩陣蹋绽!')
def Seidel(A,b,initial,delta,isPrint=False):
    '''
    @author:zengwei
    輸入:A是系數(shù)矩陣搔扁,N階方陣
          b是N*1列向量
          initial是解的初始值,N*1大小
          delta是我給定的迭代值與真實(shí)值之間的誤差
    輸出:迭代后的求解結(jié)果
    '''
    D = np.diag(np.diag(A)) 
    L = -np.tril(A,-1)
    U = -np.triu(A,1)
    try:
        d = np.linalg.inv( D - L )           # 這里是和雅克比不同的地方

        BG = np.dot(d,U)                     # 迭代矩陣BG
        lamda,_ = np.linalg.eig(BG)
        if np.max(np.abs(lamda))<1:          # 譜半徑小于1
            f = np.dot(d,b)
            X = np.dot( BG ,initial ) + f
            k = -np.log(delta)/-np.log(np.max(np.abs(lamda)))
            
            BGnorm = np.linalg.norm(BG)
            times = 1                        # 因?yàn)榍懊嬗辛艘淮蔚?            while (BGnorm**k/(1-BGnorm))*np.linalg.norm( X - initial ) > delta:
                initial = X
                X = np.dot( BG,initial )+f  
                times = times +1
            if isPrint==True:
                print('譜半徑為:',np.max(np.abs(lamda)))
                print('理論上的最大迭代次數(shù)為:%d次' %(int(k)+1))
                print("實(shí)際上的最大迭代次數(shù)為:%d次" %times)
            return X,times
        else:
            print('Sorry,不可收斂蟋字。')
            print('譜半徑為:',np.max(np.abs(lamda)))
    except:
        print('矩陣[D-L]沒(méi)有逆矩陣稿蹲!')
A = np.array([[8,-3,2],[4,11,-1],[6,3,12]],dtype=float)
b = np.array([[20],[33],[36]],dtype=float)
initial = np.zeros((3,1))
delta = 10**(-5)
Jocobi(A,b,initial,delta,isPrint=True)
'''
譜半徑為: 0.35924985028455664
理論上的最大迭代次數(shù)為:12次
實(shí)際上的最大迭代次數(shù)為:13次
array([[2.99999933],
       [2.00000577],
       [1.00000419]])
'''
Seidel(A,b,initial,delta,isPrint=True)
'''
譜半徑為: 0.13055824196677338
理論上的最大迭代次數(shù)為:6次
實(shí)際上的最大迭代次數(shù)為:7次
array([[3.00000201],
       [1.9999987 ],
       [0.99999932]])
'''
def addII(A,s):
    A = A.copy()
    for i in np.arange(len(A)):
        A[i,i] = A[i,i] + s
    return A

def getTimeslist(N,S,JorGs):
    '''
    增加N次,每次增加s大小,JorGs做算法選擇
    '''
    timeslist = []
    n = np.arange(S,N*S+S,S)
    for s in n:
        newA = addII(A,s)
        if JorGs=='Jocobi':
            _,times = Jocobi(newA,b,initial,delta)
        if JorGs=='Seidel':
            _,times = Seidel(newA,b,initial,delta)
        timeslist.append(times)
    timeslist = np.array(timeslist)
    return n,timeslist

N = 50
S = 5
n1,Jtimeslist = getTimeslist(N,S,'Jocobi')
n2,GStimeslist = getTimeslist(N,S,'Seidel')
plt.figure(figsize=(12,5))
plt.scatter(n1,Jtimeslist)
plt.plot(n1,Jtimeslist)
plt.scatter(n2,GStimeslist)
plt.plot(n2,GStimeslist)
plt.title('對(duì)角元素加%d的迭代次數(shù)變化圖'%S)
plt.legend(['Jocobi','Seidel'])
plt.xlabel('對(duì)角元素每次加%d'%S)
plt.ylabel('迭代次數(shù)')
plt.savefig('result.png')
plt.show()
迭代速度對(duì)比圖.png

從測(cè)試來(lái)看鹊奖,結(jié)論得以驗(yàn)證苛聘。

2.用迭代法計(jì)算希爾伯特矩陣

生成希爾伯特矩陣:

def Hilbert(N):
   return 1. / (np.arange(1, N+1) + np.arange(0, N)[:, np.newaxis])

生成一個(gè)6階的希爾伯特矩陣,并且解均為1忠聚。
當(dāng)我用雅克比迭代法進(jìn)行計(jì)算時(shí)设哗,會(huì)顯示不可收斂,因?yàn)樽V半徑大于1了两蟀。當(dāng)用高斯賽德?tīng)柕〞r(shí)网梢,會(huì)出現(xiàn)第一次迭代的結(jié)果。我注意到這時(shí)q^k/(1-q)*||x^{(k+1)}-x^{(k)}||這個(gè)值會(huì)變得很大赂毯,且理論上的最大迭代次數(shù)k=-ln\epsilon/-ln(\rho(B))也變得很大战虏。因?yàn)榧鹪祝瑢?xiě)SOR函數(shù)時(shí)先不用這些收斂條件,先粗糙地設(shè)置最大迭代次數(shù)烦感,同時(shí)參考書(shū)后發(fā)現(xiàn)SOR對(duì)對(duì)稱正定的三對(duì)角矩陣能取到最優(yōu)的松弛因子\omega巡社。一個(gè)不太成熟的SOR代碼:

def SOR(A,b,initial,delta,w,maxTimes,isw=False):
    '''
    @author:zengwei
    輸入:A是系數(shù)矩陣,N階方陣
          b是N*1列向量
          initial是解的初始值手趣,N*1大小
          delta是我給定的迭代值與真實(shí)值之間的誤差
          w:松弛因子
          isw:對(duì)于對(duì)稱正定的三對(duì)角矩陣可以求最優(yōu)的w
    輸出:迭代后的求解結(jié)果
    '''
    D = np.diag(np.diag(A)) 
    L = -np.tril(A,-1)
    U = -np.triu(A,1)
    
    if isw==True:
        BJ = np.dot(np.linalg.inv(D),L+U)
        lamdaBJ,_ = np.linalg.eig(BJ)
        rouBJ = np.max(np.abs(lamdaBJ))
        w = 2./(1+np.sqrt(1-rouBJ**2))
    try:
        d = np.linalg.inv(D - w*L)
        Bw = np.dot(d,(1-w)*D+w*U)          # 迭代矩陣Bw
        lamda,_ = np.linalg.eig(Bw)
        print('譜半徑為:',np.max(np.abs(lamda)))
        if np.max(np.abs(lamda))<1: 
            f = np.dot(d,w*b)
            X = np.dot( Bw ,initial ) + f
            for i in np.arange(maxTimes):
                initial = X
                X = np.dot( Bw,initial )+f  
            return X
        else:
            print('Sorry,不可收斂晌该。')
            print('譜半徑為:',np.max(np.abs(lamda)))
    except:
        print('矩陣[D-wL]沒(méi)有逆矩陣!')

我用SOR迭代法計(jì)算上述6階希爾伯特矩陣時(shí)可以得到結(jié)果绿渣,并分別試了松弛因子為1.0,1.25,1.5時(shí)得到的結(jié)果朝群。我沒(méi)法用肉眼分辨哪個(gè)結(jié)果更好,因?yàn)槲沂褂玫蹬c真實(shí)值的均方誤差來(lái)進(jìn)行比較中符。

N = 6
A = Hilbert(N)
x = np.ones((N,1))
b = np.dot(A,x)
initial = np.zeros((N,1))
delta = 10**(-5)

def MES(y,yTrue):
    return np.sum([i**2 for i in (y-yTrue)])/len(y)

yTrue = 1
print('w=1時(shí)潜圃,數(shù)值解與真實(shí)值之間的均方誤差為:',MES(SOR(A,b,initial,delta,1,100),yTrue))
print('w=1.25時(shí),數(shù)值解與真實(shí)值之間的均方誤差為:',MES(SOR(A,b,initial,delta,1.25,100),yTrue))
print('w=1.5時(shí)舟茶,數(shù)值解與真實(shí)值之間的均方誤差為:',MES(SOR(A,b,initial,delta,1.5,100),yTrue))
'''
w=1時(shí),數(shù)值解與真實(shí)值之間的均方誤差為: 0.012836171242905989
w=1.25時(shí)堵第,數(shù)值解與真實(shí)值之間的均方誤差為: 0.02127700958940544
w=1.5時(shí)吧凉,數(shù)值解與真實(shí)值之間的均方誤差為: 0.03818250349102156
'''

二、自相關(guān)

自相關(guān)在工程上有非常多的應(yīng)用踏志,典型應(yīng)用是從隨機(jī)信號(hào)中找出周期信號(hào)阀捅。噪聲的自相關(guān)會(huì)在0時(shí)刻取到最大值,隨后衰減到0针余。
參考《數(shù)字信號(hào)處理》(胡廣書(shū))編寫(xiě)自相關(guān)函數(shù)有兩種思路:一種是按照定義計(jì)算饲鄙,可以轉(zhuǎn)換為矩陣運(yùn)算;另一種是先補(bǔ)N個(gè)0圆雁,再做FFT忍级,然后對(duì)N分之一幅度平方做IFFT。代碼如下:

def myAutocorrelation(SigA):
    '''
    @author:zengwei
    自相關(guān)函數(shù),屬于有偏估計(jì)伪朽,對(duì)應(yīng)matlab的xcorr(SigA,'biased')
    https://ww2.mathworks.cn/help/matlab/ref/xcorr.html
    '''
    N = len(SigA)
    SigB = np.zeros(2*N-1)
    SigB[0:N] = SigA
    L = len(SigB)
    
    SigC = np.array(SigB.tolist()*(L+1))
    Matrix = np.zeros((L,L))
    start = N-1
    for i in np.arange(L):
        end = start + L               # 還可以用np.roll()函數(shù)
        Matrix[i,:] = SigC[start:end]
        start = end - 1
    return np.dot(Matrix,SigB)/N
def selfAutocorrelation(signal):
    N = len(signal)
    signal2N = np.hstack((signal,np.zeros(N)))
    X = np.fft.fft(signal2N)
    x = (np.abs(X)**2)/(N)
    rm = np.fft.ifft(x)
    return np.roll(rm,N-1)[0:-1]

得到的結(jié)果與matlab中的xcorr(SigA,'biased')結(jié)果一致轴咱,但看到更多情況下用xcorr(SigA,'unbiased')。matlab說(shuō)明文檔詳細(xì)說(shuō)明了其中的區(qū)別:https://ww2.mathworks.cn/help/matlab/ref/xcorr.html 烈涮。

Fs = 500
n = np.arange(0,1,1/Fs)
noise = np.random.randn(len(n))     
x =  2*np.cos(2*np.pi*5*n)+noise
cor = myAutocorrelation(x)

plt.figure(figsize=(12,5))
plt.subplot(211)
plt.title('輸入信號(hào)')
plt.plot(n,x)
plt.subplot(212)
plt.plot(cor)
plt.title('自相關(guān)結(jié)果')
plt.savefig('自相關(guān).png')
plt.show()

自相關(guān)示例.png

對(duì)于如何利用自相關(guān)結(jié)果找周期信號(hào)伶授,可以參見(jiàn)matlab說(shuō)明文檔進(jìn)一步了解:https://ww2.mathworks.cn/help/signal/ug/find-periodicity-using-autocorrelation.html

三谁鳍、自相關(guān)法求功率譜估計(jì)

用Python做功率譜估計(jì)感覺(jué)怪怪的,因?yàn)閙atlab有現(xiàn)成的函數(shù)做各種功率譜估計(jì)。我這里用信號(hào)自相關(guān)函數(shù)的FFT變換做為功率譜估計(jì)阵苇。如下所示:

# 生成原始輸入信號(hào)
fs = 1000
t = np.arange(0, 1, 1/fs)
f = 100
x = 2*np.cos(2*np.pi*f*t) + np.random.randn(t.size)

# 自相關(guān)法功率譜估計(jì)
num_fft = 1024
cor_x = myAutocorrelation(x)
cor_X = np.fft.fft(cor_x, num_fft)
P_BT = np.abs(cor_X)

plt.figure(figsize=(12, 8))
ax=plt.subplot(311)
ax.set_title('輸入信號(hào)')
plt.tight_layout()
plt.plot(x)

ax=plt.subplot(312)
ax.set_title('自相關(guān)法功率譜估計(jì)P_BT')
plt.plot(P_BT[:num_fft//2])
plt.tight_layout()

ax=plt.subplot(313)
ax.set_title('自相關(guān)法功率譜估計(jì)20*log10(P_BT)')
plt.plot(20*np.log10(P_BT[:num_fft//2]))
plt.tight_layout()
plt.savefig('P_BT.png')
plt.show()
自相關(guān)功率譜估計(jì).png

接下來(lái)試試對(duì)自相關(guān)函數(shù)加窗函數(shù),其余操作不變灯抛,并且窗函數(shù)加在自相關(guān)函數(shù)整個(gè)上面妇押。然后看看有啥變化需了。

def Hamming(N):
    return np.array([0.54 - 0.46 * np.cos(2 * np.pi * n / (N - 1)) for n in range(N)])
def Hanning(N):
    return np.array([0.5 - 0.5 * np.cos(2 * np.pi * n / (N - 1)) for n in range(N)])
def Rect(N):
    return np.ones(N)
自相關(guān)功率譜估計(jì)加窗.png

放在一副圖上比較.png

不加窗,加矩形窗橡疼,加漢明窗援所,加漢寧窗,其方差分別為:579.6754欣除,579.6754住拭,422.8173,413.1546历帚。感官上滔岳,有一丟丟改善。應(yīng)該比不上分段加窗強(qiáng)挽牢。

四谱煤、直接法功率譜估計(jì)的平滑改進(jìn)

【10月12日批注】我這里分段時(shí)沒(méi)有考慮到頻率分辨率的問(wèn)題,可以移步下一篇

依舊對(duì)上述相同的信號(hào)進(jìn)行處理禽拔。

1.Bartlett法

def Bartlett(signal,L,num_fft):
    M = len(signal)//L
    signal = signal.reshape(L,M)
    P_BT = []
    for i in signal:
        cor_I = np.fft.fft(i,num_fft)
        P_BTi = np.abs(cor_I)**2/M
        P_BT.append(P_BTi.tolist())
    P_BT = np.sum(np.array(P_BT),axis=0)/L
    return np.abs(P_BT)
BP_BT = Bartlett(x,100,1024)
plt.figure(figsize=(15,5))
plt.title('Bartlett平滑')
plt.plot(np.log10(BP_BT[:num_fft//2]))
plt.savefig('Bartlett.png')
plt.show()
Bartlett.png

2.Welch法

這里用的是漢寧窗刘离。

def Welch(sig,M,num_fft):
    L = int((len(sig)-M/2)//(M/2))
    signal = np.zeros((L,M))
    for m in np.arange(L):
        signal[m,:] = x[int(m/2):int(m/2)+M]
    
    d2 = Hanning(M)
    U = np.sum(d2**2)/M
    
    P_BT = []
    for i in signal:
        cor_I = np.fft.fft(i*d2,num_fft)
        P_BTi = np.abs(cor_I)**2/(M*U)
        P_BT.append(P_BTi.tolist())
    P_BT = np.sum(np.array(P_BT),axis=0)/L
    return np.abs(P_BT)
WP_BT = Welch(x,10,1024)
plt.figure(figsize=(15,5))
plt.title('Welch平滑')
plt.plot(np.log10(WP_BT[:num_fft//2]))
plt.savefig('Welch.png')
plt.show()
Welch.png

感覺(jué)可能有錯(cuò)誤的地方。明天繼續(xù)......

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末睹栖,一起剝皮案震驚了整個(gè)濱河市硫惕,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌野来,老刑警劉巖恼除,帶你破解...
    沈念sama閱讀 218,284評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異曼氛,居然都是意外死亡豁辉,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)舀患,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)徽级,“玉大人,你說(shuō)我怎么就攤上這事聊浅』易罚” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,614評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵狗超,是天一觀的道長(zhǎng)弹澎。 經(jīng)常有香客問(wèn)我,道長(zhǎng)努咐,這世上最難降的妖魔是什么苦蒿? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,671評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮渗稍,結(jié)果婚禮上佩迟,老公的妹妹穿的比我還像新娘团滥。我一直安慰自己,他們只是感情好报强,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,699評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布灸姊。 她就那樣靜靜地躺著,像睡著了一般秉溉。 火紅的嫁衣襯著肌膚如雪力惯。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,562評(píng)論 1 305
  • 那天召嘶,我揣著相機(jī)與錄音父晶,去河邊找鬼。 笑死弄跌,一個(gè)胖子當(dāng)著我的面吹牛甲喝,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播铛只,決...
    沈念sama閱讀 40,309評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼埠胖,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了淳玩?” 一聲冷哼從身側(cè)響起直撤,我...
    開(kāi)封第一講書(shū)人閱讀 39,223評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎凯肋,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體汽馋,經(jīng)...
    沈念sama閱讀 45,668評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡侮东,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,859評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了豹芯。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片悄雅。...
    茶點(diǎn)故事閱讀 39,981評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖铁蹈,靈堂內(nèi)的尸體忽然破棺而出宽闲,到底是詐尸還是另有隱情,我是刑警寧澤握牧,帶...
    沈念sama閱讀 35,705評(píng)論 5 347
  • 正文 年R本政府宣布容诬,位于F島的核電站,受9級(jí)特大地震影響沿腰,放射性物質(zhì)發(fā)生泄漏览徒。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,310評(píng)論 3 330
  • 文/蒙蒙 一颂龙、第九天 我趴在偏房一處隱蔽的房頂上張望习蓬。 院中可真熱鬧纽什,春花似錦、人聲如沸躲叼。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,904評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)枫慷。三九已至让蕾,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間流礁,已是汗流浹背涕俗。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,023評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留神帅,地道東北人再姑。 一個(gè)月前我還...
    沈念sama閱讀 48,146評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像找御,于是被迫代替她去往敵國(guó)和親元镀。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,933評(píng)論 2 355