循环谱的计算最大的特点就是复杂,在知网上,嵌入式系统上的快速循环谱计算的文章也非常多。不过在理论分析阶段,只要能加快仿真计算就够了。
标准的直接从时域信号计算循环自相关的公式为:
R
x
α
(
τ
)
=
lim
Δ
t
→
∞
2
Δ
t
∫
−
Δ
t
/
2
Δ
t
/
2
x
(
t
+
τ
/
2
)
x
∗
(
t
−
τ
/
2
)
e
−
j
2
π
α
t
d
t
R_{x}^{\alpha}(\tau)=\lim_{\Delta{t}\rightarrow\infty}\frac{2}{\Delta{t}} \int_{-\Delta{t}/2}^{\Delta{t}/2}x(t+\tau/2)x^*(t-\tau/2)e^{-j2\pi\alpha t}dt
Rxα(τ)=Δt→∞limΔt2∫−Δt/2Δt/2x(t+τ/2)x∗(t−τ/2)e−j2παtdt
其中
α
\alpha
α为循环频率。我们在计算机处理中,自然都要离散化,将
t
t
t与
n
n
n对应,
τ
\tau
τ与
m
m
m对应,上式就转变为
R
x
α
(
m
)
=
1
N
∑
n
=
0
N
−
1
x
(
n
+
m
)
x
∗
(
n
)
exp
(
−
j
2
π
α
n
)
exp
(
−
j
π
α
m
)
R_x^{\alpha}(m)=\frac{1}{N}\sum_{n=0}^{N-1}x(n+m)x^*(n)\exp(-j2\pi\alpha{n})\exp(-j\pi\alpha{m})
Rxα(m)=N1n=0∑N−1x(n+m)x∗(n)exp(−j2παn)exp(−jπαm)
而循环谱就是循环自相关的傅里叶变换,离散时可以用DFT:
S
x
α
(
k
)
=
DFT
[
R
x
α
(
m
)
]
S_x^{\alpha}(k)=\text{DFT}\left[R_x^{\alpha}(m)\right]
Sxα(k)=DFT[Rxα(m)]
这里最大的问题是要对信号求相关,浪费大量的时间。但时域相卷对应频域相乘,时域的相关也可以用DFT变成频域的逐点相乘。我们对第2式做DFT,可得:
S
x
α
(
k
)
=
1
N
∑
m
=
0
N
−
1
∑
n
=
0
N
−
1
x
(
n
+
m
)
x
∗
(
n
)
exp
(
−
j
2
π
α
n
)
exp
(
−
j
π
α
m
)
exp
(
−
j
2
π
k
m
N
)
S_x^{\alpha}(k)=\frac{1}{N}\sum_{m=0}^{N-1} \sum_{n=0}^{N-1}x(n+m)x^*(n)\exp(-j2\pi\alpha{n})\exp(-j\pi\alpha{m}) \exp(-j\frac{2\pi km}{N})
Sxα(k)=N1m=0∑N−1n=0∑N−1x(n+m)x∗(n)exp(−j2παn)exp(−jπαm)exp(−jN2πkm)
整理拆分得到:
S
x
α
(
k
)
=
1
N
[
∑
m
=
0
N
−
1
x
(
n
+
m
)
e
−
j
π
α
(
n
+
m
)
exp
(
−
j
2
π
k
(
m
+
n
)
N
)
]
[
∑
n
=
0
N
−
1
x
(
n
)
e
j
π
α
n
exp
(
−
j
2
π
k
n
N
)
]
∗
S_x^{\alpha}(k)=\frac{1}{N} \left[\sum_{m=0}^{N-1}x(n+m)e^{-j\pi\alpha(n+m)}\exp\left(-j\frac{2\pi k(m+n)}{N}\right)\right] \left[\sum_{n=0}^{N-1}x(n)e^{j\pi\alpha{n}}\exp\left(-j\frac{2\pi kn}{N}\right)\right]^*
Sxα(k)=N1[m=0∑N−1x(n+m)e−jπα(n+m)exp(−jN2πk(m+n))][n=0∑N−1x(n)ejπαnexp(−jN2πkn)]∗
只要
N
α
/
2
N\alpha/2
Nα/2为正数,就有
S
x
α
(
k
)
=
1
N
X
(
k
+
N
α
/
2
)
X
∗
(
k
−
N
α
/
2
)
S_x^{\alpha}(k)=\frac{1}{N}X(k+N\alpha/2)X^*(k-N\alpha/2)
Sxα(k)=N1X(k+Nα/2)X∗(k−Nα/2)
这样就可以很方便地直接从频域获得循环谱,相比自相关
O
(
n
2
)
O(n^2)
O(n2)的计算量,做FFT需要
O
(
n
log
(
n
)
)
O\left(n\log(n)\right)
O(nlog(n)),频域相乘只要
O
(
n
)
O(n)
O(n)。
代码挂在Github上:CyclicSpectrumPlot
在实现时,我在做FFT时多补一倍的零,使得 α / 2 \alpha/2 α/2可以更简便离散化计算。对应的,我的程序会引入更大的栅瓣。