DiscreteWaveletTransform[data]
gives the discrete wavelet transform (DWT) of an array of data.
DiscreteWaveletTransform[data,wave]
gives the discrete wavelet transform using the wavelet wave.
DiscreteWaveletTransform[data,wave,r]
gives the discrete wavelet transform using r levels of refinement.
DiscreteWaveletTransform
DiscreteWaveletTransform[data]
gives the discrete wavelet transform (DWT) of an array of data.
DiscreteWaveletTransform[data,wave]
gives the discrete wavelet transform using the wavelet wave.
DiscreteWaveletTransform[data,wave,r]
gives the discrete wavelet transform using r levels of refinement.
Details and Options
- DiscreteWaveletTransform gives a DiscreteWaveletData object representing a tree of wavelet coefficient arrays.
- Properties of the 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:
-
list arbitrary-rank numerical array image arbitrary Image object audio an Audio or sampled Sound object - The resulting wavelet coefficients are arrays of the same depth as the input data.
- The possible wavelets wave include:
-
BattleLemarieWavelet[…] Battle–Lemarié wavelets based on B-spline BiorthogonalSplineWavelet[…] B-spline-based wavelet CoifletWavelet[…] symmetric variant of Daubechies wavelets DaubechiesWavelet[…] the Daubechies wavelets HaarWavelet[…] classic Haar wavelet MeyerWavelet[…] wavelet defined in the frequency domain ReverseBiorthogonalSplineWavelet[…] B-spline-based wavelet (reverse dual and primal) ShannonWavelet[…] sinc function-based wavelet SymletWavelet[…] least asymmetric orthogonal wavelet - The default wave is HaarWavelet[].
- With higher settings for the refinement level r, larger-scale features are resolved.
- The default refinement level r is given by
, where
is the minimum dimension of data. » - The tree of wavelet coefficients at level
consists of coarse coefficients
and detail coefficients
, with
representing the input data. - The forward transform is given by
and
. » - The inverse transform is given by
. » - The
are lowpass filter coefficients and
are highpass filter coefficients that are defined for each wavelet family. - The dimensions of
and
are given by
, where
is the input data dimension and fl is the filter length for the corresponding wspec. » - The following options can be given:
-
Method Automatic method to use Padding "Periodic" how to extend data beyond boundaries WorkingPrecision MachinePrecision precision to use in internal computations - The settings for Padding are the same as those available in ArrayPad.
- InverseWaveletTransform gives the inverse transform.
Examples
open all close allBasic Examples (3)
Compute a discrete wavelet transform using the HaarWavelet:
DiscreteWaveletTransform[{56, 40, 8, 24, 48, 48, 40, 16}]Use Normal to view all coefficients:
Normal[%]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 Image object:
dwd = DiscreteWaveletTransform[[image], Automatic, 2]Use dwd[…,"Image"] to extract coefficient images:
dwd[All, "Image"]Compute the inverse transform:
InverseWaveletTransform[dwd]Scope (36)
Basic Uses (6)
dwd = DiscreteWaveletTransform[{0, 0, 1, 0, 0}]The resulting DiscreteWaveletData represents a tree of transform coefficients:
dwd["TreeView"]The inverse transform reconstructs the input:
InverseWaveletTransform[dwd]Useful properties can be extracted from the 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 Normal to get all wavelet coefficients explicitly:
dwd = DiscreteWaveletTransform[Range[8]];Normal[dwd]Also use All as an argument to get all coefficients:
dwd[All]Use 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 Automatic coefficients are used by default in functions like 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"]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];{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]HaarWavelet (default):
dwd = DiscreteWaveletTransform[data, HaarWavelet[], 3];WaveletListPlot[dwd, PlotLayout -> "CommonYAxis", Filling -> Axis]data = Table[Sin[t^2], {t, -3π, 3π, 0.01}];dwd = DiscreteWaveletTransform[data, DaubechiesWavelet[2], 3];WaveletListPlot[dwd, PlotLayout -> "CommonYAxis", Filling -> Axis]data = Table[Sin[t^2], {t, -3π, 3π, 0.01}];dwd = DiscreteWaveletTransform[data, BattleLemarieWavelet[3], 3];WaveletListPlot[dwd, PlotLayout -> "CommonYAxis", Filling -> Axis]data = Table[Sin[t^2], {t, -3π, 3π, 0.01}];dwd = DiscreteWaveletTransform[data, BiorthogonalSplineWavelet[4, 2], 3];WaveletListPlot[dwd, PlotLayout -> "CommonYAxis", Filling -> Axis]data = Table[Sin[t^2], {t, -3π, 3π, 0.01}];dwd = DiscreteWaveletTransform[data, CoifletWavelet[2], 3];WaveletListPlot[dwd, PlotLayout -> "CommonYAxis", Filling -> Axis]data = Table[Sin[t^2], {t, -3π, 3π, 0.01}];dwd = DiscreteWaveletTransform[data, MeyerWavelet[3], 3];WaveletListPlot[dwd, PlotLayout -> "CommonYAxis", Filling -> Axis]ReverseBiorthogonalSplineWavelet:
data = Table[Sin[t^2], {t, -3π, 3π, 0.01}];dwd = DiscreteWaveletTransform[data, ReverseBiorthogonalSplineWavelet[4, 2], 3];WaveletListPlot[dwd, PlotLayout -> "CommonYAxis", Filling -> Axis]data = Table[Sin[t^2], {t, -3π, 3π, 0.01}];dwd = DiscreteWaveletTransform[data, ShannonWavelet[8], 3];WaveletListPlot[dwd, PlotLayout -> "CommonYAxis", Filling -> Axis]data = Table[Sin[t^2], {t, 0, 3π, 0.01}];dwd = DiscreteWaveletTransform[data, SymletWavelet[3], 3];WaveletListPlot[dwd, PlotLayout -> "CommonYAxis", Filling -> Axis]Vector Data (6)
Plot the coefficients over a common horizontal axis using 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 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]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], {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, Inequality[30, Less, n, LessEqual, 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}]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//MatrixFormUse WaveletMatrixPlot to visualize the different wavelet coefficients:
dwd = DiscreteWaveletTransform[DiamondMatrix[32], Automatic, 2]WaveletMatrixPlot[dwd, ImageSize -> Small]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]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]Image Data (4)
Transform an Image object:
img = Image[DiamondMatrix[All, {64, 64}]]dwd = DiscreteWaveletTransform[img, HaarWavelet[], 3]The inverse transform yields a reconstructed Image object:
InverseWaveletTransform[dwd]Wavelet coefficients are normally given as lists of data for each image channel:
dwd = DiscreteWaveletTransform[[image], HaarWavelet[], 2];Dimensions[{0, 0} /. Normal[dwd]]Get all coefficients as Image objects instead:
dwd[All, {"Image", ImageSize -> 80}]Get raw 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 Image object:
dwd[{0, 1}, {"Image", "Inverse"}]Plot coefficients used in the inverse transform in a hierarchical grid using WaveletImagePlot:
dwd = DiscreteWaveletTransform[[image], HaarWavelet[], 3];WaveletImagePlot[dwd, BaseStyle -> Red]Image wavelet coefficients lie outside the valid range of ImageType:
img = [image];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"->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}]}Sound Data (3)
Transform a Sound object:
snd = ExampleData[{"Sound", "Apollo11ReturnSafely"}]dwd = DiscreteWaveletTransform[snd]The inverse transform yields a reconstructed 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 Sound object:
dwd[{0, 0, 1}, "Sound"]Inverse transform of {0,0,1} coefficient as a Sound object:
dwd[{0, 0, 1}, {"Sound", "Inverse"}]Browse all coefficients using a MenuView:
dwd = DiscreteWaveletTransform[ExampleData[{"Sound", "Clarinet"}]];MenuView[dwd[All, "Sound"]]Generalizations & Extensions (3)
DiscreteWaveletTransform works on arrays of symbolic quantities:
dwd = DiscreteWaveletTransform[{a, b, c, d}, WorkingPrecision -> ∞];Normal[dwd]//SimplifyInverse transform recovers the input exactly:
InverseWaveletTransform[dwd]//SimplifySpecify any internal working precision:
dwd = DiscreteWaveletTransform[{1, 2, 5, 2}, WorkingPrecision -> 20];Normal[dwd]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]Options (5)
Padding (2)
The settings for Padding are the same as the methods for ArrayPad, including "Periodic":
ArrayPad[{a, b, c}, 4, "Periodic"]ArrayPad[{a, b, c}, 4, "Reversed"]ArrayPad[{a, b, c}, 4, "ReversedNegation"]ArrayPad[{a, b, c}, 4, "Reflected"]ArrayPad[{a, b, c}, 3, "ReflectedDifferences"]ArrayPad[{a, b, c}, 4, "ReversedDifferences"]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]WorkingPrecision (3)
By default, WorkingPrecision->MachinePrecision is used:
data = RandomInteger[1, {10}];dwd1 = DiscreteWaveletTransform[data]dwd2 = DiscreteWaveletTransform[data, WorkingPrecision -> MachinePrecision]dwd1 == dwd2Use 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 WorkingPrecision->∞ for exact computation:
data = RandomInteger[10, {4}];Normal@DiscreteWaveletTransform[data, WorkingPrecision -> ∞]//SimplifyApplications (11)
Wavelet Compression (1)
Compress data by finding a representation with few nonzero coefficients:
data = Table[t^3, {t, -1, 1, 2 / 2047}];ListLinePlot[data]SymletWavelet[n] has n vanishing moments and represents polynomials of degree n:
dwd = Table[DiscreteWaveletTransform[data, SymletWavelet[n], Padding -> "Extrapolated"], {n, 5}];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}]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"]dwd = DiscreteWaveletTransform[[image], 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]]]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]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_, ___] := xWaveletMapIndexed[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 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 Image:
nimg = ImageEffect[[image], {"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]}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 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"]}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[QuantityMagnitude[price["Values"]], 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["Times"], tr}], Joined -> True, Frame -> False]price = FinancialData["AAPL", "Jan. 1, 2009"];DateListPlot[price, Joined -> True, Frame -> False]dwd = DiscreteWaveletTransform[QuantityMagnitude[price["Values"]], 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["Times"], 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 HaarWavelet and SymletWavelet:
dwd1 = DiscreteWaveletTransform[QuantityMagnitude[ret["Values"]], HaarWavelet[], 4];
dwd2 = DiscreteWaveletTransform[QuantityMagnitude[ret["Values"]], 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];SymletWavelet isolates features in a certain frequency interval better than HaarWavelet:
BarChart[Transpose@{hvar, symvar}, ChartLabels -> {Placed[dwd1[Automatic, "IndexMap"], Axis, Rotate[#, -Pi / 4]&], None}, ChartLegends -> {"Haar Wavelet", "Symlet Wavelet"}, ChartStyle -> {Orange, Green}]Properties & Relations (15)
DiscreteWaveletPacketTransform computes the full tree of wavelet coefficients:
dwpt = DiscreteWaveletPacketTransform[{1, 1, 3, 1, 1}];dwpt[{"TreeView", Left}]DiscreteWaveletTransform computes a subset of the full tree of coefficients:
dwt = DiscreteWaveletTransform[{1, 1, 3, 1, 1}];dwt[{"TreeView", Left}]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}]]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
, the computed coefficients are identical:
Sort[Expand@Simplify@Flatten[dwt[Automatic, "Values"]]] == Sort[Flatten[Expand[dwpt[Automatic, "Values"]]]]The default refinement is given by
:
data = RandomReal[1, {100}];r = Floor[Log2[Length[data]] + (1/2)]DiscreteWaveletTransform[data] == DiscreteWaveletTransform[data, Automatic, r]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
normalization at each refinement level:
%[[1, 2, 1]] / (Sqrt[2])^rMean[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 + data3Compute 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
are given by
, with
:
SetAttributes[c, Listable]c[0, n_] := x[[n]];
c[j_, n_] := Sqrt[2] Underoverscript[∑, 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
are given by
:
SetAttributes[d, Listable];d[j_, n_] := Sqrt[2]Underoverscript[∑, 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
are given:
SetAttributes[c, Listable]c[0, n_] := x[[n]];
c[j_, n_] := c[j, n] = Sqrt[2] Underoverscript[∑, m = -20, 20]a[m - 2 n + 2] c[j - 1, Mod[m, Length[x], 1]]Detail coefficients at level
are given:
SetAttributes[d, Listable];d[j_, n_] := d[j, n] = Sqrt[2]Underoverscript[∑, m = -20, 20]b[m - 2 n + 2] c[j - 1, Mod[m, Length[x], 1]]Inverse wavelet transform at level
is given by
:
SetAttributes[iwt, Listable];iwt[j_Integer, n_Integer] := Sqrt[2]Underoverscript[∑, m = -20, 20]a[n - 2 m + 2]c[j + 1, Mod[m, 2^J - (j + 1), 1]] + Sqrt[2]Underoverscript[∑, 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
:
iwt[2, Range[2]] == First[dwd[{0, 0}, "Values"]]Reconstruct coarse coefficients {0} at refinement level
:
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
, the dimensions of wavelet coefficients are given by
, where
represents dimensions of input data:
wd[0] := dwd["DataDimensions"];wd[j_] := Ceiling[(1/2) (wd[j - 1] + fl - 2)]Compare
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 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, #]&, Map[fx, #]&]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}}]//FlattenCompare with DiscreteWaveletTransform using 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[[image]]]Combine {0} coefficients of separately transformed image channels:
w = Image[Table[First[{0} /. Normal[t]], {t, dwds}], Interleaving -> False]Compare with {0} coefficient of DiscreteWaveletTransform of the original image:
dwd = DiscreteWaveletTransform[[image]];{0} /. dwd[All, {"Image", "ImageFunction" -> Identity}]ImageSubtract[w, %]DWT is similar to 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"]Possible Issues (1)
Padding can affect the total energy of wavelet coefficients:
data = RandomReal[1, {10}];dwd1 = DiscreteWaveletTransform[data, DaubechiesWavelet[4], Padding -> "Fixed"];{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}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]]Text
Wolfram Research (2010), DiscreteWaveletTransform, Wolfram Language function, https://reference.wolfram.com/language/ref/DiscreteWaveletTransform.html (updated 2017).
CMS
Wolfram Language. 2010. "DiscreteWaveletTransform." Wolfram Language & System Documentation Center. Wolfram Research. Last Modified 2017. https://reference.wolfram.com/language/ref/DiscreteWaveletTransform.html.
APA
Wolfram Language. (2010). DiscreteWaveletTransform. Wolfram Language & System Documentation Center. Retrieved from https://reference.wolfram.com/language/ref/DiscreteWaveletTransform.html
BibTeX
@misc{reference.wolfram_2026_discretewavelettransform, author="Wolfram Research", title="{DiscreteWaveletTransform}", year="2017", howpublished="\url{https://reference.wolfram.com/language/ref/DiscreteWaveletTransform.html}", note=[Accessed: 13-June-2026]}
BibLaTeX
@online{reference.wolfram_2026_discretewavelettransform, organization={Wolfram Research}, title={DiscreteWaveletTransform}, year={2017}, url={https://reference.wolfram.com/language/ref/DiscreteWaveletTransform.html}, note=[Accessed: 13-June-2026]}