DCT与DFT关系探究:为何DCT可以视为DFT的特例?

DCT与DFT关系探究:为何DCT可以视为DFT的特例?_58汽车

本文探讨了离散余弦变换(DCT)与离散傅里叶变换(DFT)之间的关系,通过延拓实数序列x并对其进行DFT变换,发现DCT的第一种形式可以视为延拓序列DFT变换结果的前N项。文章还详细推导了DCT公式,并解释了如何通过修改公式使DCT成为正交变换。通过scipy和MATLAB的代码验证,证明了推导的正确性,并展示了修改后的DCT与MATLAB中dct函数的一致性。

最近在理解DCT与DFT,正好写下来和大家一起分享,第一次写技术博客,不足之处还各位网友望批评指正。

在这里研究长度为N的一维实数序列x=left{x[0],x[1],…,x[N-1] ight},x[n]inmathbb{R}的DCT和DFT。

根据scipy的说明文档上对于DCT的描述,DCT有四种形式,本文我们讨论第一种形式。scipy对DCT的说明链接如下:

首先回顾一下离散傅里叶变换(DFT),公式如下:

egin{aligned}X[k]&=sum_{n=0}^{N-1}x[n]cdote^{-frac{i2pi}{N}kn}&=sum_{n=0}^{N-1}x[n]cdotleft[cosleft(frac{2pi}{N}kn ight)-icdotsinleft(frac{2pi}{N}kn ight) ight]end{aligned}

大家知道,一般的实数序列的傅里叶变换为复数,在序列为偶对称序列的情况下,其傅里叶变换为实数,好,我们现在对序列x进行延拓。令:

y=left[x_0,x_1,…,x_{N-2},x_{N-1},x_{N-2},…,x_2,x_1 ight]

y的长度记作M,M=2(N-1)。y中的元素除了x_0和x_{N-1}没有重复,其他所有的元素都对x_{N-1}呈镜像对称。很显然,序列y有如下特性:

y[m]=y[N-m]quadforquadm=0,1,2,…,M-1

举个例子:

输出结果为:

现在,我们对序列y进行离散傅里叶变换:

egin{aligned}Y[k]&=sum_{m=0}^{M-1}y[m]cdote^{-frac{i2pi}{M}km}&=sum_{m=0}^{M-1}y[m]cdotleft[cosleft(frac{2pi}{M}km ight)-icdotsinleft(frac{2pi}{M}km ight) ight]end{aligned}

对于没有镜像对称的两个元素y[0],y[frac{M}{2}],将他们单独写出来,方便化简。

对于m=0,有:cosleft(frac{2pi}{M}k*0 ight)=1,sinleft(frac{2pi}{M}k*0 ight)=0

对于m=frac{M}{2},有:cosleft(frac{2pi}{M}k*frac{M}{2} ight)=(-1)^k,sinleft(frac{2pi}{M}k*frac{M}{2} ight)=0

于是:

egin{aligned}Y[k]&=y[0]+(-1)^ky[frac{M}{2}]&+sum_{m=1}^{frac{M}{2}-1}y[m]cdotleft[cosleft(frac{2pi}{M}km ight)-icdotsinleft(frac{2pi}{M}km ight) ight]&+sum_{m=frac{M}{2}+1}^{M-1}y[m]cdotleft[cosleft(frac{2pi}{M}km ight)-icdotsinleft(frac{2pi}{M}km ight) ight]end{aligned} ag{1}

利用正弦余弦函数的性质:

egin{aligned}cosleft[frac{2pi}{M}k(M-m) ight]&=cosleft[2pik-frac{2pi}{M}km ight]=cosleft[frac{2pi}{M}km ight]sinleft[frac{2pi}{M}k(M-m) ight]&=sinleft[2pik-frac{2pi}{M}km ight]=-sinleft[frac{2pi}{M}km ight]end{aligned}

并根据序列y的对称性:

y[m]=y[N-m]quadforquadm=0,1,2,…,M-1

则(1)式的后两项的实部完全相等,虚部互为相反数,因此(1)式进一步化简为:

Y[k]=y[0]+(-1)^ky[frac{M}{2}]+2sum_{m=1}^{frac{M}{2}-1}y[m]cosleft(frac{2pikm}{M} ight) ag{2}

由于M=2(N-1),同时根据序列x与y之间的关系,有:

Y[k]=x[0]+(-1)^kx[N-1]+2sum_{n=1}^{N-2}x[n]cosleft(frac{pikn}{N-1} ight) ag{3}

公式(3)即为序列x的离散余弦变换。与scipy说明文档中,DCT的第一种表达式完全一致,见下图。

因此,我们得出结论,序列x的DCT和延拓序列y的DFT的前N位完全一致。dct(x)和fft(y)的长度必然不同,因此我们我们只看前N位。

最后需要说明的是,(3)式所表达的DCT不是正交变换,弱要进行正交变换,则要对(3)式进行简单的修改:

修改一:x[0]leftarrowsqrt{2}*x[0],quadx[N-1]leftarrowsqrt{2}*x[N-1]

修改二:Y[0]leftarrowfrac{Y[0]}{sqrt{2}},quadY[N-1]leftarrowfrac{Y[N-1]}{sqrt{2}}

修改三:Y[k]leftarrowY[k]*frac{1}{2}*sqrt{frac{2}{N-1}}

经过这三步修改,最终的DCT为正交变换。与MATLAB中dct函数的说明文档对比一下:

读者朋友们可以仔细对比一下,修改后的(3)式和MATLAB说明文档给出的公式是一致的。需要注意的是,MATLAB的数组索引是从1开始,而本文中的数组索引是从0开始。

首先看scipy的代码验证:

输出结果为:

然后看MATLAB的代码验证,MATLAB中的自带函数dct只有正交变换:

输出结果为:

可见,MATLAB和scipy的计算结果一致,且与我们的推导一致。

最后,可以验证修改后的dct是否是正交变换,验证x与dct(x)的模是否相等即可,在MATLAB命令行输入:

输出:

可见我们验证了修改后的dct为正交变换。

以上内容由58汽车提供。如有任何买车、用车、养车、玩车相关问题,欢迎在下方表单填写您的信息,我们将第一时间与您联系,为您提供快捷、实用、全面的解决方案。

原创文章,作者:58汽车,如若转载,请注明出处:https://car.58.com/7146433/