簡體   English   中英

Scipy的fftpack dct和idct

[英]Scipy's fftpack dct and idct

假設您使用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.])

任何人都有解釋為什么? 當然,一個簡單的c*10**-1可以解決問題,但是如果你重復調用函數在幾個維度上使用它,那么錯誤就會變大:

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做同樣的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 ]]])

我不確定為什么默認情況下沒有選擇規范化。 但是當使用orthodctidct每個似乎都會以1/sqrt(2 * N)1/sqrt(4 * N)的系數歸一化。 可能存在dct而不是idct需要規范化的應用程序,反之亦然。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM