小波变换的两个不同值(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。或者,您可以进行其他测试以查看计算是否正确。
小波分解方法
看起来 cA
和 cD
是 c“Approximated”和“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,希望以后有大佬指正并给出正确答案。不是很专业。
总之,你什么都不缺,好方法,祝你好运!
我正在测试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。或者,您可以进行其他测试以查看计算是否正确。
小波分解方法
看起来 cA
和 cD
是 c“Approximated”和“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,希望以后有大佬指正并给出正确答案。不是很专业。
总之,你什么都不缺,好方法,祝你好运!