Visible to Intel only — GUID: GUID-7392410E-1D2F-4D6C-8D5C-6F552B84C044
Visible to Intel only — GUID: GUID-7392410E-1D2F-4D6C-8D5C-6F552B84C044
Wavelet Transforms Example
The delay line paradigm is well-known interface solution for functions that require some pre-history in the streaming processing. In such application the use of the Intel IPP wavelet transform functions is similar to the use of the FIR, IIR, or multi-rate filters. (See also the discussion on the synchronization of low-pass and high-pass filter delays in this chapter.) But very often the wavelet transforms are used to process entire non-streaming data by extending with borders that are suitable for filter bank type that are used in transforms.
The following code example demonstrates how to implement this approach using the Intel IPP functions. It performs forward and inverse wavelet transforms of a short vector containing 12 elements. It uses Daubechies filter bank of the order 2 (that allows the perfect reconstruction) and periodical data extension by wrapping.
It is also may be useful as an illustration of how to fill delay line, if you need non-zero pre-history of signal in streaming applications.
Example
// Filter bank for Daubechies, order 2 static const int fwdFltLenL = 4; static const int fwdFltLenH = 4; static const Ipp32f pFwdFltL[4] = { -1.294095225509215e-001f, 2.241438680418574e-001f, 8.365163037374690e-001f, 4.829629131446903e-001f }; static const Ipp32f pFwdFltH[4] = { -4.829629131446903e-001f, 8.365163037374690e-001f, -2.241438680418574e-001f, -1.294095225509215e-001f }; static const int invFltLenL = 4; static const int invFltLenH = 4; static const Ipp32f pInvFltL[4] = { 4.829629131446903e-001f, 8.365163037374690e-001f, 2.241438680418574e-001f, -1.294095225509215e-001f }; static const Ipp32f pInvFltH[4] = { -1.294095225509215e-001f, -2.241438680418574e-001f, 8.365163037374690e-001f, -4.829629131446903e-001f }; // minimal values static const int fwdFltOffsL = -1; static const int fwdFltOffsH = -1; // minimal values, that corresponds to perfect reconstruction static const int invFltOffsL = 0; static const int invFltOffsH = 0; void func_wavelet() { IppStatus status=ippStsNoErr; Ipp32f pSrc[] = {1, -10, 324, 48, -483, 4, 7, -5532, 34, 8889, -57, 54}; Ipp32f pDst[12]; Ipp32f pLow[6]; Ipp32f pHigh[6]; IppsWTFwdState_32f* pFwdState; IppsWTInvState_32f* pInvState; int i, szState; printf("original:\n"); for(i = 0; i < 12; i++) printf("%.0f; ", pSrc[i]); printf("\n"); // Forward transform ippsWTFwdGetSize( ipp32f, fwdFltLenL, fwdFltOffsL, fwdFltLenH, fwdFltOffsH, &szState ); pFwdState = (IppsWTFwdState_32f*)ippMalloc( szState ); ippsWTFwdInit_32f( pFwdState, pFwdFltL, fwdFltLenL, fwdFltOffsL, pFwdFltH, fwdFltLenH, fwdFltOffsH); // We substitute wrapping extension in "the beginning of stream" // Here should be the same pointers for this offsets, // but in the general case it may be different ippsWTFwdSetDlyLine_32f( pFwdState, &pSrc[10], &pSrc[10] ); ippsWTFwd_32f( pSrc, pLow, pHigh, 6, pFwdState ); printf("approx:\n"); for(i = 0; i < 6; i++) printf("%.4f; ", pLow[i]); printf("\n"); printf("details:\n"); for(i = 0; i < 6; i++) printf("%.4f; ", pHigh[i]); printf("\n"); // Inverse transform ippsWTInvGetSize( ipp32f, invFltLenL, invFltOffsL, invFltLenH, invFltOffsH, &szState ); pInvState = (IppsWTInvState_32f*)ippMalloc( szState ); ippsWTInvInit_32f( pInvState, pInvFltL, invFltLenL, invFltOffsL, pInvFltH, invFltLenH, invFltOffsH ); // For this particular case (non-shifted reconstruction) // here is first data itself, // that we need to place to delay line // [(invFltLenL + invFltOffsL - 1) / 2] elements for l. filtering // [(invFltLenH + invFltOffsH - 1) / 2] elements for h. filtering ippsWTInvSetDlyLine_32f( pInvState, pLow, pHigh); ippsWTInv_32f( &pLow[1], &pHigh[1], 5, pDst, pInvState ); // Here are the substitution of the wrapping extension // at the "end of stream" and calculation of last samples of reconstruction // We do not use additional buffer and do not copy any data externally, // just substitute beginning of input data itself to simulate wrapping ippsWTInv_32f( pLow, pHigh, 1, &pDst[10], pInvState ); printf("reconstruction:\n"); for(i = 0; i < 12; i++) printf("%.0f; ", pDst[i]); printf("\n"); ippFree(pFwdState); ippFree(pInvState); }
After compiling and running it gives the following console output:
original: 1; -10; 324; 48; -483; 4; 7; -5532; 34; 8889; -57; 54; approx: 19.1612; 58.5288; 87.8536; 487.5375; -5766.9277; 7432.4497; details: 0.9387; 249.9611; -458.6568; 2739.2146; -3025.5576; -2070.5762; reconstruction: 1; -10; 324; 48; -483; 4; 7; -5532; 34; 8889; -57; 54;
The program prints on console the original data, approximation, and details components after forward transform and perfect reconstruction of original data after inverse transform.