问题描述
我们在手写DCT离散余弦函数的时候,算出来的值总是与scipy库里面的DCT函数不一样,结果和代码如下所示:
## 这是自己写的dct离散余弦函数
## n代表阶数,0 < n <= 数据长度
## s代表数据,一般是一维
## num是s数据的长度
def dct_test(n,s,num):# n代表阶数>=1,s代表每一帧的滤波器组,维度是(128,),num是滤波器的个数
result=[]
for i in range(num):
tem=math.cos((math.pi*n*(i+0.5))/(num))
result.append(s[i]*tem)
return 2*np.sum(result)
## 这是库函数里面的dct函数
import numpy as np
from scipy import fftpack
from scipy.fftpack import dct, idct
x2 = np.array([-29.31844288,-27.1852446,-9.3301039, 6.6906352,3.85852898,-7.66088315,-9.4338189,-6.94219835,1.32766129,2.97283554])
y2 = dct(x2)
print('离散余弦变换:\n', y2)
原因分析:
因为scipy库里面的函数内部公式是不一样的,这个dct函数一共有8种模式,每一种模式算出来的结果是不一样。但是一般默认为第二种模式,在这里我将详细介绍1,2种模式,其他的模式可以看这个库函数的手册。
解决方案:
我们只要弄清楚dct函数里面不同模式下的不同函数公式就可以了,现在介绍dct函数下的1,2种模式
#dct函数的内部参数
dct(x, type=2, n=None, axis=-1, norm=None, overwrite_x=False)
x:array_like
输入数组。
类型:{1、2、3、4},可选
DCT 的类型(见注释)。默认类型为 2。
n:整数,可选
变换的长度。如果 ``n < x.shape[axis]``,则 `x` 是
截断。如果 ``n > x.shape[axis]``,则 `x` 是零填充的。这
默认结果为“n = x.shape[axis]”。
轴:int,可选
计算 dct 的轴;默认结束
最后一个轴(即“axis=-1”)。
norm : {None, 'ortho'}, 可选
标准化模式(见注释)。默认为无。
overwrite_x : bool,可选
如果为 True,则可以销毁 `x` 的内容;默认为假。
退货
--------
y :实数的ndarray
转换后的输入数组。
模式一的公式:如果norm=‘ortho’,则需要乘以下面的缩放因子
y k = x 0 + ( − 1 ) k x N − 1 + 2 ∑ n = 1 N − 2 x n cos ( π k n N − 1 ) y_k = x_0 + (-1)^k x_{N-1} + 2 \sum_{n=1}^{N-2} x_n \cos\left( \frac{\pi k n}{N-1} \right) yk=x0+(−1)kxN−1+2n=1∑N−2xncos(N−1πkn)
x f = { 1 2 1 N − 1 if k = 0 or N − 1 , 1 2 2 N − 1 otherwise xf = \begin{cases} \frac{1}{2}\sqrt{\frac{1}{N-1}} & \text{if }k=0\text{ or }N-1, \\ \frac{1}{2}\sqrt{\frac{2}{N-1}} & \text{otherwise} \end{cases} xf=⎩⎨⎧21N−1121N−12if k=0 or N−1,otherwise
模式二的公式:如果norm=‘ortho’,则需要乘以下面的缩放因子
y k = 2 ∑ n = 0 N − 1 x n cos ( π k ( 2 n + 1 ) 2 N ) y_k = 2 \sum_{n=0}^{N-1} x_n \cos\left(\frac{\pi k(2n+1)}{2N} \right) yk=2n=0∑N−1xncos(2Nπk(2n+1))
f = { 1 4 N if k = 0 , 1 2 N otherwise f = \begin{cases} \sqrt{\frac{1}{4N}} & \text{if }k=0, \\ \sqrt{\frac{1}{2N}} & \text{otherwise} \end{cases} f=⎩⎨⎧4N12N1if k=0,otherwise
以上就是问题的解决方案了,如果还有不明白的的友友可以点个关注,私信我哟!