小波变换的两个不同值(Daubechies D4)

Two different value for the Wavelet Transform (Daubechies D4)

我正在测试this code

   protected final double sqrt_3 = Math.sqrt( 3 );
   protected final double denom = 4 * Math.sqrt( 2 );
   //
   // forward transform scaling (smoothing) coefficients
   //
   protected final double h0 = (1 + sqrt_3)/denom;
   protected final double h1 = (3 + sqrt_3)/denom; 
   protected final double h2 = (3 - sqrt_3)/denom; 
   protected final double h3 = (1 - sqrt_3)/denom;
   //
   // forward transform wavelet coefficients
   //
   protected final double g0 =  h3;
   protected final double g1 = -h2;
   protected final double g2 =  h1;
   protected final double g3 = -h0;

protected void transform( double a[], int n )
{
  if (n >= 4) {
     int i, j;
     int half = n >> 1;

 double tmp[] = new double[n];

 i = 0;
     for (j = 0; j < n-3; j = j + 2) {
        tmp[i]      = a[j]*h0 + a[j+1]*h1 + a[j+2]*h2 + a[j+3]*h3;
        tmp[i+half] = a[j]*g0 + a[j+1]*g1 + a[j+2]*g2 + a[j+3]*g3;
    i++;
     }

     tmp[i]      = a[n-2]*h0 + a[n-1]*h1 + a[0]*h2 + a[1]*h3;
     tmp[i+half] = a[n-2]*g0 + a[n-1]*g1 + a[0]*g2 + a[1]*g3;

     for (i = 0; i < n; i++) {
        a[i] = tmp[i];
     }
  }
 } // transform

在此离散数组上执行 Daubechies D4 小波变换:

[1,2,0,4,5,6,8,10]

结果是

  - 0 : 1.638357430415108
  - 1 : 3.6903274198537357
  - 2 : -2.6439375651698196
  - 3 : 79.01146993331695
  - 4 : 7.399237211089009
  - 5 : 0.3882285676537802
  - 6 : -39.6029588778518
  - 7 : -19.794010741818195
  - 8 : -2.1213203435596424
  - 9 : 0.0

但是当我在同一个数组上使用 python pywt.dwt 时,我得到这个:

import pywt
[cA, cD] = pywt.dwt([1,2,0,4,5,6,8,10], 'db4')


>>> >>> cA
array([ 7.14848277,  1.98754736,  1.9747116 ,  0.95510018,  4.90207373,
        8.72887094, 14.23995582])
>>> cD
array([-0.5373913 , -2.00492859,  0.01927609,  0.1615668 , -0.0823509 ,
       -0.32289939,  0.92816281])

除了不同的值,一个有 10 个项目,另一个有 7 个。

我错过了什么?

我从来没有使用过这些代码中的任何一个,也不太确定你的问题!但是,也许这些信息可以帮助您更接近问题的答案:

Daubechies 4 Wiki

Daubechies 系数 Wiki

  • 在此之前,我认为您的输入向量(信号)可能太小而无法进行小波计算,对吗?虽然不确定!也许,尝试 1x128 尺寸的东西。

  • 也许,Java代码是快速小波变换。根据以下方法猜测:

代码

   /**
     Forward Daubechies D4 transform
    */
   public void daubTrans( double s[] )
   {
      final int N = s.length;
      int n;
      for (n = N; n >= 4; n >>= 1) {
         transform( s, n );
      }
   }


   /**
     Inverse Daubechies D4 transform
    */
   public void invDaubTrans( double coef[])
   {
      final int N = coef.length;
      int n;
      for (n = 4; n <= N; n <<= 1) {
         invTransform( coef, n );
      }
   }

根据上面的方法,好像是"Fast Wavelet Transform",我也不太确定他们的计算,你可以看看这个link

小波变换上有很多 so-called,与 "terms" 类似,因此最好通过他们的数学来了解事物,并找出确切的方法可能是什么(例如,离散小波变换、连续小波变换、离散分组分解)。每个图书馆都有一些术语和假设,并进行不同的计算。您可能会 print 看看,如果您首先获得接近 D4 Wavelet = {−0.1830127, −0.3169873, 1.1830127, −0.6830127}; 的 DB4。或者,您可以进行其他测试以查看计算是否正确。

小波分解方法

看起来 cAcDcApproximated”和“Details" 由离散小波变换分解的信号。但是,我不太确定您可能已将输入向量分解到多少层。

在小波中有两种well-known分解信号的方法,一种是"packet"(分解"approximations"和"details"信号,所以你会得到2^4=16 sub-signals 用于将原始信号分解为 4 层)。

另一种分解方法分解信号的low-frequency部分。因此,您可能需要了解分解向量的分解级别。

另外,如果您自己编写代码,您可以随意分解它。

了解小波的简单关键

移动(时间)与缩放(频率)

有一件简单的事情,如果你理解了,那么小波就变得容易多了。首先,您可能知道,Wavelet 是一种 time-frequency 方法。但是,不是绘制时间与频率的关系,而是时间与比例的关系,其中比例是频率的 "inverse"。

Children 小波函数如DB4

小波变换将小波函数(例如 DB4)映射到整个原始信号中,这可能就是它计算您打印出的那些数字的方式。要考虑的一件事是找到一个基本函数 DB4,它将 "look like" 您的原始信号。你是怎么做到的?

基本上,您选择一个基函数 DB4,然后小波变换创建该基函数的多种形式(例如,假设您将它们命名为 DB4-0、DB4-2、DB4-3、DB4-4、.. .,DB4-15).这些 children 的创建基于:

(a) Shifting(在for循环中增加时间,滑动child函数,然后计算系数),shifting 显然与 time 有关。

(b) Scaling(表示 "stretching" 小波函数,垂直或水平,这将改变基函数的频率性质,然后再次滑动它时间),它与频率成反比关系,即规模越大,频率越低,反之亦然。

因此,这取决于您可能需要多少 children 函数,基于分解 (sub-signals)。如果您有 16 个 sub-signals(使用数据包方法进行 4 级分解),那么您将有 16 个 "children" 函数映射到您的整个信号中。这就是计算系数向量的方式。然后,你可能会把那些不需要的sub-signals扔掉,而继续关注那些你可能感兴趣的sub-signals(频率)。问题是Wavelet保留(维护)时间信息,而不是Fourier

正常分解

此外,由于您是一名优秀的程序员,我敢肯定,您可以快速破解代码,而且我认为您不会遗漏任何内容。你可以通过他们的方法并阅读维基百科的几页,如果你愿意的话,你可能会在那里。

如果您有真正令人兴奋的细节问题,您可以试试 DSP SE。那里有很多信号专家。对于那个很抱歉!写的太快了,也不是很好writer/explainer,希望以后有大佬指正并给出正确答案。不是很专业。

总之,你什么都不缺,好方法,祝你好运!