Main Content

lwt

R2026b

1-D lifting wavelet transform

    Description

    [ca,cd] = lwt(x) returns the wavelet decomposition of x. lwt uses the lifting scheme associated with the Haar wavelet and does not preserve integer-valued data.

    [ca,cd] = lwt(x,Name=Value) specifies options using one or more name-value arguments. For example, [ca,cd] = lwt(x,Level=2) specifies a level 2 wavelet decomposition.

    example

    Examples

    collapse all

    Create an integer-valued signal. Create a lifting scheme associated with the db2 wavelet.

    sig = randi([1 100],1,10)
    sig = 1×10
    
        82    91    13    92    64    10    28    55    96    97
    
    
    lsc = liftingScheme(Wavelet="db2");

    Use the lifting scheme to obtain the wavelet decomposition of the signal down to level 2. Display the approximation and detail coefficients.

    [ca,cd] = lwt(sig,LiftingScheme=lsc,Level=2);
    ca
    ca = 3×1
    
      131.8466
       88.5651
      188.4185
    
    
    cd{1}
    ans = 5×1
    
        9.5206
       64.5665
      -26.4039
       13.6642
      -17.5068
    
    
    cd{2}
    ans = 3×1
    
        4.6343
       36.3262
      -27.0884
    
    

    Obtain the decomposition again, but this time preserve the integer-valued data.

    [ca,cd] = lwt(sig,LiftingScheme=lsc,Level=2,Int2Int=true);
    ca
    ca = 3×1
    
        35
        24
        51
    
    
    cd{1}
    ans = 5×1
    
        19
       124
       -51
        27
       -33
    
    
    cd{2}
    ans = 3×1
    
         6
        36
       -27
    
    

    Load the 23 channel EEG data Espiga3. The channels are arranged column-wise.

    load Espiga3
    size(Espiga3)
    ans = 1×2
    
       995    23
    
    

    Obtain the LWT of the multisignal using the db4 wavelet. The default decomposition level is floor(log2(N)), where N is the length of the signal.

    wv = "db4";
    [ca,cd] = lwt(Espiga3,Wavelet=wv);

    Confirm the number of columns in ca is equal to the number of channels in the multisignal.

    size(ca,2)
    ans = 
    23
    

    Confirm that the detail coefficients are an N-by-1 cell array, where N is equal to floor(log2(size(Espiga3,1))).

    [length(cd) floor(log2(size(Espiga3,1)))]
    ans = 1×2
    
         9     9
    
    

    Each element of cd is a matrix. Confirm that the every matrix has 23 columns.

    cellfun(@(x) size(x,2),cd,UniformOutput=false)
    ans = 9×1 cell array
        {[23]}
        {[23]}
        {[23]}
        {[23]}
        {[23]}
        {[23]}
        {[23]}
        {[23]}
        {[23]}
    
    

    Create a signal.

    x = 1:8;

    Lifting Using Haar Wavelet

    Create the lifting scheme associated with the Haar wavelet. The scheme consists of one predict step and one update step.

    lsHaar = liftingScheme(Wavelet="haar")
    lsHaar = 
     	 Wavelet               : 'haar' 
    	 LiftingSteps          : [2 × 1] liftingStep 
    	 NormalizationFactors  : [1.4142 0.7071] 
    	 CustomLowpassFilter   : [  ] 
    
    
     Details of LiftingSteps :
                Type: 'predict'
        Coefficients: -1
            MaxOrder: 0
    
                Type: 'update'
        Coefficients: 0.5000
            MaxOrder: 0
    
    

    Many textbook presentations of wavelet lifting show the predict step with a negative coefficient (subtracting the prediction from the odd samples to obtain the wavelet or detail coefficients) because the intuition is "detail equals actual minus predicted". However, this is not necessarily the case and may differ from predict step to predict step within a lifting scheme.

    For the forward LWT, the predict step is defined as d:=d+Pxeven, where P is the predict operator and xeven are the even-indexed samples. For the Haar wavelet, the coefficient of the predict operator is negative, making the definition consistent with the intuition. In the predict step, the odd samples are replaced with the difference between the odd samples and the prediction: xodd:=xodd-xeven. You can write the predict step as a matrix operation on the z-transforms of the polyphase components: [10-11][Xe(z)Xo(z)]. For the update step, you multiply the result of the predict step by the matrix [11201]. You then apply the normalization factors. Create the three matrices.

    pmat = [1 0 ; -1 1];                      % predict step
    umat = [1 1/2 ; 0 1];                     % update step
    nmat = diag(lsHaar.NormalizationFactors); % normalization

    Split the input signal into even and odd polyphase components. Because MATLAB® indexes from 1 and not 0, the even polyphase component is x(1:2:end) and the odd polyphase component is x(2:2:end).

    xe = x(1:2:end); % even polyphase component
    xo = x(2:2:end); % odd polyphase component

    Perform the predict step as a matrix multiplication. The elements of the second row are the detail coefficients before normalization.

    pStep = pmat*[xe ; xo]
    pStep = 2×4
    
         1     3     5     7
         1     1     1     1
    
    

    Perform the update step. The elements of the first row are the approximation coefficients before normalization.

    uStep = umat*pStep
    uStep = 2×4
    
        1.5000    3.5000    5.5000    7.5000
        1.0000    1.0000    1.0000    1.0000
    
    

    Normalize the result.

    lStep = nmat*uStep
    lStep = 2×4
    
        2.1213    4.9497    7.7782   10.6066
        0.7071    0.7071    0.7071    0.7071
    
    

    Use the lwt function to obtain the single level decomposition of the signal. Confirm the approximation and detail coefficients match the first and second rows, respectively, of lStep.

    [ca,cd] = lwt(x,LiftingScheme=lsHaar,Level=1);
    [ca' ; lStep(1,:)]
    ans = 2×4
    
        2.1213    4.9497    7.7782   10.6066
        2.1213    4.9497    7.7782   10.6066
    
    
    [cd{1}' ; lStep(2,:)]
    ans = 2×4
    
        0.7071    0.7071    0.7071    0.7071
        0.7071    0.7071    0.7071    0.7071
    
    

    Lifting Using db2 Wavelet and Laurent Polynomials

    As mentioned previously, the coefficient in the predict step of a lifting scheme is not always negative. Create the lifting scheme associated with the db2 wavelet. The scheme consists of two predict steps and one update step. Similar to the Haar wavelet lifting scheme, the coefficient in the first predict step is negative. However, in the second predict step, the coefficient is positive. The odd sample xodd is replaced with xodd+xeven.

    lsDb2 = liftingScheme(Wavelet="db2")
    lsDb2 = 
     	 Wavelet               : 'db2' 
    	 LiftingSteps          : [3 × 1] liftingStep 
    	 NormalizationFactors  : [1.9319 0.5176] 
    	 CustomLowpassFilter   : [  ] 
    
    
     Details of LiftingSteps :
                Type: 'predict'
        Coefficients: -1.7321
            MaxOrder: 0
    
                Type: 'update'
        Coefficients: [-0.0670 0.4330]
            MaxOrder: 1
    
                Type: 'predict'
        Coefficients: 1
            MaxOrder: -1
    
    

    You can use laurentPolynomial objects to duplicate the output of the lwt function. In terms of z-transforms, you can write the lifting scheme as:

    [N100N2][10P2(z)1][1S(z)01][10P1(z)1][Xe(z)Xo(z)],

    where P1(z)=-3, S(z)=-0.067z+0.433, P2(z)=z-1, and N1 and N2 are the normalization factors.

    Use the lifting steps in the scheme to create P1(z), S(z), and P2(z) as laurentPolynomial objects.

    lSteps = lsDb2.LiftingSteps;
    lpP1 = laurentPolynomial(Coefficients=lSteps(1).Coefficients, ...
        MaxOrder=lSteps(1).MaxOrder)
    lpP1 = 
      laurentPolynomial with properties:
    
        Coefficients: -1.7321
            MaxOrder: 0
    
    
    lpS = laurentPolynomial(Coefficients=lSteps(2).Coefficients, ...
        MaxOrder=lSteps(2).MaxOrder)
    lpS = 
      laurentPolynomial with properties:
    
        Coefficients: [-0.0670 0.4330]
            MaxOrder: 1
    
    
    lpP2 = laurentPolynomial(Coefficients=lSteps(3).Coefficients, ...
        MaxOrder=lSteps(3).MaxOrder)
    lpP2 = 
      laurentPolynomial with properties:
    
        Coefficients: 1
            MaxOrder: -1
    
    

    Use the polyphase object function to create the even and odd polyphase components Xe(z) and Xo(z).

    lp = laurentPolynomial(Coefficients=x);
    [lpe,lpo] = polyphase(lp)
    lpe = 
      laurentPolynomial with properties:
    
        Coefficients: [1 3 5 7]
            MaxOrder: 0
    
    
    lpo = 
      laurentPolynomial with properties:
    
        Coefficients: [2 4 6 8]
            MaxOrder: 0
    
    

    Perform First Predict Step

    The first predict step is the operation [10P1(z)1][Xe(z)Xo(z)]=[Xe(z)P1(z)Xe(z)+Xo(z)]. Compute L1(z)=P1(z)Xe(z)+Xo(z). By default, lwt uses periodic boundary extension. Because P1(z) is strictly scalar multiplication, P1(z)Xe(z) and Xe(z) have the same maximum order. You do not have to shift the polynomial coefficients of Xe(z) before multiplying by P1(z) to account for periodic boundary extension.

    lpL1 = lpP1*lpe+lpo    % P1(Z)*Xe(z)+Xo(z)
    lpL1 = 
      laurentPolynomial with properties:
    
        Coefficients: [0.2679 -1.1962 -2.6603 -4.1244]
            MaxOrder: 0
    
    

    Perform Update Step

    The update step is the operation [1S(z)01][Xe(z)L1(z)]=[Xe(z)+S(z)L1(z)L1(z)]. Compute U(z)=Xe(z)+S(z)L1(z). The update operator S(z) has the form Az+B, where A and B are constants. You can compute S(z)L1(z) as AzL1(z)+bL1(z). To determine AzL1(z), you must account for periodic boundary extension. Before multiplying Az and L1(z), circularly shift the polynomial coefficients of L1(z) by −1, the negative of the maximum order of S(z). The product, AzL1(z), is a Laurent polynomial whose maximum order is 0.

    lpLtmp = lpL1;
    lpLtmp.Coefficients = circshift(lpLtmp.Coefficients,-1);
    tmp1 = rescale(lpLtmp,lSteps(2).Coefficients(1));  % Az*L1(z)
    lpLtmp = lpL1;
    tmp2 = rescale(lpLtmp,lSteps(2).Coefficients(2));  % B*L1(z)
    lpU = tmp1+tmp2+lpe                                % Az*L1(z)+B*L1(z)+Xe(z)
    lpU = 
      laurentPolynomial with properties:
    
        Coefficients: [1.1962 2.6603 4.1244 5.1962]
            MaxOrder: 0
    
    

    Perform Second Predict Step

    The second predict step is the operation [10P2(z)1][U(z)L1(z)]=[U(z)P2(z)U(z)+L1(z)]. Compute L2(z)=P2(z)U(z)+L1(z). Because P2(z)=z-1, you must account for periodic boundary extension when calculating P2(z)U(z).

    lpUtmp = lpU;
    lpUtmp.Coefficients = circshift(lpUtmp.Coefficients,1);
    lpUtmp = rescale(lpUtmp,lSteps(3).Coefficients);
    lpL2 = lpUtmp + lpL1    % P2(z)*U(z)+L1(z)  
    lpL2 = 
      laurentPolynomial with properties:
    
        Coefficients: 5.4641
            MaxOrder: 0
    
    

    Normalize

    Apply the normalization factors to U(z) and L2(z).

    lpU = rescale(lpU,lsDb2.NormalizationFactors(1));
    lpL2 = rescale(lpL2,lsDb2.NormalizationFactors(2));

    Compare with lwt

    The polynomials U(z) and L2(z) both have a maximum order of 0. Use the lwt function to obtain the single level decomposition of the signal. Confirm the approximation and detail coefficients match the coefficients of U(z) and L2(z), respectively.

    [ca,cd] = lwt(x,LiftingScheme=lsDb2,Level=1);
    ca'
    ans = 1×4
    
        2.3108    5.1392    7.9676   10.0382
    
    
    lpU.Coefficients
    ans = 1×4
    
        2.3108    5.1392    7.9676   10.0382
    
    
    cd{1}'
    ans = 1×4
    
        2.8284         0    0.0000    0.0000
    
    
    lpL2.Coefficients
    ans = 
    2.8284
    

    Input Arguments

    collapse all

    Signal, specified as a vector or matrix. If x is a matrix, lwt operates along the first dimension of x. x must have at least two samples. If x has an odd number of samples, lwt extends x by one sample by duplicating the last element of x.

    Data Types: single | double
    Complex Number Support: Yes

    Name-Value Arguments

    collapse all

    Specify optional pairs of arguments as Name1=Value1,...,NameN=ValueN, where Name is the argument name and Value is the corresponding value. Name-value arguments must appear after other arguments, but the order of the pairs does not matter.

    Example: [ca,cd] = lwt(x,Wavelet="db3",Level=4) uses the db3 wavelet to perform a level 4 wavelet decomposition.

    Orthogonal or biorthogonal wavelet to use in the LWT, specified as a character vector or string scalar. See the Wavelet property of liftingScheme for the list of supported wavelets.

    You cannot simultaneously specify Wavelet and LiftingScheme.

    Example: [ca,cd] = lwt(x,Wavelet="bior3.5") specifies the bior3.5 biorthogonal wavelet.

    Lifting scheme to use in the LWT, specified as a liftingScheme object.

    You cannot simultaneously specify Wavelet and LiftingScheme.

    Example: [ca,cd] = lwt(x,LiftingScheme=lScheme) specifies the lScheme lifting scheme.

    Level of wavelet decomposition, specified as a positive integer less than or equal to floor(log2(N)), where N is the length of x if x is a vector, or the row dimension of x if x is a matrix.

    Example: [ca,cd] = lwt(x,Level=4) specifies a level 4 wavelet decomposition.

    Data Types: double

    Extension mode to use in the LWT, specified as "periodic", "zeropad", or "symmetric". The value of Extension specifies how to extend the signal at the boundaries.

    Example: [ca,cd] = lwt(x,Extension="symmetric") specifies the symmetric extension mode.

    Integer-valued data handling, specified as a numeric or logical 1 (true) or 0 (false).

    • 1 (true) — Preserve integer-valued data

    • 0 (false) — Do not preserve integer-valued data

    Specify Int2Int only if all elements of the input are integers.

    Example: [ca,cd] = lwt(1:8,Int2Int=true) preserves integer-valued data.

    Output Arguments

    collapse all

    Approximation (lowpass) coefficients at the coarsest level, returned as a scalar, vector, or matrix. The dimension of ca depends on the signal dimension.

    Data Types: single | double

    Detail coefficients, returned as an L-by-1 cell array, where L is the level of the transform. The elements of cd are in order of decreasing resolution.

    Data Types: single | double

    References

    [1] Strang, Gilbert, and Truong Nguyen. Wavelets and Filter Banks. Rev. ed. Wellesley, Mass: Wellesley-Cambridge Press, 1997.

    [2] Sweldens, Wim. “The Lifting Scheme: A Construction of Second Generation Wavelets.” SIAM Journal on Mathematical Analysis 29, no. 2 (March 1998): 511–46. https://doi.org/10.1137/S0036141095289051.

    Extended Capabilities

    expand all

    C/C++ Code Generation
    Generate C and C++ code using MATLAB® Coder™.

    GPU Code Generation
    Generate CUDA® code for NVIDIA® GPUs using GPU Coder™.

    Version History

    Introduced in R2021a

    expand all