Python实现相空间重构求关联维数——GP算法、自相关法求时间延迟tau、最近邻算法求嵌入维数m

Python实现相空间重构求关联维数——GP算法、自相关法求时间延迟tau、最近邻算法求嵌入维数m

GP算法:

若有一维时间序列为{x1,x2,…,xn},对其进行相空间重构得到高维相空间的一系列向量:

x i ( τ , m ) = ( x i , x i 1 , ⋯   , x i + ( m − 1 ) τ ) {x_i}(\tau ,m) = \left( {{x_i},{x_{i1}}, \cdots ,{x_{i + {{(m - 1)}_\tau }}}} \right) xi(τ,m)=(xi,xi1,,xi+(m1)τ)

式中: τ \tau τ为时间延迟, τ \tau τ=k Δ t {\rm{\Delta }}t Δt,其中k为整数,为采样时间间隔;m为嵌入维数;i=1,2,⋯,N;N为重构后向量的个数, N = n − ( m − 1 ) τ N = n - (m - 1)\tau N=n(m1)τ
重构相空间关联维数为:

D 2 = lim ⁡ r → 0 ln ⁡ c r ln ⁡ r {D_2} = \mathop {\lim }\limits_{r \to 0} \frac{{\ln {c_r}}}{{\ln r}} D2=r0limlnrlncr

c r = 1 N 2 {c_r} = \frac{1}{{{N^2}}} cr=N21 ∑ ∑ H \sum\sum H H ( r − ∣ ∣ x j − x k ∣ ∣ ) \left( {r - ||{x_j} - {x_k}||} \right) (rxjxk)

式中:j≠k;r为m维超球半径;H为Heaviside函数。

def GP(imf,tau):            #GP算法求关联维数
    N=2000
    if (len(imf) != N):
        print('请输入指定的数据长度!')   # N为指定数据长度
        return
    elif (isinstance(imf, np.ndarray) != True):
        print('数据格式错误!')
        return
    else:
        m_max=10                  #最大嵌入维数
        ss=50                     #r的步长
        fig=plt.figure()
        for m in range(1,m_max+1):
            i_num = N - (m - 1) * tau
            kj_m = np.zeros((i_num, m))  # m维重构相空间
            for i in range(i_num):
                for j in range(m):
                    kj_m[i][j] = imf[i + j * tau]
            dist_min, dist_max = np.linalg.norm(kj_m[0] - kj_m[1]), np.linalg.norm(kj_m[0] - kj_m[1])
            Dist_m = np.zeros((i_num, i_num))  # 两向量之间的距离
            for i in range(i_num):
                for k in range(i_num):
                    D= np.linalg.norm(kj_m[i] - kj_m[k])
                    if(D>dist_max):
                        dist_max=D
                    elif(D>0 and D<dist_min):
                        dist_min=D
                    Dist_m[i][k] = D
            dr=(dist_max-dist_min)/(ss-1)           #r的间距
            r_m=[]
            Cr_m=[]
            for r_index in range(ss):
                r=dist_min+r_index*dr
                r_m.append(r)
                Temp=np.heaviside(r-Dist_m,1)
                for i in range(i_num):
                    Temp[i][i]=0
                Cr_m.append(np.sum(Temp))
            r_m=np.log(np.array((r_m)))
            Cr_m=np.log(np.array((Cr_m))/(i_num*(i_num-1)))
            plt.plot(r_m,Cr_m)
        plt.show()

自相关法确定 τ \tau τ

计算时间序列{x1,x2,…,xn}的自相关函数:

R ( j τ ) = 1 N ∑ R(j\tau )= \frac{1}{{{N}}}\sum R(jτ)=N1 x ( i ) x ( i + j τ ) x(i)x(i + j\tau ) x(i)x(i+jτ)

当自相关函数值下降到初始函数值的1- e − 1 {{\rm{e}}^{ - 1}} e1时。所对应的 τ \tau τ即为时间延迟参数。

# 计算GP算法的时间延迟参数(自相关法)
def get_tau(imf):
    N=2000
    if (len(imf) != N):
        print('请输入指定的数据长度!')  # N为指定数据长度
        return 0
    elif (isinstance(imf, np.ndarray) != True):
        print('数据格式错误!')
        return 0
    else:
        j = 1  # j为固定值
        tau_max = 20
        Rall = np.zeros(tau_max)
        for tau in range(tau_max):
            R = 0
            for i in range(N - j * tau):
                R += imf[i] * imf[i + j * tau]
            Rall[tau] = R / (N - j * tau)
        for tau in range(tau_max):
            if Rall[tau] < (Rall[0] * 0.6321):
                break
        return tau

假近邻算法确定m

对m维相空间每一个向量 X i ( m ) = { x i , x i + τ , ⋯   , x i + ( m − 1 ) τ } {X_{i(m)}} = \left\{ {{x_i},{x_{i + \tau }}, \cdots ,{x_{i + (m - 1)\tau }}} \right\} Xi(m)={xi,xi+τ,,xi+(m1)τ},i=1,2,…,N,N为向量总数,找出它的最近向量 X j ( m ) X_{j(m)} Xj(m),计算两者欧氏距离 R m ( i ) = ∣ ∣ X i ( m ) − X j ( m ) ∣ ∣ {R_{m }}(i) = ||{X_{i(m)}} - {X_{j(m )}}|| Rm(i)=Xi(m)Xj(m),它们在m+1维空间的距离为:

R m + 1 ( i ) = ∣ ∣ X i ( m + 1 ) − X j ( m + 1 ) ∣ ∣ {R_{m + 1}}(i) = ||{X_{i(m + 1)}} - {X_{j(m + 1)}}|| Rm+1(i)=Xi(m+1)Xj(m+1)

如果 R m + 1 ( i ) {R_{m + 1}}(i) Rm+1(i)>> R m ( i ) {R_{m}}(i) Rm(i),则为虚假近邻点,定义比值:

R ( i ) = R(i)= R(i)= [ R m + 1 ( i ) ] 2 − [ R m ( i ) ] 2 [ R m ( i ) ] 2 \sqrt {\frac{{{{\left[ {{R_{m + 1}}(i)} \right]}^2} - {{\left[ {{R_m}(i)} \right]}^2}}}{{{{\left[ {{R_m}(i)} \right]}^2}}}} [Rm(i)]2[Rm+1(i)]2[Rm(i)]2

R ( i ) > R 0 R(i)>R_0 R(i)>R0,则称 X j X_j Xj X i X_i Xi的假近邻点, R 0 R_0 R0为阈值通常取大于10.计算该m下虚假近邻点占点比例,直到虚假近邻点百分比很小或不随m增大而减少时,此时的m即为所需嵌入维数。

#计算GP算法的嵌入维数(假近邻算法)
def get_m(imf, tau):
    N=2000
    if (len(imf) != N):
        print('请输入指定的数据长度!')  # N为指定数据长度
        return 0, 0
    elif (isinstance(imf, np.ndarray) != True):
        print('数据格式错误!')
        return 0, 0
    else:
        m_max = 10
        P_m_all = []  # m_max-1个假近邻点百分率
        for m in range(1, m_max + 1):
            i_num = N - (m - 1) * tau
            kj_m = np.zeros((i_num, m))  # m维重构相空间
            for i in range(i_num):
                for j in range(m):
                    kj_m[i][j] = imf[i + j * tau]
            if (m > 1):
                index = np.argsort(Dist_m)
                a_m = 0  # 最近邻点数
                for i in range(i_num):
                    temp = 0
                    for h in range(i_num):
                        temp = index[i][h]
                        if (Dist_m[i][temp] > 0):
                            break
                    D = np.linalg.norm(kj_m[i] - kj_m[temp])
                    D = np.sqrt((D * D) / (Dist_m[i][temp] * Dist_m[i][temp]) - 1)
                    if (D > 10):
                        a_m += 1
                P_m_all.append(a_m / i_num)
            i_num_m = i_num - tau
            Dist_m = np.zeros((i_num_m, i_num_m))  # 两向量之间的距离
            for i in range(i_num_m):
                for k in range(i_num_m):
                    Dist_m[i][k] = np.linalg.norm(kj_m[i] - kj_m[k])
        P_m_all = np.array(P_m_all)
        m_all = np.arange(1, m_max)
        return m_all, P_m_all

三连、三连、三连

Python实现相空间重构求关联维数——GP算法、自相关法求时间延迟tau、最近邻算法求嵌入维数m_第1张图片

完整测试代码如下:

import numpy as np
from scipy.fftpack import fft
from scipy import fftpack
import matplotlib.pyplot as plt

N_ft=2000         #时频域的点数

# 计算GP算法的时间延迟参数(自相关法)
def get_tau(imf):
    if (len(imf) != N_ft):
        print('请输入指定的数据长度!')  # 需要更改,比如弹出对话框
        return 0,0,0
    elif (isinstance(imf, np.ndarray) != True):
        print('数据格式错误!')
        return 0,0,0
    else:
        j = 1  # j为固定值
        tau_max = 20
        Rall = np.zeros(tau_max)
        for tau in range(tau_max):
            R = 0
            for i in range(N_ft - j * tau):
                R += imf[i] * imf[i + j * tau]
            Rall[tau] = R / (N_ft - j * tau)
        for tau in range(tau_max):
            if Rall[tau] < (Rall[0] * 0.6321):
                break
            tauall=np.arange(tau_max)
        return tauall,Rall,tau


# 计算GP算法的嵌入维数(假近邻算法)
def get_m(imf, tau):
    if (len(imf) != N_ft):
        print('请输入指定的数据长度!')  # 需要更改,比如弹出对话框
        return 0, 0
    elif (isinstance(imf, np.ndarray) != True):
        print('数据格式错误!')
        return 0, 0
    else:
        m_max = 10
        P_m_all = []  # m_max-1个假近邻点百分率
        for m in range(1, m_max + 1):
            i_num = N_ft - (m - 1) * tau
            kj_m = np.zeros((i_num, m))  # m维重构相空间
            for i in range(i_num):
                for j in range(m):
                    kj_m[i][j] = imf[i + j * tau]
            if (m > 1):
                index = np.argsort(Dist_m)
                a_m = 0  # 最近邻点数
                for i in range(i_num):
                    temp = 0
                    for h in range(i_num):
                        temp = index[i][h]
                        if (Dist_m[i][temp] > 0):
                            break
                    D = np.linalg.norm(kj_m[i] - kj_m[temp])
                    D = np.sqrt((D * D) / (Dist_m[i][temp] * Dist_m[i][temp]) - 1)
                    if (D > 10):
                        a_m += 1
                P_m_all.append(a_m / i_num)
            i_num_m = i_num - tau
            Dist_m = np.zeros((i_num_m, i_num_m))  # 两向量之间的距离
            for i in range(i_num_m):
                for k in range(i_num_m):
                    Dist_m[i][k] = np.linalg.norm(kj_m[i] - kj_m[k])
        P_m_all = np.array(P_m_all)
        m_all = np.arange(1, m_max)
        return m_all, P_m_all


# GP算法求关联维数(时频域特征)
def GP(imf, tau):
    if (len(imf) != N_ft):
        print('请输入指定的数据长度!')  # 需要更改,比如弹出对话框
        return
    elif (isinstance(imf, np.ndarray) != True):
        print('数据格式错误!')
        return
    else:
        m_max = 10  # 最大嵌入维数
        ss = 50  # r的步长
        fig = plt.figure(1)
        for m in range(1, m_max + 1):
            i_num = N_ft - (m - 1) * tau
            kj_m = np.zeros((i_num, m))  # m维重构相空间
            for i in range(i_num):
                for j in range(m):
                    kj_m[i][j] = imf[i + j * tau]
            dist_min, dist_max = np.linalg.norm(kj_m[0] - kj_m[1]), np.linalg.norm(kj_m[0] - kj_m[1])
            Dist_m = np.zeros((i_num, i_num))  # 两向量之间的距离
            for i in range(i_num):
                for k in range(i_num):
                    D = np.linalg.norm(kj_m[i] - kj_m[k])
                    if (D > dist_max):
                        dist_max = D
                    elif (D > 0 and D < dist_min):
                        dist_min = D
                    Dist_m[i][k] = D
            dr = (dist_max - dist_min) / (ss - 1)  # r的间距
            r_m = []
            Cr_m = []
            for r_index in range(ss):
                r = dist_min + r_index * dr
                r_m.append(r)
                Temp = np.heaviside(r - Dist_m, 1)
                for i in range(i_num):
                    Temp[i][i] = 0
                Cr_m.append(np.sum(Temp))
            r_m = np.log(np.array((r_m)))
            Cr_m = np.log(np.array((Cr_m)) / (i_num * (i_num - 1)))
            plt.plot(r_m, Cr_m)
        plt.xlabel('ln(r)')
        plt.ylabel('ln(C)')
        plt.show()

if __name__=='__main__':
    # 检验关联维数程序
    t = []
    f1 = 25
    f2 = 30
    for i in range(N_ft):
        t.append(i * 0.001)
    t = np.array(t)
    # yu = np.ones(M * N)
    AEall = np.sin(t * 2 * np.pi * f1) + np.sin(t * 2 * np.pi * f2)  #在这里直接改信号


    tauall, Rall, tau = get_tau(AEall)
    m, P = get_m(AEall, tau)
    GP(AEall, 1)
    print(tau)
    fig2 = plt.figure(2)
    yu = np.ones(len(tauall)) * Rall[0] * 0.6321
    plt.plot(tauall, Rall)
    plt.plot(tauall, yu)
    plt.xlabel('tau')
    plt.ylabel('R')
    plt.show()
    fig3 = plt.figure(3)
    plt.plot(m, P)
    plt.xlabel('m')
    plt.ylabel('P')
    plt.show()

你可能感兴趣的:(笔记,算法)