scipy.signal.windows.dpss

scipy.signal.windows.dpss(M, NW, Kmax=None, sym=True, norm=None, return_ratios=False)[源代码]

计算离散长球面序列(DPSS)。

DPS(或Slepian序列)通常用于多锥功率谱密度估计(请参见 [1]) 。序列中的第一个窗口可用于最大化主瓣中的能量集中,也称为Slepian窗口。

参数
M集成

窗口长度。

NW浮动

对应于以下各项的标准化半带宽 2*NW = BW/f0 = BW*M*dt 哪里 dt 被视为1。

Kmaxint|无,可选

要返回的DPSS窗口数(订单 0 通过 Kmax-1 )。如果为None(默认值),则仅返回单个形状窗口 (M,) 代替形状窗口阵列 (Kmax, M)

sym布尔值,可选

如果为True(默认值),则生成对称窗口,用于过滤设计。如果为False,则生成周期性窗口,用于频谱分析。

norm{2,‘近似’,‘子样本’}|无,可选

如果为‘近似’或‘子样本’,则按最大值对窗口进行归一化,并应用偶数长度窗口的校正比例因子 M**2/(M**2+NW) (“近似”)或基于FFT的子样本移位(“子样本”),详情请参阅“注释”。如果没有,则在以下情况下使用“近似” Kmax=None 另外2个(使用L2范数)。

return_ratios布尔值,可选

如果为True,则除返回窗口外,还返回浓度比率。

退货
vndarray,Shape(Kmax,M)或(M,)

DPSS窗口。将是1D,如果 Kmax 是没有的。

rndarray、Shape(Kmax)或Float,可选

窗口的浓度比。仅在以下情况下返回 return_ratios 计算结果为True。将为0D,如果 Kmax 是没有的。

注意事项

此计算使用中给出的三对角线特征向量公式 [2].

的默认规范化 Kmax=None 即窗口生成模式,简单地使用l-无穷大范数将创建具有两个单位值的窗口,这在偶数阶和奇数阶之间产生轻微的归一化差异。的近似修正 M**2/float(M**2+NW) 因为偶数样本数被用来抵消这种影响(参见下面的示例)。

对于非常长的信号(例如,1E6个元素),计算较短幅度的窗口并使用内插(例如, scipy.interpolate.interp1d )以获得一定长度的锥度 M ,但这通常不会保持锥体之间的正交性。

1.1 新版功能.

参考文献

1

华盛顿州瓦尔登市珀西瓦尔数据库物理应用的光谱分析:多纸和传统的单变量技术。剑桥大学出版社;1993年。

2

斯莱宾,D.扁球面波函数,傅立叶分析,以及不确定度V:离散情况。贝尔系统技术学报,第57卷(1978年),1371430。

3

Kaiser,JF,Schafer RW.I0-SINH窗在光谱分析中的应用IEEE声学、语音和信号处理汇刊。ASSP-28(1):105-107;1980年。

示例

我们可以把窗户比作 kaiser, which was invented as an alternative that was easier to calculate [3] (example adapted from here ):

>>> import numpy as np
>>> import matplotlib.pyplot as plt
>>> from scipy.signal import windows, freqz
>>> M = 51
>>> fig, axes = plt.subplots(3, 2, figsize=(5, 7))
>>> for ai, alpha in enumerate((1, 3, 5)):
...     win_dpss = windows.dpss(M, alpha)
...     beta = alpha*np.pi
...     win_kaiser = windows.kaiser(M, beta)
...     for win, c in ((win_dpss, 'k'), (win_kaiser, 'r')):
...         win /= win.sum()
...         axes[ai, 0].plot(win, color=c, lw=1.)
...         axes[ai, 0].set(xlim=[0, M-1], title=r'$\alpha$ = %s' % alpha,
...                         ylabel='Amplitude')
...         w, h = freqz(win)
...         axes[ai, 1].plot(w, 20 * np.log10(np.abs(h)), color=c, lw=1.)
...         axes[ai, 1].set(xlim=[0, np.pi],
...                         title=r'$\beta$ = %0.2f' % beta,
...                         ylabel='Magnitude (dB)')
>>> for ax in axes.ravel():
...     ax.grid(True)
>>> axes[2, 1].legend(['DPSS', 'Kaiser'])
>>> fig.tight_layout()
>>> plt.show()
../../_images/scipy-signal-windows-dpss-1_00_00.png

以下是前四个窗口的示例以及它们的集中率:

>>> M = 512
>>> NW = 2.5
>>> win, eigvals = windows.dpss(M, NW, 4, return_ratios=True)
>>> fig, ax = plt.subplots(1)
>>> ax.plot(win.T, linewidth=1.)
>>> ax.set(xlim=[0, M-1], ylim=[-0.1, 0.1], xlabel='Samples',
...        title='DPSS, M=%d, NW=%0.1f' % (M, NW))
>>> ax.legend(['win[%d] (%0.4f)' % (ii, ratio)
...            for ii, ratio in enumerate(eigvals)])
>>> fig.tight_layout()
>>> plt.show()
../../_images/scipy-signal-windows-dpss-1_01_00.png

使用标准 \(l_{{\infty}}\) 范数将为偶数产生两个统一值 M ,但奇数只有一个单位值 M 。这会产生可通过近似校正抵消的不均匀窗口功率 M**2/float(M**2+NW) ,可以使用以下命令选择 norm='approximate' (与 norm=None 什么时候 Kmax=None ,就像这里的情况一样)。或者,速度越慢 norm='subsample' 可以使用,它使用频域(FFT)中的子样本移位来计算校正:

>>> Ms = np.arange(1, 41)
>>> factors = (50, 20, 10, 5, 2.0001)
>>> energy = np.empty((3, len(Ms), len(factors)))
>>> for mi, M in enumerate(Ms):
...     for fi, factor in enumerate(factors):
...         NW = M / float(factor)
...         # Corrected using empirical approximation (default)
...         win = windows.dpss(M, NW)
...         energy[0, mi, fi] = np.sum(win ** 2) / np.sqrt(M)
...         # Corrected using subsample shifting
...         win = windows.dpss(M, NW, norm='subsample')
...         energy[1, mi, fi] = np.sum(win ** 2) / np.sqrt(M)
...         # Uncorrected (using l-infinity norm)
...         win /= win.max()
...         energy[2, mi, fi] = np.sum(win ** 2) / np.sqrt(M)
>>> fig, ax = plt.subplots(1)
>>> hs = ax.plot(Ms, energy[2], '-o', markersize=4,
...              markeredgecolor='none')
>>> leg = [hs[-1]]
>>> for hi, hh in enumerate(hs):
...     h1 = ax.plot(Ms, energy[0, :, hi], '-o', markersize=4,
...                  color=hh.get_color(), markeredgecolor='none',
...                  alpha=0.66)
...     h2 = ax.plot(Ms, energy[1, :, hi], '-o', markersize=4,
...                  color=hh.get_color(), markeredgecolor='none',
...                  alpha=0.33)
...     if hi == len(hs) - 1:
...         leg.insert(0, h1[0])
...         leg.insert(0, h2[0])
>>> ax.set(xlabel='M (samples)', ylabel=r'Power / $\sqrt{M}$')
>>> ax.legend(leg, ['Uncorrected', r'Corrected: $\frac{M^2}{M^2+NW}$',
...                 'Corrected (subsample)'])
>>> fig.tight_layout()
../../_images/scipy-signal-windows-dpss-1_02_00.png