문제

Let say you use the dct function, then do no manipulation of the data and use the invert transform; wouldn't the inverted data be the same as the pre-transformed data? Why the floating point issue? Is it a reported issue or is it a normal behavior?

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.])

Anyone has an explanation as why? Of course, a simple c*10**-1 would do the trick, but if you repeat the call of the function to use it on several dimensions, the error gets bigger:

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]]])

Here a link to the doc.

도움이 되었습니까?

해결책

It looks like dct and idct do not normalize by default. define dct to call fftpack.dct in the following manner. Do the same for idct.

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

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

Once done, you will get back the original answers after performing the transforms.

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 ]]])

I am not sure why no normalization was chosen by default. But when using ortho, dct and idct each seem to normalize by a factor of 1/sqrt(2 * N) or 1/sqrt(4 * N). There may be applications where the normalization is needed for dct and not idct and vice versa.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top