({{, (RefLink[DiscreteWaveletTransform, paclet:ref/DiscreteWaveletTransform])[data] 
gives the discrete wavelet transform (DWT) of an array of data.}, {, (RefLink[DiscreteWaveletTransform, paclet:ref/DiscreteWaveletTransform])[data,wave]
gives the discrete wavelet transform using the wavelet wave.}, {, (RefLink[DiscreteWaveletTransform, paclet:ref/DiscreteWaveletTransform])[data,wave,r]
gives the discrete wavelet transform using r levels of refinement.}})

OpenersNotesSection(Spacer1)Details and Options

(RefLink[DiscreteWaveletTransform, paclet:ref/DiscreteWaveletTransform]) gives a (RefLink[DiscreteWaveletData, paclet:ref/DiscreteWaveletData]) object representing a tree of wavelet coefficient arrays.

Properties of the (RefLink[DiscreteWaveletData, paclet:ref/DiscreteWaveletData]) dwd can be found using dwd["prop"], and a list of available properties can be found using dwd["Properties"].

The data can be any of the following:

The resulting wavelet coefficients are arrays of the same depth as the input data.

The possible wavelets wave include:

The default wave is (RefLink[HaarWavelet, paclet:ref/HaarWavelet])[].

With higher settings for the refinement level r, larger-scale features are resolved.

The default refinement level r is given by (Floor[(Subscript[log, 2])(n)+(1/2)]), where n is the minimum dimension of data.  »

The tree of wavelet coefficients at level j consists of coarse coefficients (Subscript[c, j,n]) and detail coefficients (Subscript[d, j,n]), with (Subscript[c, 0,n])=(Subscript[x, n]) representing the input data.

The forward transform is given by (Subscript[c, j+1,n])=(Sqrt[2])(∑_m)(Subscript[a, m-2n+2]) (Subscript[c, j,m]) and (Subscript[d, j+1,n])=(Sqrt[2])(∑_m)(Subscript[b, m-2n+2]) (Subscript[c, j,m]).  »

The inverse transform is given by (Subscript[c, j,n])=(Sqrt[2]) ((∑_m)(Subscript[a, n-2 m+2]) (Subscript[c, j+1,n])+ (∑_m)(Subscript[b, n-2 m+2]) (Subscript[d, j+1,m])).  »

The (Subscript[a, i]) are lowpass filter coefficients and (Subscript[b, i]) are highpass filter coefficients that are defined for each wavelet family.

The dimensions of (Subscript[c, j]) and (Subscript[d, j]) are given by (Subscript[wd, j+1])=(Ceiling[(1/2) ((Subscript[wd, j])+fl-2)]), where (Subscript[wd, 0]) is the input data dimension and fl is the filter length for the corresponding wspec.  »

The following options can be given:

The settings for (RefLink[Padding, paclet:ref/Padding]) are the same as those available in (RefLink[ArrayPad, paclet:ref/ArrayPad]).

(RefLink[InverseWaveletTransform, paclet:ref/InverseWaveletTransform]) gives the inverse transform.

OpenersPrimaryExamplesSection(Spacer1)Examples  (75)

OpenersExampleSection0(Spacer1)Basic Examples  (3)

Compute a discrete wavelet transform using the (RefLink[HaarWavelet, paclet:ref/HaarWavelet]):

DiscreteWaveletTransform[{56,40,8,24,48,48,40,16}]

Use (RefLink[Normal, paclet:ref/Normal]) to view all coefficients:

Normal[%]

Transform an audio signal:

a=Audio["ExampleData/rule30.wav"]

dwd=DiscreteWaveletTransform[a,Automatic,3]

Use dwd[…,"Audio"] to extract coefficient signals:

dwd[All,"Audio"]

Compute the inverse transform:

InverseWaveletTransform[dwd]

Transform an (RefLink[Image, paclet:ref/Image]) object:

dwd=DiscreteWaveletTransform[,Automatic,2]

Use dwd[…,"Image"] to extract coefficient images:

dwd[All,"Image"]

Compute the inverse transform:

InverseWaveletTransform[dwd]

OpenersExampleSection1(Spacer1)Scope  (36)

OpenersExampleSubsection0(Spacer1)Basic Uses  (6)

Compute a wavelet transform:

dwd=DiscreteWaveletTransform[{0,0,1,0,0}]

The resulting (RefLink[DiscreteWaveletData, paclet:ref/DiscreteWaveletData]) represents a tree of transform coefficients:

dwd["TreeView"]

The inverse transform reconstructs the input:

InverseWaveletTransform[dwd]

Useful properties can be extracted from the (RefLink[DiscreteWaveletData, paclet:ref/DiscreteWaveletData]) object:

dwd=DiscreteWaveletTransform[RandomReal[1,{16}],DaubechiesWavelet[4],2]

Get a full list of properties:

dwd["Properties"]

Get data and coefficient dimensions:

dwd["DataDimensions"]

dwd["Dimensions"]

Use (RefLink[Normal, paclet:ref/Normal]) to get all wavelet coefficients explicitly:

dwd=DiscreteWaveletTransform[Range[8]];

Normal[dwd]

Also use (RefLink[All, paclet:ref/All]) as an argument to get all coefficients:

dwd[All]

Use (RefLink[Automatic, paclet:ref/Automatic]) to get only the coefficients used in the inverse transform:

dwd[Automatic]

Use the "TreeView" or "WaveletIndex" to find out what wavelet coefficients are available:

dwd=DiscreteWaveletTransform[Range[8],HaarWavelet[],2];

dwd["TreeView"]

dwd["WaveletIndex"]

Extract specific coefficient arrays:

dwd[{0}]

dwd[{0,0}]

Extract several wavelet coefficients corresponding to the list of wavelet index specifications:

dwd[{{0},{0,1}}]

Extract all coefficients whose wavelet indexes match a pattern:

dwd[{_}]

dwd[{{_,0},{_,1}}]

The (RefLink[Automatic, paclet:ref/Automatic]) coefficients are used by default in functions like (RefLink[WaveletListPlot, paclet:ref/WaveletListPlot]):

dwd=DiscreteWaveletTransform[Table[Sin[x^2],{x,0,10,0.2}],Automatic,4];

First/@dwd[Automatic]

WaveletListPlot[dwd,Ticks->Full]

Use a higher refinement level to increase the frequency resolution:

data=Table[Sin[x^2]+RandomReal[{-0.2,0.2}],{x,0,10,0.02}];

ListLinePlot[data]

With a smaller refinement level, more signal energy is left in {0,0,0}:

dwt1=DiscreteWaveletTransform[data,DaubechiesWavelet[4],3];

WaveletListPlot[dwt1,PlotLayout->"CommonYAxis"]

With further refinement, {0,0,0} is resolved into further components:

dwt2=DiscreteWaveletTransform[data,DaubechiesWavelet[4],4];

WaveletListPlot[dwt2,PlotLayout->"CommonYAxis"]

OpenersExampleSubsection1(Spacer1)Wavelet Families  (10)

Compute the discrete wavelet transform using different wavelet families:

data=Table[Sin[x^2],{x,0,10,0.02}];

dwd1=DiscreteWaveletTransform[data,DaubechiesWavelet[4],3];
dwd2=DiscreteWaveletTransform[data,SymletWavelet[4],3];

Compare the coefficients:

{WaveletListPlot[dwd1],WaveletListPlot[dwd2]}

Use different families of wavelets to capture different features:

data = Table[Sin[(t^2)],{t,-3π,3π,0.01}];

ListLinePlot[data]

(RefLink[HaarWavelet, paclet:ref/HaarWavelet]) (default):

dwd=DiscreteWaveletTransform[data,HaarWavelet[],3];

WaveletListPlot[dwd,PlotLayout->"CommonYAxis",Filling->Axis]

(RefLink[DaubechiesWavelet, paclet:ref/DaubechiesWavelet]):

data=Table[Sin[(t^2)],{t,-3π,3π,0.01}];

dwd=DiscreteWaveletTransform[data,DaubechiesWavelet[2],3];

WaveletListPlot[dwd,PlotLayout->"CommonYAxis",Filling->Axis]

(RefLink[BattleLemarieWavelet, paclet:ref/BattleLemarieWavelet]):

data=Table[Sin[(t^2)],{t,-3π,3π,0.01}];

dwd=DiscreteWaveletTransform[data,BattleLemarieWavelet[3],3];

WaveletListPlot[dwd,PlotLayout->"CommonYAxis",Filling->Axis]

(RefLink[BiorthogonalSplineWavelet, paclet:ref/BiorthogonalSplineWavelet]):

data=Table[Sin[(t^2)],{t,-3π,3π,0.01}];

dwd=DiscreteWaveletTransform[data,BiorthogonalSplineWavelet[4,2],3];

WaveletListPlot[dwd,PlotLayout->"CommonYAxis",Filling->Axis]

(RefLink[CoifletWavelet, paclet:ref/CoifletWavelet]):

data=Table[Sin[(t^2)],{t,-3π,3π,0.01}];

dwd=DiscreteWaveletTransform[data,CoifletWavelet[2],3];

WaveletListPlot[dwd,PlotLayout->"CommonYAxis",Filling->Axis]

(RefLink[MeyerWavelet, paclet:ref/MeyerWavelet]):

data=Table[Sin[(t^2)],{t,-3π,3π,0.01}];

dwd=DiscreteWaveletTransform[data,MeyerWavelet[3],3];

WaveletListPlot[dwd,PlotLayout->"CommonYAxis",Filling->Axis]

(RefLink[ReverseBiorthogonalSplineWavelet, paclet:ref/ReverseBiorthogonalSplineWavelet]):

data=Table[Sin[(t^2)],{t,-3π,3π,0.01}];

dwd=DiscreteWaveletTransform[data,ReverseBiorthogonalSplineWavelet[4,2],3];

WaveletListPlot[dwd,PlotLayout->"CommonYAxis",Filling->Axis]

(RefLink[ShannonWavelet, paclet:ref/ShannonWavelet]):

data=Table[Sin[(t^2)],{t,-3π,3π,0.01}];

dwd=DiscreteWaveletTransform[data,ShannonWavelet[8],3];

WaveletListPlot[dwd,PlotLayout->"CommonYAxis",Filling->Axis]

(RefLink[SymletWavelet, paclet:ref/SymletWavelet]):

data=Table[Sin[(t^2)],{t,0,3π,0.01}];

dwd=DiscreteWaveletTransform[data,SymletWavelet[3],3];

WaveletListPlot[dwd,PlotLayout->"CommonYAxis",Filling->Axis]

OpenersExampleSubsection2(Spacer1)Vector Data  (6)

Plot the coefficients over a common horizontal axis using (RefLink[WaveletListPlot, paclet:ref/WaveletListPlot]):

dwd=DiscreteWaveletTransform[Table[Sin[x^2],{x,0,10,0.02}],Automatic,3];

WaveletListPlot[dwd]

Plot against a common vertical axis:

WaveletListPlot[dwd,PlotLayout->"CommonYAxis"]

Visualize coefficients as a function of time and refinement level using (RefLink[WaveletScalogram, paclet:ref/WaveletScalogram]):

dwd=DiscreteWaveletTransform[Table[Sin[20x]+Sin[10x],{x,1,10,0.01}],Automatic,4];

The coefficient indexes appear as tooltips when the mouse pointer is moved over a coefficient:

WaveletScalogram[dwd,All]

Constant data:

data=Table[1,{x,0,10,0.02}];

ListLinePlot[data]

All coefficients are small except coarse coefficients {0,0,…}:

dwd=DiscreteWaveletTransform[data,DaubechiesWavelet[4],3];

WaveletListPlot[dwd,All,PlotLayout->"CommonYAxis"]

Data oscillating at the highest resolvable frequency (Nyquist frequency):

data=Table[(((-1))^n),{n,80}];

ListLinePlot[data]

Only the first detail coefficient {1} is not small:

dwd=DiscreteWaveletTransform[data,Automatic,3];

WaveletListPlot[dwd,All,PlotLayout->"CommonYAxis",Ticks->Full]

Data with large discontinuities:

data=Table[({{\[Piecewise], ({{1, 1<x<3.1}, {0, True}})}}),{x,0,4,0.02}];

ListLinePlot[data]

Coarse coefficients {0,…} have the same large-scale structure as the data:

dwd=DiscreteWaveletTransform[data,Automatic,3];

WaveletListPlot[dwd,{0..},FrameTicks->Full]

Detail coefficients are sensitive to discontinuities:

WaveletListPlot[dwd,Except[{0..}],FrameTicks->Full]

Data with both spatial and frequency structure:

data=Table[({{\[Piecewise], ({{5, n≤30}, {2+(((-1))^n), 30<n≤60}, {5, 60<n}})}}),{n,90}];

ListLinePlot[data,PlotRange->{0,5}]

Coarse coefficients {0,…} track the local mean of the data:

dwd=DiscreteWaveletTransform[data,Automatic,3];

WaveletListPlot[dwd,{0..},Ticks->Full]

The first detail coefficient identifies the oscillatory region:

WaveletListPlot[dwd,{1,0...},Ticks->Full]

All coefficients on a common vertical axis:

WaveletListPlot[dwd,All,PlotLayout->"CommonYAxis",AxesOrigin->{0,-5}]

OpenersExampleSubsection3(Spacer1)Matrix Data  (5)

Compute a two-dimensional discrete wavelet transform:

dwd=DiscreteWaveletTransform[(({{0, 0, 1, 0, 0}, {0, 1, 1, 1, 0}, {1, 1, 1, 1, 1}, {0, 1, 1, 1, 0}, {0, 0, 1, 0, 0}}))]

View the tree of wavelet coefficients:

dwd[{"TreeView",Left}]

Inverse transform to get back the original signal:

InverseWaveletTransform[dwd]//Chop//MatrixForm

Use (RefLink[WaveletMatrixPlot, paclet:ref/WaveletMatrixPlot]) to visualize the different wavelet coefficients:

dwd=DiscreteWaveletTransform[DiamondMatrix[32],Automatic,2]

WaveletMatrixPlot[dwd,ImageSize->Small]

(RefLink[WaveletMatrixPlot, paclet:ref/WaveletMatrixPlot]) of wavelet transform at a higher refinement level:

WaveletMatrixPlot[DiscreteWaveletTransform[DiamondMatrix[32],Automatic,3],ImageSize->Small]

In two dimensions, the vector of filtering operations in each direction can be computed:

Tuples[{0,1},2]/.{0->"lowpass",1->"highpass"}

Interpreting these vectors as binary digit expansions results in wavelet index numbers:

FromDigits[#,2]&/@Tuples[{0,1},2]

Get the lowpass and highpass filters for a Haar wavelet:

{lp,hp}=Map[Last,WaveletFilterCoefficients[HaarWavelet[],{"PrimalLowpass","PrimalHighpass"}],{2}]

The resulting 2D filters are outer products of filters in the two directions:

Apply[KroneckerProduct,Tuples[{lp,hp},2],{1}]

Map[MatrixPlot,%]

Wavelet transform of step data:

step[{a_,b_,c_,d_}]:=
ArrayFlatten[{{ConstantArray[a,{3,3}],ConstantArray[b,{3,5}]},{ConstantArray[c,{5,3}],ConstantArray[d,{5,5}]}}];

Data with a vertical discontinuity:

MatrixPlot[step[{0,1,0,1}],FrameTicks->False]

Only the vertical detail coefficients, wavelet index {…,1}, are nonzero:

WaveletMatrixPlot[DiscreteWaveletTransform[step[{0,1,0,1}]],ImageSize->Small]

Data with horizontal discontinuity:

MatrixPlot[step[{0,0,1,1}],FrameTicks->False]

Only the horizontal detail coefficients, wavelet index {…,2}, are nonzero:

WaveletMatrixPlot[DiscreteWaveletTransform[step[{0,0,1,1}]],ImageSize->Small]

Data with diagonal discontinuity:

MatrixPlot[Reverse@IdentityMatrix[8],FrameTicks->False]

Only the diagonal detail coefficients, wavelet index {…,3}, are nonzero:

WaveletMatrixPlot[DiscreteWaveletTransform[Reverse@IdentityMatrix[8]],ImageSize->Small]

OpenersExampleSubsection4(Spacer1)Array Data  (2)

Compute a three-dimensional discrete wavelet transform:

data=RandomReal[1,{16,16,16}];

dwd=DiscreteWaveletTransform[data,Automatic,2]

Tree view of all coefficients:

dwd["TreeView"]

Inverse transform to get back the original signal:

Norm[Flatten[data-InverseWaveletTransform[dwd]]]

Wavelet transform of a three-dimensional cross array:

data = CrossMatrix[All,{8,8,8}];

Graphics3D[{Red,Cuboid/@Position[data,1]}]

dwd=DiscreteWaveletTransform[data,Automatic,1]

Visualize wavelet coefficients:

Table[i->Graphics3D[{If[Positive[Extract[dwd[i][[1,2]],#]],Red, Green],Cuboid[#]}&/@Position[dwd[i][[1,2]],u_/;Abs[u]>0],PlotRange->Automatic],{i,dwd["IndexMap"]}]

Energy of the original data is conserved within the transformed coefficients:

Total[((Flatten[data])^2)]== Total[((Flatten[dwd[Automatic][[All,2]]])^2)]

OpenersExampleSubsection5(Spacer1)Image Data  (4)

Transform an (RefLink[Image, paclet:ref/Image]) object:

img = Image[DiamondMatrix[All,{64,64}]]

dwd=DiscreteWaveletTransform[img,HaarWavelet[],3]

The inverse transform yields a reconstructed (RefLink[Image, paclet:ref/Image]) object:

InverseWaveletTransform[dwd]

Wavelet coefficients are normally given as lists of data for each image channel:

dwd=DiscreteWaveletTransform[,HaarWavelet[],2];

Dimensions[{0,0}/.Normal[dwd]]

Get all coefficients as (RefLink[Image, paclet:ref/Image]) objects instead:

dwd[All,{"Image",ImageSize->80}]

Get raw (RefLink[Image, paclet:ref/Image]) objects with no rescaling of color levels:

dwd[All,{"Image","ImageFunction"->Identity,ImageSize->80}]

Get the inverse transform of the {0,1} coefficient as an (RefLink[Image, paclet:ref/Image]) object:

dwd[{0,1},{"Image","Inverse"}]

Plot coefficients used in the inverse transform in a hierarchical grid using (RefLink[WaveletImagePlot, paclet:ref/WaveletImagePlot]):

dwd=DiscreteWaveletTransform[,HaarWavelet[],3];

WaveletImagePlot[dwd,BaseStyle->Red]

(RefLink[Image, paclet:ref/Image]) wavelet coefficients lie outside the valid range of (RefLink[ImageType, paclet:ref/ImageType]):

img = ;

dwd=DiscreteWaveletTransform[img,CDFWavelet["9/7"],1];

"ImageFunction"->Identity gives an unnormalized image wavelet coefficient:

i1=First[dwd[{0},{"Values",{"Image","ImageFunction"->Identity}}]];

{r1,g1,b1}=Flatten/@ImageData/@ColorSeparate[i1];

The color channels lie outside its valid 0 to 1 range:

{i1,BoxWhiskerChart[{r1,g1,b1},ChartStyle->{Red,Green,Blue}]}

By default, "ImageFunction"->(RefLink[ImageAdjust, paclet:ref/ImageAdjust]) is used to normalize coefficients:

i2=First[dwd[{0},{"Values",{"Image","ImageFunction"->ImageAdjust}}]];

{r2,g2,b2}=Flatten/@ImageData/@ColorSeparate[i2];

The color channels are now within the valid 0 to 1 range:

{i2,BoxWhiskerChart[{r2,g2,b2},ChartStyle->{Red,Green,Blue}]}

OpenersExampleSubsection6(Spacer1)Sound Data  (3)

Transform a (RefLink[Sound, paclet:ref/Sound]) object:

snd=ExampleData[{"Sound","Apollo11ReturnSafely"}]

dwd=DiscreteWaveletTransform[snd]

The inverse transform yields a reconstructed (RefLink[Sound, paclet:ref/Sound]) object:

InverseWaveletTransform[dwd]

By default, coefficients are given as lists of data for each sound channel:

dwd=DiscreteWaveletTransform[ExampleData[{"Sound","PianoScale"}]];

Dimensions[{0,0,1}/.Normal[dwd]]

Get the {0,1} coefficient as a (RefLink[Sound, paclet:ref/Sound]) object:

dwd[{0,0,1},"Sound"]

Inverse transform of {0,0,1} coefficient as a (RefLink[Sound, paclet:ref/Sound]) object:

dwd[{0,0,1},{"Sound","Inverse"}]

Browse all coefficients using a (RefLink[MenuView, paclet:ref/MenuView]):

dwd=DiscreteWaveletTransform[ExampleData[{"Sound","Clarinet"}]];

MenuView[dwd[All,"Sound"]]

OpenersExampleSection2(Spacer1)Generalizations & Extensions  (3)

(RefLink[DiscreteWaveletTransform, paclet:ref/DiscreteWaveletTransform]) works on arrays of symbolic quantities:

dwd=DiscreteWaveletTransform[{a,b,c,d},WorkingPrecision->∞];

Normal[dwd]//Simplify

Inverse transform recovers the input exactly:

InverseWaveletTransform[dwd]//Simplify

Specify any internal working precision:

dwd=DiscreteWaveletTransform[{1,2,5,2},WorkingPrecision->20];

Normal[dwd]

Use complex-valued data:

data=Exp[I RandomReal[1,4]];

dwd=DiscreteWaveletTransform[data]

The wavelet coefficients are complex:

dwd[Automatic]

Inverse transform recovers the input:

Norm[InverseWaveletTransform[dwd]-data]

OpenersExampleSection3(Spacer1)Options  (5)

OpenersExampleSubsection7(Spacer1)Padding  (2)

The settings for (RefLink[Padding, paclet:ref/Padding]) are the same as the methods for (RefLink[ArrayPad, paclet:ref/ArrayPad]), including "Periodic":

ArrayPad[{a,b,c},4, "Periodic"]

"Reversed":

ArrayPad[{a,b,c},4,"Reversed"]

"ReversedNegation":

ArrayPad[{a,b,c},4,"ReversedNegation"]

"Reflected":

ArrayPad[{a,b,c},4,"Reflected"]

"ReflectedDifferences":

ArrayPad[{a,b,c},3,"ReflectedDifferences"]

"ReversedDifferences":

ArrayPad[{a,b,c},4,"ReversedDifferences"]

"Extrapolated":

ArrayPad[{a,b,c},3,"Extrapolated"]

Padding can remove boundary effects:

data = Table[UnitStep[x],{x,-2,2,4/255}];

ListLinePlot[data]

Using the default "Periodic" padding:

dwt1 =DiscreteWaveletTransform[data,DaubechiesWavelet[2],5];

WaveletListPlot[dwt1]

Using "Extrapolated" padding has fewer boundary effects for nonperiodic data:

dwt2 =DiscreteWaveletTransform[data,DaubechiesWavelet[2],5,Padding->"Extrapolated"];

WaveletListPlot[dwt2]

OpenersExampleSubsection8(Spacer1)WorkingPrecision  (3)

By default, (RefLink[WorkingPrecision, paclet:ref/WorkingPrecision])->(RefLink[MachinePrecision, paclet:ref/MachinePrecision]) is used:

data=RandomInteger[1,{10}];

dwd1=DiscreteWaveletTransform[data]

dwd2=DiscreteWaveletTransform[data,WorkingPrecision->MachinePrecision]

dwd1==dwd2

Use higher-precision computation:

data={0,0,1,1};

dwd=Normal@DiscreteWaveletTransform[data,WorkingPrecision->30]

With numbers close to zero, accuracy is the better indicator of the number of correct digits:

{Precision[dwd],Accuracy[dwd]}

Use (RefLink[WorkingPrecision, paclet:ref/WorkingPrecision])->∞ for exact computation:

data=RandomInteger[10,{4}];

Normal@DiscreteWaveletTransform[data,WorkingPrecision->∞]//Simplify

OpenersExampleSection4(Spacer1)Applications  (11)

OpenersExampleSubsection9(Spacer1)Wavelet Compression  (1)

Compress data by finding a representation with few nonzero coefficients:

data = Table[(t^3),{t,-1,1,2/2047}];

ListLinePlot[data]

(RefLink[SymletWavelet, paclet:ref/SymletWavelet])[n] has n vanishing moments and represents polynomials of degree n:

dwd=Table[DiscreteWaveletTransform[data,SymletWavelet[n],Padding->"Extrapolated"],{n,5}];

(RefLink[Count, paclet:ref/Count]) counts the number of wavelet coefficients close to 0:

Table[n->Count[Flatten[dwd[[n]][Automatic][[All,2]]],u_/;Chop[Abs[u],(10^(-3))]==0],{n,5}]

OpenersExampleSubsection10(Spacer1)Detect Discontinuities and Edges  (2)

Visualize discontinuities in the wavelet domain:

data = Table[HeavisideLambda[x],{x,-2,2,4/1023}];

ListLinePlot[data]

Detail coefficients in the region of discontinuities have larger values:

dwd= DiscreteWaveletTransform[data,DaubechiesWavelet[3],5,Padding->"Reflected"];

WaveletScalogram[dwd,{___,1}, Method->"Inverse"->True,ColorFunction->"BlueGreenYellow"]

Detect edges in an image:

dwd = DiscreteWaveletTransform[,SymletWavelet[2],4];

WaveletImagePlot[dwd,Automatic,ImageAdjust[ImageAdjust[#],{1,0.2,1.9}]&]

Set coarse coefficients to 0 and reconstruct using detail coefficients only:

imgEdge[img_,{0,0,0,0}]:= ImageApply[# 0.0&,img]
imgEdge[img_,___]:= ImageApply[# 2&,img]

Sharpen[InverseWaveletTransform[WaveletMapIndexed[imgEdge,dwd]]]

OpenersExampleSubsection11(Spacer1)Energy Comparison  (1)

Compare the cumulative energy in a signal, its wavelet coefficients, and Fourier coefficients:

data = Table[N[2-5t+5 Exp[-500(((t-0.5))^2)]],{t,0,1,1/63}];

ListLinePlot[data]

Compute the ordered cumulative energy in the signal:

cumulativeEnergy[data_]:=Module[{c=Sort[((Flatten[data])^2),Greater]},Accumulate[c]/Total[c]]

ListLinePlot[cumulativeEnergy[data]]

Compute wavelet coefficients and Fourier coefficients:

dwd = DiscreteWaveletTransform[data];

dft = Fourier[data];

The DWT captures more energy with fewer coefficients than the DFT:

ListLinePlot[{cumulativeEnergy[data],cumulativeEnergy[Last/@dwd[Automatic]],cumulativeEnergy[Abs[dft]]},BaseStyle->Thick,PlotStyle->{Red,Blue,Orange},PlotRange->All]

OpenersExampleSubsection12(Spacer1)Denoising  (3)

Perform energy-dependent thresholding:

data = Table[Sin[x]+RandomReal[{-0.1,0.1}],{x,0,2π,0.01}];

ListLinePlot[data]

dwd = DiscreteWaveletTransform[data,SymletWavelet[4],6];

Computing the fraction of energy contained at each refinement level:

efrac= dwd["EnergyFraction"]

Set wavelet coefficients containing less than 1% energy to zero:

eth[x_,ind_]:=If[(ind/.efrac) < 0.01, x*0.,x]/;MemberQ[efrac[[All,1]],ind]
eth[x_,___]:= x

WaveletMapIndexed[eth,dwd];

ListLinePlot[InverseWaveletTransform[%]]

Perform an amplitude-dependent thresholding:

data = Table[N[5Exp[-100(((t-0.5))^2)]+5Exp[-10t]],{t,0,1,1/511}];
noise = RandomVariate[NormalDistribution[0,0.2],Length[data]];

ListLinePlot[data+noise]

dwd = DiscreteWaveletTransform[data+noise,DaubechiesWavelet[4]];

Use (RefLink[WaveletThreshold, paclet:ref/WaveletThreshold]) to perform "Universal" thresholding:

WaveletThreshold[dwd];

ListLinePlot[{InverseWaveletTransform[%],data}]

Use Stein's unbiased risk estimator smoothing:

WaveletThreshold[dwd,"SURE"];

ListLinePlot[{InverseWaveletTransform[%],data}]

Denoise an (RefLink[Image, paclet:ref/Image]):

nimg = ImageEffect[,{"GaussianNoise",0.2}];

dwd = DiscreteWaveletTransform[nimg,BiorthogonalSplineWavelet[5,5]];

Perform "Soft" thresholding with threshold value "SURE" computed adaptively at each level:

wtdwd = WaveletThreshold[dwd,{"Soft","SURELevel"},{1|2|3}];

Invert thresholded coefficients:

{Image[InverseWaveletTransform[wtdwd],ImageSize->All],Image[nimg,ImageSize->All]}

OpenersExampleSubsection13(Spacer1)Frequency Filtering  (1)

Wavelet transforms can be used to filter frequencies:

d1 = Table[Sin[x]+Cos[2x],{x,-2π,2π,((4π)/2047)}];

d2 = Table[((ArcSin[Sin[20x]])/5),{x,-2π,2π,((4π)/2047)}];

ListLinePlot[d1+d2]

To filter out the two signals, first perform a wavelet transform:

dwd = DiscreteWaveletTransform[d1+d2,SymletWavelet[4],6];

Use (RefLink[WaveletListPlot, paclet:ref/WaveletListPlot]) to visualize frequency distribution:

WaveletListPlot[dwd,PlotLayout->"CommonXAxis",DataRange->{-2π,2π}]

To filter low frequencies, keep only the coarse coefficients:

rdwd1 = WaveletMapIndexed[(#*0.0)&,dwd,{___,1}];

{ListLinePlot[d1,PlotLabel->"data"],ListLinePlot[InverseWaveletTransform[rdwd1],PlotLabel->"filtered coarse data"]}

To filter high frequencies, keep only the detail coefficients:

rdwd2 = WaveletMapIndexed[(#*0.0)&,dwd,{___,0}];

{ListLinePlot[d2,PlotLabel->"data"],ListLinePlot[InverseWaveletTransform[rdwd2],PlotLabel->"filtered fine data"]}

OpenersExampleSubsection14(Spacer1)Finance  (3)

Extract the stock price trend for IBM since January 1, 2000:

price = FinancialData["IBM","Jan. 1, 2000"];

DateListPlot[price,Joined->True,Frame->False]

dwd = DiscreteWaveletTransform[price[[All,2]],BiorthogonalSplineWavelet[3,3],4];

The trend of the series is captured in the lowpass filter coefficients:

WaveletListPlot[dwd,PlotLayout->"CommonYAxis"]

Thresholding all detail coefficients and inverting the series gives the trend:

tr = InverseWaveletTransform[WaveletThreshold[dwd,{"Hard",100}]];

DateListPlot[Transpose[{price[[All,1]],tr}],Joined->True,Frame->False]

Detrend a financial series:

price = FinancialData["AAPL","Jan. 1, 2009"];

DateListPlot[price,Joined->True,Frame->False]

dwd = DiscreteWaveletTransform[price[[All,2]],SymletWavelet[2],4,Padding->"Extrapolated"]

Detail coefficients captured the detrended series:

WaveletListPlot[dwd]

Remove the trend by removing the coarse coefficients and inverting:

dtr = InverseWaveletTransform[WaveletMapIndexed[# 0.0&,dwd,{___,0}]];

DateListPlot[Transpose[{price[[All,1]],dtr}],Joined->True]

Study variance of returns in a financial time series:

ret =FinancialData["GE","Return",{{1962,1,1},{1963,1,1},"Day"}];

DateListPlot[ret,PlotRange->All]

Perform a wavelet transform using (RefLink[HaarWavelet, paclet:ref/HaarWavelet]) and (RefLink[SymletWavelet, paclet:ref/SymletWavelet]):

dwd1 = DiscreteWaveletTransform[ret[[All,2]],HaarWavelet[],4];
dwd2 = DiscreteWaveletTransform[ret[[All,2]],SymletWavelet[8],4];

Since the GE return series does not exhibit low-frequency oscillations, higher-scale detail coefficients do not indicate large variations from zero:

WaveletListPlot[{dwd1,dwd2},PlotLayout->"CommonYAxis"]

Although both filters will capture the variance of the series, they distribute it differently because of their approximate bandpass properties:

hvar=Variance[#[[2]]]&/@dwd1[Automatic];

symvar=Variance[#[[2]]]&/@dwd2[Automatic];

(RefLink[SymletWavelet, paclet:ref/SymletWavelet]) isolates features in a certain frequency interval better than (RefLink[HaarWavelet, paclet:ref/HaarWavelet]):

BarChart[Transpose@{hvar,symvar},ChartLabels->{Placed[dwd1[Automatic,"IndexMap"],Axis,Rotate[#,-Pi/4]&],None},ChartLegends->{"Haar Wavelet","Symlet Wavelet"},ChartStyle->{Orange,Green}]

OpenersExampleSection5(Spacer1)Properties & Relations  (15)

(RefLink[DiscreteWaveletPacketTransform, paclet:ref/DiscreteWaveletPacketTransform]) computes the full tree of wavelet coefficients:

dwpt=DiscreteWaveletPacketTransform[{1,1,3,1,1}];

dwpt[{"TreeView",Left}]

(RefLink[DiscreteWaveletTransform, paclet:ref/DiscreteWaveletTransform]) computes a subset of the full tree of coefficients:

dwt=DiscreteWaveletTransform[{1,1,3,1,1}];

dwt[{"TreeView",Left}]

(RefLink[DiscreteWaveletTransform, paclet:ref/DiscreteWaveletTransform]) coefficients halve in length with each level of refinement:

Normal[DiscreteWaveletTransform[{1,2,3,4}]]

Rotated data gives different coefficients:

Normal[DiscreteWaveletTransform[{2,3,4,1}]]

(RefLink[StationaryWaveletTransform, paclet:ref/StationaryWaveletTransform]) coefficients have the same length as the original data:

Normal[StationaryWaveletTransform[{1,2,3,4}]]

Rotated data gives rotated coefficients:

Normal[StationaryWaveletTransform[{2,3,4,1}]]

Multidimensional discrete wavelet transform is related to one-dimensional packet transform:

dwt=DiscreteWaveletTransform[(({{a, b}, {c, d}})),WorkingPrecision->∞];

Simplify[dwt[Automatic]]

dwpt=DiscreteWaveletPacketTransform[{a,b,c,d},WorkingPrecision->∞];

Simplify[dwpt[Automatic]]

For Haar wavelet (default) and data length (2^n), the computed coefficients are identical:

Sort[Expand@Simplify@Flatten[dwt[Automatic,"Values"]]]==Sort[Flatten[Expand[dwpt[Automatic,"Values"]]]]

The default refinement is given by (Floor[(Subscript[log, 2])(n)+(1/2)]):

data=RandomReal[1,{100}];

r = Floor[Log2[Length[data]]+(1/2)]

DiscreteWaveletTransform[data]==DiscreteWaveletTransform[data,Automatic,r]

In higher dimensions:

data=RandomReal[1,{100,10,10}];

r= Floor[Log2[Min[Dimensions[data]]]+(1/2)]

DiscreteWaveletTransform[data]==DiscreteWaveletTransform[data,Automatic,r]

The energy norm is conserved for orthogonal wavelet families:

data=RandomReal[1,{100}];

dwt=DiscreteWaveletTransform[data,Padding->0.];

Norm[data]==Norm[Flatten[Last/@dwt[Automatic]]]

The energy norm is approximately conserved for biorthogonal wavelet families:

data=RandomReal[1,{100}];

dwt=DiscreteWaveletTransform[data,BiorthogonalSplineWavelet[2,4],Padding->0.];

Norm[data]

Norm[Flatten[Last/@dwt[Automatic]]]

The mean of the data is captured at the maximum refinement level of the transform:

data=RandomReal[1,{64}];

dwt = DiscreteWaveletTransform[data,HaarWavelet[]];

Extract the coefficient for the maximum refinement level:

r = dwt["Refinement"]

dwt[ConstantArray[0,{r}]]

Compensate for the (Sqrt[2]) normalization at each refinement level:

%[[1,2,1]]/((((Sqrt[2])))^r)

Mean[data]

The sum of inverse transforms from individual coefficient arrays gives the original data:

data=Table[DiscreteDelta[n],{n,-2,2}]

dwt=DiscreteWaveletTransform[data];

dwt["TreeView"]

Individually inverse transform each wavelet coefficient array:

data1=InverseWaveletTransform[dwt,Automatic,{0,0}]

data2=InverseWaveletTransform[dwt,Automatic,{0,1}]

data3=InverseWaveletTransform[dwt,Automatic,{1}]

The sum gives the original data:

data1+data2+data3

Compute discrete wavelet coefficients for periodic data:

x =Range[8];

dwd=DiscreteWaveletTransform[x,HaarWavelet[]];

J=dwd["Refinement"];

Define filter coefficients to have compact support:

lp=WaveletFilterCoefficients[HaarWavelet[],"PrimalLowpass"];
hp=WaveletFilterCoefficients[HaarWavelet[],"PrimalHighpass"];

a[n_]:= If[1≤n≤Length[lp],lp[[n,2]],0]
b[n_]:= If[1≤n≤Length[hp],hp[[n,2]],0]

Coarse coefficients at level j are given by (Subscript[c, j+1,n])=(Sqrt[2]) (∑_m)(Subscript[a, m-2 n+2]) (Subscript[c, j,m]), with (Subscript[c, 0,n])=(Subscript[x, n]):

SetAttributes[c,Listable]

c[0,n_]:=x[[n]];
c[j_,n_]:=(Sqrt[2]) (∑_(m=-20)^20)a[m-2 n+2] c[j-1,Mod[m,Length[x],1]]

dwd[{___,0},"Values"]==Table[c[j,Range[(2^(J-j))]],{j,1,J}]

Detail coefficients at level j are given by (Subscript[d, j+1,n])=(Sqrt[2]) (∑_m)(Subscript[b, m-2 n+2]) (Subscript[c, j,m]):

SetAttributes[d,Listable];

d[j_,n_]:=(Sqrt[2])(∑_(m=-20)^20)b[m-2 n+2] c[j-1,Mod[m,Length[x],1]]

dwd[{___,1},"Values"]==Table[d[j,Range[(2^(J-j))]],{j,1,J}]

Compute a partial discrete inverse wavelet transform:

x =Range[8];

dwd=DiscreteWaveletTransform[x,HaarWavelet[]];

J=dwd["Refinement"];

Define filter coefficients to have compact support:

lp=WaveletFilterCoefficients[HaarWavelet[],"PrimalLowpass"];
hp=WaveletFilterCoefficients[HaarWavelet[],"PrimalHighpass"];

a[n_]:= If[1≤n≤Length[lp],lp[[n,2]],0]
b[n_]:= If[1≤n≤Length[hp],hp[[n,2]],0]

Coarse coefficients at level j are given:

SetAttributes[c,Listable]

c[0,n_]:=x[[n]];
c[j_,n_]:=c[j,n]=(Sqrt[2]) (∑_(m=-20)^20)a[m-2 n+2] c[j-1,Mod[m,Length[x],1]]

Detail coefficients at level j are given:

SetAttributes[d,Listable];

d[j_,n_]:=d[j,n]=(Sqrt[2])(∑_(m=-20)^20)b[m-2 n+2] c[j-1,Mod[m,Length[x],1]]

Inverse wavelet transform at level j is given by (Subscript[c, j,n])=(Sqrt[2]) ((∑_m)(Subscript[a, n-2 m+2]) (Subscript[c, j+1,n])+(∑_m)(Subscript[b, n-2 m+2]) (Subscript[d, j+1,m])):

SetAttributes[iwt,Listable];

iwt[j_Integer,n_Integer]:=(Sqrt[2])(∑_(m=-20)^20)a[n-2 m+2]c[j+1,Mod[m,(2^(J-(j+1))),1]]  + (Sqrt[2])(∑_(m=-20)^20)b[n-2 m+2]d[j+1,Mod[m,(2^(J-(j+1))),1]]

Reconstruct coarse coefficients {0,0} at refinement level j=2:

iwt[2,Range[2]]==First[dwd[{0,0},"Values"]]

Reconstruct coarse coefficients {0} at refinement level j=1:

iwt[1,Range[4]]==First[dwd[{0},"Values"]]

Compute the dimensions of wavelet coefficients:

dwd = DiscreteWaveletTransform[RandomReal[1,{99}],SymletWavelet[4],3];

fl = Length[WaveletFilterCoefficients[dwd["Wavelet"]]];

At refinement level j, the dimensions of wavelet coefficients are given by (Subscript[wd, j+1])=(Ceiling[(1/2) ((Subscript[wd, j])+fl-2)]), where (Subscript[wd, 0]) represents dimensions of input data:

wd[0] := dwd["DataDimensions"];

wd[j_]:=Ceiling[(1/2) (wd[j-1]+fl-2)]

Compare (Subscript[wd, j]) dimensions with coefficient dimensions in dwd:

Table[j->wd[j],{j,dwd["Refinement"]}]

Length[#[[1]]]->#[[2]]&/@(dwd["Dimensions"])

Compute a Haar discrete wavelet transform in one dimension:

low[v_]:=Partition[v,2].{(1/(Sqrt[2])),(1/(Sqrt[2]))}
high[v_]:=Partition[v,2].{(1/(Sqrt[2])),-(1/(Sqrt[2]))}

HaarDWT[v_]:={{0}->low[v],{1}->high[v]};

Compute {0} and {1} wavelet coefficients:

HaarDWT[{a,b,c,d}]

Compare with (RefLink[DiscreteWaveletTransform, paclet:ref/DiscreteWaveletTransform]):

DiscreteWaveletTransform[{a,b,c,d},HaarWavelet[],1,WorkingPrecision->∞][All]

In two dimensions, a separate filter is applied in each dimension:

f2d[fx_,fy_]:=Composition[Map[fy,#\[Transpose]]&,Map[fx,#\[Transpose]]&]

Lowpass and highpass filters for Haar wavelet:

low[v_]:=Partition[v,2].{(1/(Sqrt[2])),(1/(Sqrt[2]))}
high[v_]:=Partition[v,2].{(1/(Sqrt[2])),-(1/(Sqrt[2]))}

Haar wavelet transform of matrix data:

data = Table[Sin[x y],{x,-2,2,4/63},{y,-2,2,4/63}];

Table[MatrixPlot[f2d[fx,fy][data],PlotLabel->{fx,fy},FrameTicks->None],{fx,{low,high}},{fy,{low,high}}]//Flatten

Compare with (RefLink[DiscreteWaveletTransform, paclet:ref/DiscreteWaveletTransform]) using (RefLink[HaarWavelet, paclet:ref/HaarWavelet]):

dwd=DiscreteWaveletTransform[data,HaarWavelet[],1];

Table[MatrixPlot[Last[p],PlotLabel->First[p],FrameTicks->None],{p,Normal[dwd]}]

Image channels are transformed individually:

dwds=Map[DiscreteWaveletTransform,ColorSeparate[]]

Combine {0} coefficients of separately transformed image channels:

w=Image[Table[First[{0}/.Normal[t]],{t,dwds}],Interleaving->False]

Compare with {0} coefficient of (RefLink[DiscreteWaveletTransform, paclet:ref/DiscreteWaveletTransform]) of the original image:

dwd=DiscreteWaveletTransform[];

{0}/.dwd[All,{"Image","ImageFunction"->Identity}]

The images are identical:

ImageSubtract[w,%]

DWT is similar to (RefLink[LiftingWaveletTransform, paclet:ref/LiftingWaveletTransform]) with extra coefficients needed for padding:

data = Table[2Sin[x]+x/2,{x,0,15,15/63}];

dwt = DiscreteWaveletTransform[data,Automatic,1];
lwt = LiftingWaveletTransform[data,Automatic,1];

WaveletListPlot[dwt,PlotLayout->"CommonYAxis"]

WaveletListPlot[lwt,PlotLayout->"CommonYAxis"]

OpenersExampleSection6(Spacer1)Possible Issues  (1)

Padding can affect the total energy of wavelet coefficients:

data=RandomReal[1,{10}];

dwd1=DiscreteWaveletTransform[data,DaubechiesWavelet[4], Padding->"Fixed"];

Energy is not conserved:

{((Norm[data])^2),((Norm[Flatten[Last/@dwd1[Automatic]]])^2)}

Pad with 0s to ensure energy conservation in the coefficients:

dwd2=DiscreteWaveletTransform[data,DaubechiesWavelet[4],Padding->0];

{((Norm[data])^2),((Norm[Flatten[Last/@dwd2[Automatic]]])^2)}

OpenersExampleSection7(Spacer1)Neat Examples  (1)

Create a padded matrix of data:

data = ArrayPad[IdentityMatrix[4],8,"Reflected"];

ListPlot3D[data,InterpolationOrder->0,Mesh->None,Filling->Axis]

Create a 3D plot of the Haar DWT coefficients:

WaveletPlot3D[wr_]:= Map[First[#]->ListPlot3D[Last[#],InterpolationOrder->0,Mesh->None,Filling->Axis]&,wr[All]]

WaveletPlot3D[DiscreteWaveletTransform[data,HaarWavelet[],2]]

({{DocumentationFooterIconsRelatedFunction.png, ({{See Also}, {(RefLink[InverseWaveletTransform, paclet:ref/InverseWaveletTransform])  ▪  (RefLink[DiscreteWaveletData, paclet:ref/DiscreteWaveletData])  ▪  (RefLink[WaveletThreshold, paclet:ref/WaveletThreshold])  ▪  (RefLink[LiftingWaveletTransform, paclet:ref/LiftingWaveletTransform])  ▪  (RefLink[StationaryWaveletTransform, paclet:ref/StationaryWaveletTransform])  ▪  (RefLink[DiscreteWaveletPacketTransform, paclet:ref/DiscreteWaveletPacketTransform])  ▪  (RefLink[ArrayPad, paclet:ref/ArrayPad])  ▪  (RefLink[WaveletMapIndexed, paclet:ref/WaveletMapIndexed])  ▪  (RefLink[ImagePyramid, paclet:ref/ImagePyramid])}})}})

({{DocumentationFooterIconsRelatedGuide.png, ({{Related Guides}, {▪(RefLinkPlain[Wavelet Analysis, paclet:guide/Wavelets])}, {▪(RefLinkPlain[Fourier Analysis, paclet:guide/FourierAnalysis])}, {▪(RefLinkPlain[Data Transforms and Smoothing, paclet:guide/DataTransformsAndSmoothing])}, {▪(RefLinkPlain[Signal Processing, paclet:guide/SignalProcessing])}, {▪(RefLinkPlain[Summation Transforms, paclet:guide/SummationTransforms])}, {▪(RefLinkPlain[Computer Vision, paclet:guide/ComputerVision])}})}})