假设你使用了DCT函数,然后不做数据的处理,使用逆变换;反转数据和转换前的数据不一样吗?为什么会出现浮点问题?是报告的问题还是正常的行为?

In [21]: a = [1.2, 3.4, 5.1, 2.3, 4.5]

In [22]: b = dct(a)

In [23]: b
Out[23]: array([ 33.        ,  -4.98384545,  -4.5       ,  -5.971707  ,   4.5       ])

In [24]: c = idct(b)

In [25]: c
Out[25]: array([ 12.,  34.,  51.,  23.,  45.])

有人能解释为什么吗?当然,一个简单的cc会起作用,但是如果重复函数的调用在几个维度上使用它,错误就会变大:
In [37]: a = np.random.rand(3,3,3)

In [38]: d = dct(dct(dct(a).transpose(0,2,1)).transpose(2,1,0)).transpose(2,1,0).transpose(0,2,1)

In [39]: e = idct(idct(idct(d).transpose(0,2,1)).transpose(2,1,0)).transpose(2,1,0).transpose(0,2,1)

In [40]: a
Out[40]:
array([[[ 0.48709809,  0.50624831,  0.91190972],
        [ 0.56545798,  0.85695062,  0.62484782],
        [ 0.96092354,  0.17453537,  0.17884233]],

       [[ 0.29433402,  0.08540074,  0.18574437],
        [ 0.09942075,  0.78902363,  0.62663572],
        [ 0.20372951,  0.67039551,  0.52292875]],

       [[ 0.79952289,  0.48221372,  0.43838685],
        [ 0.25559683,  0.39549153,  0.84129493],
        [ 0.69093533,  0.71522961,  0.16522915]]])

In [41]: e
Out[41]:
array([[[ 105.21318703,  109.34963575,  196.97249887],
        [ 122.13892469,  185.10133376,  134.96712825],
        [ 207.55948396,   37.69964085,   38.62994399]],

       [[  63.57614855,   18.44656009,   40.12078466],
        [  21.47488098,  170.42910452,  135.35331646],
        [  44.00557341,  144.80543099,  112.95260949]],

       [[ 172.69694529,  104.15816275,   94.69156014],
        [  55.20891593,   85.42617016,  181.71970442],
        [ 149.2420308 ,  154.48959477,   35.68949734]]])

这里是doc的链接。

最佳答案

看起来dct和idct在默认情况下不会正常化。定义dct以以下方式调用fftpack.dct。对idct执行同样的操作。

In [13]: dct = lambda x: fftpack.dct(x, norm='ortho')

In [14]: idct = lambda x: fftpack.idct(x, norm='ortho')

完成后,您将在执行转换后返回原始答案。
In [19]: import numpy

In [20]: a = numpy.random.rand(3,3,3)

In [21]: d = dct(dct(dct(a).transpose(0,2,1)).transpose(2,1,0)).transpose(2,1,0).transpose(0,2,1)

In [22]: e = idct(idct(idct(d).transpose(0,2,1)).transpose(2,1,0)).transpose(2,1,0).transpose(0,2,1)

In [23]: a
Out[23]:
array([[[ 0.51699637,  0.42946223,  0.89843545],
        [ 0.27853391,  0.8931508 ,  0.34319118],
        [ 0.51984431,  0.09217771,  0.78764716]],

       [[ 0.25019845,  0.92622331,  0.06111409],
        [ 0.81363641,  0.06093368,  0.13123373],
        [ 0.47268657,  0.39635091,  0.77978269]],

       [[ 0.86098829,  0.07901332,  0.82169182],
        [ 0.12560088,  0.78210188,  0.69805434],
        [ 0.33544628,  0.81540172,  0.9393219 ]]])

In [24]: e
Out[24]:
array([[[ 0.51699637,  0.42946223,  0.89843545],
        [ 0.27853391,  0.8931508 ,  0.34319118],
        [ 0.51984431,  0.09217771,  0.78764716]],

       [[ 0.25019845,  0.92622331,  0.06111409],
        [ 0.81363641,  0.06093368,  0.13123373],
        [ 0.47268657,  0.39635091,  0.77978269]],

       [[ 0.86098829,  0.07901332,  0.82169182],
        [ 0.12560088,  0.78210188,  0.69805434],
        [ 0.33544628,  0.81540172,  0.9393219 ]]])

我不知道为什么默认情况下没有选择标准化。但是,当使用ortho时,dctidct似乎都通过1/sqrt(2 * N)1/sqrt(4 * N)的因子进行了标准化。在有些应用中,dct和不idct需要标准化,反之亦然。

08-25 01:24