# 1D Wavelet Transform delay line, what happens at the end of the signal?

## 1D Wavelet Transform delay line, what happens at the end of the signal?

Hello all!
After having read the excellent thread 5481956 it has become a little bit clear for me now.
It explained really a lot. But I'm still not quite sure about how the delay line works. I am trying the biorthogonal filter banks, say bior3.3. I tested the program in that thread with biorthogonal filter banks and was quite confused.

In the forward transform, delay line is used to extrapolate only the prehistory of the signal, ie at the beginning. Since the anchor point of the filter banks is usually in the middle . We should supply those values. It seems that IPP cares automatically about the end and we don't need to supply these values at the end. Isn't it right? By comparing the result with matlab, it seems confirmed. That' all right.
The reconstruction seems more difficult to understand. Acctually we should supply the prehistory of the approximation and detail. But in the sample program the values at the beginnning are entered as the delay line. Again we don't need to care about the end, but why? I just couldn't get the result of the perfect reconstruction with my bior3.3.

Another question concerns the total delay. In the reconstruction we should call inversion twice due to the total delay. In the case of bior3.3 I thought the total delay is 4, so I splitt the input in 2-points and 4-points blocks. And the result was strange.

Here is the programm. Pls help!

#include
#include "ipp.h"

static const int fwdFltLenL = 8;
static const int fwdFltLenH = 4;

static const float Lo_D[8] =
{
0.06629126073624f,
-0.19887378220872f,
-0.15467960838456f,
0.99436891104358f,
0.99436891104358f,
-0.15467960838456f,
-0.19887378220872f,
0.06629126073624f
};

static const float Hi_D[4] =
{
-0.17677669529664f,
0.53033008588991f,
-0.53033008588991f,
0.17677669529664f
};

static const int invFltLenL = 4;
static const int invFltLenH = 8;

static const float Lo_R[4] =
{
0.17677669529664f,
0.53033008588991f,
0.53033008588991f,
0.17677669529664f,
};

static const float Hi_R[8] =
{
0.06629126073624f,
0.19887378220872f,
-0.15467960838456f,
-0.99436891104358f,
0.99436891104358f,
0.15467960838456f,
-0.19887378220872f,
-0.06629126073624f
};

// minimal values, that corresponds to MATLAB calculations
static const int fwdFltOffsL = -1;
static const int fwdFltOffsH = 1;
// minimal values, that corresponds to MATLAB calculations

void main(void)
{ Ipp32f src[] = {1, -10, 324, 48, -483, 4, 7, -5532, 34, 8889, -57, 54};

Ipp32f low[7];
Ipp32f high[7];
int i;
printf("original:
");
for(i = 0; i < 12; i++) printf("%.0f; ", src[i]);
printf("
");
{
IppsWTFwdState_32f* state;

ippsWTFwdInitAlloc_32f (&state, Lo_D, fwdFltLenL, fwdFltOffsL, Hi_D, fwdFltLenH, fwdFltOffsH);
ippsWTFwdSetDlyLine_32f( state, &src[6], &src[8]);
ippsWTFwd_32f (src, low, high, 6, state);
ippsWTFwdFree_32f (state);
// print decomposition result
printf("approx:
");
for(i = 0; i < 7; i++) printf("%.4f; ", low[i]);
printf("
");
printf("details:
");
for(i = 0; i < 7; i++) printf("%.4f; ", high[i]);
printf("
");
}
// note actually we simply do not need to keep MATLAB excessive low[6] & high[6] elements
// it can be applied as wrapped extension from first element
// let's change it to 'trash' to check it
{

static const int invFltOffsL = 2;
static const int invFltOffsH = 0;

Ipp32f dst[24];
IppsWTInvState_32f* state;
ippsWTInvInitAlloc_32f (&state, Lo_R, invFltLenL, invFltOffsL, Hi_R, invFltLenH, invFltOffsH);
ippsWTInvSetDlyLine_32f( state,low,high);//extBegL, extBegH);

ippsWTInv_32f (&low[2], &high[2], 4, dst, state);
ippsWTInv_32f (low, high, 2, &dst[8], state);//(extEndL, extEndH, 3, &dst[6], state);

ippsWTInvFree_32f (state);
// print reconstruction result
int i;
printf("reconstruction:
");
for(i = 0; i < 12; i++) printf("%.0f; ", dst[i]);
printf("
");
}
}

3 posts / 0 new
For more complete information about compiler optimizations, see our Optimization Notice.

Hi,
I successfully tuned up offsets and borders to make the code working.
First, the value for high-pass delay line length must be different for reconstruction, see formulas on manual page 7-106. At the same time it's definitely right idia, that "low" & "high" parameters of ippsWTInv_32f reffer to the same index offset (till we keep MATLAB style). In combination the "high" delay line length must be (8 - 1) /2, that is 3, so offset must be 3 (instead of 2). After this correction the beginning of destitination vector will be perfectly reconstructed.
Second, the code doesn't apply final border into L & H components, which is required for the reconstruction and border placement also was corrected.

So finally the source code is:

#include
#include "ipp.h"

static const int fwdFltLenL = 8;
static const int fwdFltLenH = 4;
static const int fwdFltOffsL = -1;
static const int fwdFltOffsH = 1;

static const float Lo_D[8] =
{
0.06629126073624f,
-0.19887378220872f,
-0.15467960838456f,
0.99436891104358f,
0.99436891104358f,
-0.15467960838456f,
-0.19887378220872f,
0.06629126073624f
};

static const float Hi_D[4] =
{
-0.17677669529664f,
0.53033008588991f,
-0.53033008588991f,
0.17677669529664f
};

static const int invFltLenL = 4;
static const int invFltLenH = 8;
static const int invFltOffsL = 2;
static const int invFltOffsH = 0;

static const float Lo_R[4] =
{
0.17677669529664f,
0.53033008588991f,
0.53033008588991f,
0.17677669529664f
};

static const float Hi_R[8] =
{
0.06629126073624f,
0.19887378220872f,
-0.15467960838456f,
-0.99436891104358f,
0.99436891104358f,
0.15467960838456f,
-0.19887378220872f,
-0.06629126073624f
};

void main(void)
{
Ipp32f low [7];
Ipp32f high[7];

int i;

{
static const Ipp32f src[12] = {1, -10, 324, 48, -483, 4, 7, -5532, 34, 8889, -57, 54};

printf("original:
");
for(i = 0; i < 12; i++) printf("%.0f; ", src[i]);
printf("
");

IppsWTFwdState_32f* state;

ippsWTFwdInitAlloc_32f (&state, Lo_D, fwdFltLenL, fwdFltOffsL, Hi_D, fwdFltLenH, fwdFltOffsH);
ippsWTFwdSetDlyLine_32f(state, &src[6], &src[8]);
ippsWTFwd_32f (src, low, high, 6, state);

ippsWTFwdFree_32f (state);

// print decomposition result
printf("approx:
");
for(i = 0; i < 7; i++) pr
intf("%.4f; ", low[i]);
printf("
");
printf("details:
");
for(i = 0; i < 7; i++) printf("%.4f; ", high[i]);
printf("
");
}

{
Ipp32f dst[12];

IppsWTInvState_32f* state;
ippsWTInvInitAlloc_32f (&state, Lo_R, invFltLenL, invFltOffsL, Hi_R, invFltLenH, invFltOffsH);
ippsWTInvSetDlyLine_32f( state, &low[1], high);//extBegL, extBegH);

ippsWTInv_32f (&low[3], &high[3], 3, dst , state);
ippsWTInv_32f (&low[0], &high[0], 3, &dst[6], state);//(extEndL, extEndH, 3, &dst[6], state);

ippsWTInvFree_32f (state);

// print reconstruction result
int i;
printf("reconstruction:
");
for(i = 0; i < 12; i++) printf("%.0f; ", dst[i]);
printf("
");
}
}

The console output:

original:
1; -10; 324; 48; -483; 4; 7; -5532; 34; 8889; -57; 54;
approx:
9868.4268; -1761.7345; 386.4560; -849.3457; 1535.7697; -6860.9688; -107374176.00
00;
details:
-4747.8682; -36.4160; 168.8217; -225.0367; 894.1365; 1381.6865; -107374176.0000;

reconstruction:
1; -10; 324; 48; -483; 4; 7; -5532; 34; 8889; -57; 54;

Regards,
Mikhail

Hello Mikhail,

thanks a lot for the excellent correction!
Next I would like to test the mulitlevel decomposition with this example and report the result some time if it succeeds or fails.

Best regards,
Binjian