Scipy:生成 NxN 离散余弦矩阵

Pet*_*ter 3 python dct scipy

使用 scipy,是否有一种简单的方法来模拟 MATLABdctmtx函数的行为,该函数为某些给定的 N 返回 NxN DCT 矩阵?有scipy.fftpack.dctn但仅适用于 DCT。如果我不想使用除 scipy 之外的其他依赖项,我是否必须从头开始实现?

War*_*ser 7

DCT 是一种线性变换,因此获得变换矩阵的一种方法是将其应用于单位矩阵。这是我找到长度为 8 的序列的矩阵的示例(N一般情况下将 8 更改为):

In [124]: import numpy as np

In [125]: from scipy.fft import dct

In [126]: D = dct(np.eye(8), axis=0)
Run Code Online (Sandbox Code Playgroud)

D 是矩阵:

In [127]: D
Out[127]: 
array([[ 2.        ,  2.        ,  2.        ,  2.        ,  2.        ,  2.        ,  2.        ,  2.        ],
       [ 1.96157056,  1.66293922,  1.11114047,  0.39018064, -0.39018064, -1.11114047, -1.66293922, -1.96157056],
       [ 1.84775907,  0.76536686, -0.76536686, -1.84775907, -1.84775907, -0.76536686,  0.76536686,  1.84775907],
       [ 1.66293922, -0.39018064, -1.96157056, -1.11114047,  1.11114047,  1.96157056,  0.39018064, -1.66293922],
       [ 1.41421356, -1.41421356, -1.41421356,  1.41421356,  1.41421356, -1.41421356, -1.41421356,  1.41421356],
       [ 1.11114047, -1.96157056,  0.39018064,  1.66293922, -1.66293922, -0.39018064,  1.96157056, -1.11114047],
       [ 0.76536686, -1.84775907,  1.84775907, -0.76536686, -0.76536686,  1.84775907, -1.84775907,  0.76536686],
       [ 0.39018064, -1.11114047,  1.66293922, -1.96157056,  1.96157056, -1.66293922,  1.11114047, -0.39018064]])
Run Code Online (Sandbox Code Playgroud)

验证它D @ x等效于dct(x)

In [128]: x = np.array([1, 2, 0, -1, 3, 0, 1, -1])

In [129]: dct(x)
Out[129]: array([10.        ,  4.02535777, -1.39941754,  7.38025967, -1.41421356, -6.39104653, -7.07401092,  7.51550307])

In [130]: D @ x
Out[130]: array([10.        ,  4.02535777, -1.39941754,  7.38025967, -1.41421356, -6.39104653, -7.07401092,  7.51550307])
Run Code Online (Sandbox Code Playgroud)

请注意,D @ x通常会比dct(x).


要与 Matlab 的 完全一致dctmtx,请添加参数norm='ortho'。例如,这里是dctmtxOctave(它返回与 Matlab 中相同的数组):

octave:1> pkg load image
octave:2> dctmtx(4)
ans =

   0.50000   0.50000   0.50000   0.50000
   0.65328   0.27060  -0.27060  -0.65328
   0.50000  -0.50000  -0.50000   0.50000
   0.27060  -0.65328   0.65328  -0.27060
Run Code Online (Sandbox Code Playgroud)

这是使用的计算scipy.fft.dct

In [56]: from scipy.fft import dct

In [57]: dct(np.eye(4), axis=0, norm='ortho')
Out[57]: 
array([[ 0.5       ,  0.5       ,  0.5       ,  0.5       ],
       [ 0.65328148,  0.27059805, -0.27059805, -0.65328148],
       [ 0.5       , -0.5       , -0.5       ,  0.5       ],
       [ 0.27059805, -0.65328148,  0.65328148, -0.27059805]])
Run Code Online (Sandbox Code Playgroud)