---
title: "StationaryWaveletTransform"
language: "en"
type: "Symbol"
summary: "StationaryWaveletTransform[data] gives the stationary wavelet transform (SWT) of an array of data. StationaryWaveletTransform[data, wave] gives the stationary wavelet transform using the wavelet wave. StationaryWaveletTransform[data, wave, r] gives the stationary wavelet transform using r levels of refinement."
keywords: 
- wavelet
- discrete wavelet
- modwt
- imodwt
- swt
- iswt
- sdwt
- maximum overlap wavelet transform
- stationary wavelet transform
- redundant wavelet transform
- algorithme a trous
- quasi-continuous wavelet transform
- shift invariant wavelet transform
- cycle spinning
- undecimated wavelet transform
- Coiflet
- biorthogonal spline wavelet
- biorthogonal wavelet
- Haar transform
- Walsh transform
- least asymmetric wavelet
- Shannon wavelet
- spline wavelet
- Battle-Lemarie
- Daubechies
- Meyer
canonical_url: "https://reference.wolfram.com/language/ref/StationaryWaveletTransform.html"
source: "Wolfram Language Documentation"
related_guides: 
  - 
    title: "Wavelet Analysis"
    link: "https://reference.wolfram.com/language/guide/Wavelets.en.md"
  - 
    title: "Signal Transforms"
    link: "https://reference.wolfram.com/language/guide/SignalTransforms.en.md"
related_functions: 
  - 
    title: "InverseWaveletTransform"
    link: "https://reference.wolfram.com/language/ref/InverseWaveletTransform.en.md"
  - 
    title: "DiscreteWaveletData"
    link: "https://reference.wolfram.com/language/ref/DiscreteWaveletData.en.md"
  - 
    title: "WaveletMapIndexed"
    link: "https://reference.wolfram.com/language/ref/WaveletMapIndexed.en.md"
  - 
    title: "WaveletThreshold"
    link: "https://reference.wolfram.com/language/ref/WaveletThreshold.en.md"
  - 
    title: "DiscreteWaveletTransform"
    link: "https://reference.wolfram.com/language/ref/DiscreteWaveletTransform.en.md"
  - 
    title: "StationaryWaveletPacketTransform"
    link: "https://reference.wolfram.com/language/ref/StationaryWaveletPacketTransform.en.md"
---
# StationaryWaveletTransform

StationaryWaveletTransform[data] gives the stationary wavelet transform (SWT) of an array of data.

StationaryWaveletTransform[data, wave] gives the stationary wavelet transform using the wavelet wave.

StationaryWaveletTransform[data, wave, r] gives the stationary wavelet transform using r levels of refinement.

## Details and Options

* ``StationaryWaveletTransform`` is similar to ``DiscreteWaveletTransform`` except that no subsampling occurs at any refinement level and the resulting coefficient arrays all have the same dimensions as the original data.

* ``StationaryWaveletTransform`` gives a ``DiscreteWaveletData`` object.

* 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 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 $⌊Log2(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``.

[image]

* The forward transform is given by $Subscript[c, j + 1, n] = Underoverscript[∑, m = 1, f]Subscript[a, m] Subscript[c, j, n - 2^j (1 - m mod l)]$ and $Subscript[d, j + 1, n] = Underoverscript[∑, m = 1, f]Subscript[b, m] Subscript[c, j, n - 2^j (1 - m mod l)]$, where $f$ is the filter length for the corresponding ``wspec`` and $l$ is the length of input ``data``.  »

* The inverse transform is given by $Subscript[c, j, n] = Underoverscript[∑, m = 1, f]Subscript[a, m] Subscript[c, j + 1, 2^j ( m mod d - 1) + n] + Subscript[b, m] Subscript[d, j + 1, 2^j (m mod d - 1) + n]$.  »

* 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 the same as input ``data`` dimensions.

* The following options can be given:

|                   |                  |                                           |
| ----------------- | ---------------- | ----------------------------------------- |
| Method            | Automatic        | method to use                             |
| WorkingPrecision  | MachinePrecision | precision to use in internal computations |

* ``StationaryWaveletTransform`` uses periodic padding of data.

* ``InverseWaveletTransform`` gives the inverse transform.

---

## Examples (58)

### Basic Examples (3)

Compute a stationary wavelet transform using the ``HaarWavelet`` :

```wl
In[1]:= StationaryWaveletTransform[{56, 40, 8, 24, 48, 48, 40, 16}]

Out[1]= DiscreteWaveletData[«SWT», <3>, {8}]
```

Use ``Normal`` to view all coefficients:

```wl
In[2]:= Normal[%]

Out[2]= {{0} -> {36., 48., 24., 16., 36., 48., 44., 28.}, {1} -> {20., -8., -16., 8., 12., 0., -4., -12.}, {0, 0} -> {40., 38., 30., 32., 30., 32., 40., 38.}, {0, 1} -> {-4., 10., -6., -16., 6., 16., 4., -10.}, {0, 0, 0} -> {35., 35., 35., 35., 35., 35., 35., 35.}, {0, 0, 1} -> {5., 3., -5., -3., -5., -3., 5., 3.}}
```

---

Transform an audio signal:

```wl
In[1]:= a = Audio["ExampleData/rule30.wav"]

Out[1]= \!\(\*AudioBox["![Audio Player: ExampleData/rule30.wav](audio://content-v2rs7)"]\)

In[2]:= dwd = StationaryWaveletTransform[a, Automatic, 3]

Out[2]= DiscreteWaveletData[<<SWT>>, <3>, {79380}]
```

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

```wl
In[3]:= dwd[All, "Audio"]

Out[3]= {{0} -> \!\(\*AudioBox["![Embedded Audio Player](audio://content-h08z0)"]\), {1} -> \!\(\*AudioBox["![Embedded Audio Player](audio://content-m5wdo)"]\), {0, 0} -> \!\(\*AudioBox["![Embedded Audio Player](audio://content-fnm3v)"]\), {0, 1} -> \!\(\*AudioBox["![Embedded Audio Player](audio://content-h7dt4)"]\), {0, 0, 0} -> \!\(\*AudioBox["![Embedded Audio Player](audio://content-vu72x)"]\), {0, 0, 1} -> \!\(\*AudioBox["![Embedded Audio Player](audio://content-c8lg0)"]\)}
```

Verify lengths of all coefficient signals:

```wl
In[4]:= AudioLength[#[[2]]]& /@ %

Out[4]= {Quantity[79380, "Samples"], Quantity[79380, "Samples"], Quantity[79380, "Samples"], Quantity[79380, "Samples"], Quantity[79380, "Samples"], Quantity[79380, "Samples"]}
```

Compute the inverse transform:

```wl
In[5]:= InverseWaveletTransform[dwd]

Out[5]= \!\(\*AudioBox["![Embedded Audio Player](audio://content-3tlpw)"]\)
```

---

Transform an ``Image`` object:

```wl
In[1]:= dwd = StationaryWaveletTransform[[image], Automatic, 2]

Out[1]= DiscreteWaveletData[«SWT», <2>, {107, 150}]
```

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

```wl
In[2]:= dwd[All, {"Image", ImageSize -> 80}]

Out[2]= {{0} -> [image], {1} -> [image], {2} -> [image], {3} -> [image], {0, 0} -> [image], {0, 1} -> [image], {0, 2} -> [image], {0, 3} -> [image]}
```

Compute the inverse transform:

```wl
In[3]:= InverseWaveletTransform[dwd]

Out[3]= [image]
```

### Scope (34)

#### Basic Uses (6)

Compute a stationary wavelet transform:

```wl
In[1]:= dwd = StationaryWaveletTransform[{0, 0, 1, 0, 0}]

Out[1]= DiscreteWaveletData[<<SWT>>, <2>, {5}]
```

The resulting ``DiscreteWaveletData`` represents a tree of transform coefficients:

```wl
In[2]:= dwd["TreeView"]

Out[2]= [image]
```

The inverse transform reconstructs the input:

```wl
In[3]:= InverseWaveletTransform[dwd]

Out[3]= {0., 0., 1., 0., 0.}
```

---

Useful properties can be extracted from the ``DiscreteWaveletData`` object:

```wl
In[1]:= dwd = StationaryWaveletTransform[RandomReal[1, {16}], DaubechiesWavelet[4], 2]

Out[1]= DiscreteWaveletData[«SWT», <2>, {16}]
```

Get a full list of properties:

```wl
In[2]:= dwd["Properties"]

Out[2]= {"BasisIndex", "DataChannels", "DataDimensions", "DataWrapper", "Dimensions", "EnergyFraction", "ListPlot", "Padding", "Properties", "Refinement", "ThresholdTable", "ThresholdValues", "Transform", "TreeView", "Wavelet", "WaveletIndex"}
```

Get data and coefficient dimensions:

```wl
In[3]:= dwd["DataDimensions"]

Out[3]= {16}

In[4]:= dwd["Dimensions"]

Out[4]= {{0} -> {16}, {1} -> {16}, {0, 0} -> {16}, {0, 1} -> {16}}
```

---

Use ``Normal`` to get all wavelet coefficients explicitly:

```wl
In[1]:= dwd = StationaryWaveletTransform[Range[4]];

In[2]:= Normal[dwd]

Out[2]= {{0} -> {2.5, 1.5, 2.5, 3.5}, {1} -> {-1.5, 0.5, 0.5, 0.5}, {0, 0} -> {2.5, 2.5, 2.5, 2.5}, {0, 1} -> {0., -1., 0., 1.}}
```

Also use ``All`` as an argument to get all coefficients:

```wl
In[3]:= dwd[All]

Out[3]= {{0} -> {2.5, 1.5, 2.5, 3.5}, {1} -> {-1.5, 0.5, 0.5, 0.5}, {0, 0} -> {2.5, 2.5, 2.5, 2.5}, {0, 1} -> {0., -1., 0., 1.}}
```

Use ``Automatic`` to get only the coefficients used in the inverse transform:

```wl
In[4]:= dwd[Automatic]

Out[4]= {{1} -> {-1.5, 0.5, 0.5, 0.5}, {0, 1} -> {0., -1., 0., 1.}, {0, 0} -> {2.5, 2.5, 2.5, 2.5}}
```

---

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

```wl
In[1]:= dwd = StationaryWaveletTransform[Range[4], HaarWavelet[], 2];

In[2]:= dwd["TreeView"]

Out[2]= [image]

In[3]:= dwd["IndexMap"]

Out[3]= {{0}, {1}, {0, 0}, {0, 1}}
```

Extract specific coefficient arrays:

```wl
In[4]:= dwd[{0}]

Out[4]= {{0} -> {2.5, 1.5, 2.5, 3.5}}

In[5]:= dwd[{0, 0}]

Out[5]= {{0, 0} -> {2.5, 2.5, 2.5, 2.5}}
```

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

```wl
In[6]:= dwd[{{0}, {0, 1}}]

Out[6]= {{0} -> {2.5, 1.5, 2.5, 3.5}, {0, 1} -> {0., -1., 0., 1.}}
```

Extract all coefficients whose wavelet indexes match a pattern:

```wl
In[7]:= dwd[{_}]

Out[7]= {{0} -> {2.5, 1.5, 2.5, 3.5}, {1} -> {-1.5, 0.5, 0.5, 0.5}}

In[8]:= dwd[{{_, 0}, {_, 1}}]

Out[8]= {{0, 0} -> {2.5, 2.5, 2.5, 2.5}, {0, 1} -> {0., -1., 0., 1.}}
```

---

The ``Automatic`` coefficients are used by default in functions like ``WaveletListPlot`` :

```wl
In[1]:= dwd = StationaryWaveletTransform[Table[Sin[x ^ 2], {x, 0, 10, 0.2}], Automatic, 4];

In[2]:= First /@ dwd[Automatic]

Out[2]= {{1}, {0, 1}, {0, 0, 1}, {0, 0, 0, 1}, {0, 0, 0, 0}}

In[3]:= WaveletListPlot[dwd, FrameTicks -> Full]

Out[3]= [image]
```

---

Use a higher refinement level to increase the frequency resolution:

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

In[2]:= ListLinePlot[data]

Out[2]= [image]
```

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

```wl
In[3]:= dwt1 = StationaryWaveletTransform[data, DaubechiesWavelet[4], 3];

In[4]:= WaveletListPlot[dwt1, PlotLayout -> "CommonYAxis"]

Out[4]= [image]
```

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

```wl
In[5]:= dwt2 = StationaryWaveletTransform[data, DaubechiesWavelet[4], 4];

In[6]:= WaveletListPlot[dwt2, PlotLayout -> "CommonYAxis"]

Out[6]= [image]
```

#### Wavelet Families (10)

Compute the stationary wavelet transform using different wavelet families:

```wl
In[1]:= data = Table[Sin[x ^ 2], {x, 0, 10, 0.02}];

In[2]:=
dwd1 = StationaryWaveletTransform[data, DaubechiesWavelet[4], 3];
dwd2 = StationaryWaveletTransform[data, SymletWavelet[4], 3];
```

Compare the coefficients:

```wl
In[3]:= {WaveletListPlot[dwd1, PlotLayout -> "CommonXAxis"], WaveletListPlot[dwd2, PlotLayout -> "CommonXAxis"]}

Out[3]= {[image], [image]}
```

---

Use different families of wavelets to capture different features:

```wl
In[1]:= data = Table[4 Exp[-100 (t - 0.5) ^ 2]  + Sin[5Pi t], {t, 0, 1, 0.01}];

In[2]:= ListLinePlot[data]

Out[2]= [image]
```

``HaarWavelet`` (default):

```wl
In[3]:= dwd = StationaryWaveletTransform[data, HaarWavelet[], 3];

In[4]:= WaveletListPlot[dwd, PlotLayout -> "CommonYAxis", Filling -> Axis]

Out[4]= [image]
```

---

``DaubechiesWavelet``:

```wl
In[1]:= data = Table[4 Exp[-100 (t - 0.5) ^ 2]  + Sin[5Pi t], {t, 0, 1, 0.01}];

In[2]:= dwd = StationaryWaveletTransform[data, DaubechiesWavelet[2], 3];

In[3]:= WaveletListPlot[dwd, PlotLayout -> "CommonYAxis", Filling -> Axis]

Out[3]= [image]
```

---

``BattleLemarieWavelet`` :

```wl
In[1]:= data = Table[4 Exp[-100 (t - 0.5) ^ 2]  + Sin[5Pi t], {t, 0, 1, 0.01}];

In[2]:= dwd = StationaryWaveletTransform[data, BattleLemarieWavelet[3], 3];

In[3]:= WaveletListPlot[dwd, PlotLayout -> "CommonYAxis", Filling -> Axis]

Out[3]= [image]
```

---

``BiorthogonalSplineWavelet`` :

```wl
In[1]:= data = Table[4 Exp[-100 (t - 0.5) ^ 2]  + Sin[5Pi t], {t, 0, 1, 0.01}];

In[2]:= dwd = StationaryWaveletTransform[data, BiorthogonalSplineWavelet[4, 2], 3];

In[3]:= WaveletListPlot[dwd, PlotLayout -> "CommonYAxis", Filling -> Axis]

Out[3]= [image]
```

---

``CoifletWavelet`` :

```wl
In[1]:= data = Table[4 Exp[-100 (t - 0.5) ^ 2]  + Sin[5Pi t], {t, 0, 1, 0.01}];

In[2]:= dwd = StationaryWaveletTransform[data, CoifletWavelet[2], 3];

In[3]:= WaveletListPlot[dwd, PlotLayout -> "CommonYAxis", Filling -> Axis]

Out[3]= [image]
```

---

``MeyerWavelet`` :

```wl
In[1]:= data = Table[4 Exp[-100 (t - 0.5) ^ 2]  + Sin[5Pi t], {t, 0, 1, 0.01}];

In[2]:= dwd = StationaryWaveletTransform[data, MeyerWavelet[3], 3];

In[3]:= WaveletListPlot[dwd, PlotLayout -> "CommonYAxis", Filling -> Axis]

Out[3]= [image]
```

---

``ReverseBiorthogonalSplineWavelet`` :

```wl
In[1]:= data = Table[4 Exp[-100 (t - 0.5) ^ 2]  + Sin[5Pi t], {t, 0, 1, 0.01}];

In[2]:= dwd = StationaryWaveletTransform[data, ReverseBiorthogonalSplineWavelet[4, 2], 3];

In[3]:= WaveletListPlot[dwd, PlotLayout -> "CommonYAxis", Filling -> Axis]

Out[3]= [image]
```

---

``ShannonWavelet`` :

```wl
In[1]:= data = Table[4 Exp[-100 (t - 0.5) ^ 2]  + Sin[5Pi t], {t, 0, 1, 0.01}];

In[2]:= dwd = StationaryWaveletTransform[data, ShannonWavelet[8], 3];

In[3]:= WaveletListPlot[dwd, PlotLayout -> "CommonYAxis", Filling -> Axis]

Out[3]= [image]
```

---

``SymletWavelet`` :

```wl
In[1]:= data = Table[4 Exp[-100 (t - 0.5) ^ 2]  + Sin[5Pi t], {t, 0, 1, 0.01}];

In[2]:= dwd = StationaryWaveletTransform[data, SymletWavelet[3], 3];

In[3]:= WaveletListPlot[dwd, PlotLayout -> "CommonYAxis", Filling -> Axis]

Out[3]= [image]
```

#### Vector Data (6)

Plot the coefficients over a common horizontal axis using ``WaveletListPlot`` :

```wl
In[1]:= dwd = StationaryWaveletTransform[Table[Sin[x ^ 2], {x, 0, 10, 0.02}], Automatic, 3];

In[2]:= WaveletListPlot[dwd, FrameTicks -> Full]

Out[2]= [image]
```

Plot against a common vertical axis:

```wl
In[3]:= WaveletListPlot[dwd, PlotLayout -> "CommonYAxis"]

Out[3]= [image]
```

---

Visualize coefficients as a function of time and refinement level using ``WaveletScalogram`` :

```wl
In[1]:= dwd = StationaryWaveletTransform[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:

```wl
In[2]:= WaveletScalogram[dwd, All]

Out[2]= [image]
```

---

Constant data:

```wl
In[1]:= data = Table[1, {x, 0, 10, 0.02}];

In[2]:= ListLinePlot[data]

Out[2]= [image]
```

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

```wl
In[3]:= dwd = StationaryWaveletTransform[data, DaubechiesWavelet[4], 3];

In[4]:= WaveletListPlot[dwd, All, PlotLayout -> "CommonYAxis", Filling -> Axis]

Out[4]= [image]
```

---

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

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

In[2]:= ListLinePlot[data]

Out[2]= [image]
```

Only the first detail coefficient ``{1}`` is nonzero:

```wl
In[3]:= dwd = StationaryWaveletTransform[data, Automatic, 3];

In[4]:= WaveletListPlot[dwd, All, PlotLayout -> "CommonYAxis"]

Out[4]= [image]
```

---

Data with large discontinuities:

```wl
In[1]:= data = Table[Piecewise[{{1, 1 < x < 3.1}}, 0], {x, 0, 4, 0.02}];

In[2]:= ListLinePlot[data]

Out[2]= [image]
```

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

```wl
In[3]:= dwd = StationaryWaveletTransform[data, Automatic, 3];

In[4]:= WaveletListPlot[dwd, {0..}, FrameTicks -> Full]

Out[4]= [image]
```

Detail coefficients are sensitive to discontinuities:

```wl
In[5]:= WaveletListPlot[dwd, Except[{0..}], FrameTicks -> Full]

Out[5]= [image]
```

---

Data with both spatial and frequency structure:

```wl
In[1]:= data = Table[Piecewise[{{5, n <= 30}, {2 + (-1)^n, Inequality[30, Less, n, LessEqual, 60]}, {5, 60 < n}}], {n, 90}];

In[2]:= ListLinePlot[data, PlotRange -> {0, 5}]

Out[2]= [image]
```

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

```wl
In[3]:= dwd = StationaryWaveletTransform[data, Automatic, 3];

In[4]:= WaveletListPlot[dwd, {0..}, FrameTicks -> Full]

Out[4]= [image]
```

The first detail coefficient identifies the oscillatory region:

```wl
In[5]:= WaveletListPlot[dwd, {1, 0...}, FrameTicks -> Full]

Out[5]= [image]
```

All coefficients on a common vertical axis:

```wl
In[6]:= WaveletListPlot[dwd, All, PlotLayout -> "CommonYAxis"]

Out[6]= [image]
```

#### Matrix Data (5)

Compute a two-dimensional stationary wavelet transform:

```wl
In[1]:=
dwd = StationaryWaveletTransform[(⁠|   |   |   |   |   |
| - | - | - | - | - |
| 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 |⁠)]

Out[1]= DiscreteWaveletData[<<SWT>>, <2>, {5, 5}]
```

View the tree of wavelet coefficients:

```wl
In[2]:= dwd[{"TreeView", Left}]

Out[2]= [image]
```

Inverse transform to get back the original signal:

```wl
In[3]:= InverseWaveletTransform[dwd]//Chop//MatrixForm

Out[3]//MatrixForm=
(⁠|    |    |    |    |    |
| -- | -- | -- | -- | -- |
| 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  |⁠)
```

---

Use ``dwd[…, "MatrixPlot"]`` to visualize each coefficient as a ``MatrixPlot`` :

```wl
In[1]:= dwd = StationaryWaveletTransform[DiamondMatrix[32], Automatic, 1]

Out[1]= DiscreteWaveletData[«SWT», <1>, {65, 65}]

In[2]:= dwd[All, "MatrixPlot"]

Out[2]= {{0} -> [image], {1} -> [image], {2} -> [image], {3} -> [image]}
```

Visualize wavelet coefficients at higher refinement levels:

```wl
In[3]:= dwd2 = StationaryWaveletTransform[DiamondMatrix[32], Automatic, 2];

In[4]:= dwd2[All, "MatrixPlot"]

Out[4]= {{0} -> [image], {1} -> [image], {2} -> [image], {3} -> [image], {0, 0} -> [image], {0, 1} -> [image], {0, 2} -> [image], {0, 3} -> [image]}
```

---

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

```wl
In[1]:= Tuples[{0, 1}, 2] /. {0 -> "lowpass", 1 -> "highpass"}

Out[1]= {{"lowpass", "lowpass"}, {"lowpass", "highpass"}, {"highpass", "lowpass"}, {"highpass", "highpass"}}
```

Interpreting these vectors as binary digit expansions, you get wavelet index numbers:

```wl
In[2]:= FromDigits[#, 2]& /@ Tuples[{0, 1}, 2]

Out[2]= {0, 1, 2, 3}
```

---

Get the lowpass and highpass filters for a Haar wavelet:

```wl
In[1]:= {lp, hp} = Map[Last, WaveletFilterCoefficients[HaarWavelet[], {"PrimalLowpass", "PrimalHighpass"}], {2}]

Out[1]= {{0.5, 0.5}, {0.5, -0.5}}
```

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

```wl
In[2]:= Apply[KroneckerProduct, Tuples[{lp, hp}, 2], {1}]

Out[2]= {{{0.25, 0.25}, {0.25, 0.25}}, {{0.25, -0.25}, {0.25, -0.25}}, {{0.25, 0.25}, {-0.25, -0.25}}, {{0.25, -0.25}, {-0.25, 0.25}}}

In[3]:= Map[MatrixPlot, %]

Out[3]= {[image], [image], [image], [image]}
```

---

Wavelet transform of step data:

```wl
In[1]:=
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:

```wl
In[2]:= MatrixPlot[step[{0, 1, 0, 1}], FrameTicks -> False]

Out[2]= [image]
```

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

```wl
In[3]:= StationaryWaveletTransform[step[{0, 1, 0, 1}]][Automatic, {"MatrixPlot", ImageSize -> 40}]

Out[3]= {{1} -> [image], {2} -> [image], {3} -> [image], {0, 1} -> [image], {0, 2} -> [image], {0, 3} -> [image], {0, 0, 1} -> [image], {0, 0, 2} -> [image], {0, 0, 3} -> [image], {0, 0, 0} -> [image]}
```

Data with horizontal discontinuity:

```wl
In[4]:= MatrixPlot[step[{0, 0, 1, 1}], FrameTicks -> False]

Out[4]= [image]
```

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

```wl
In[5]:= StationaryWaveletTransform[step[{0, 0, 1, 1}]][Automatic, {"MatrixPlot", ImageSize -> 40}]

Out[5]= {{1} -> [image], {2} -> [image], {3} -> [image], {0, 1} -> [image], {0, 2} -> [image], {0, 3} -> [image], {0, 0, 1} -> [image], {0, 0, 2} -> [image], {0, 0, 3} -> [image], {0, 0, 0} -> [image]}
```

#### Array Data (2)

Compute a three-dimensional stationary wavelet transform:

```wl
In[1]:= data = RandomReal[1, {16, 16, 16}];

In[2]:= dwd = StationaryWaveletTransform[data, Automatic, 2]

Out[2]= DiscreteWaveletData[<<SWT>>, <2>, {16, 16, 16}]
```

Tree view of all coefficients:

```wl
In[3]:= dwd["TreeView"]

Out[3]= [image]
```

Inverse transform to get back the original signal:

```wl
In[4]:= Norm[Flatten[data - InverseWaveletTransform[dwd]]]

Out[4]= 3.1020503500324403`*^-15
```

---

Wavelet transform of a three-dimensional cross array:

```wl
In[1]:= data = CrossMatrix[All, {8, 8, 8}];

In[2]:= Graphics3D[{Red, Cuboid /@ Position[data, 1]}]

Out[2]= [image]

In[3]:= dwd = StationaryWaveletTransform[data, Automatic, 1]

Out[3]= DiscreteWaveletData[«SWT», <1>, {8, 8, 8}]
```

Visualize wavelet coefficients:

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

Out[4]= {{0} -> [image], {1} -> [image], {2} -> [image], {3} -> [image], {4} -> [image], {5} -> [image], {6} -> [image], {7} -> [image]}
```

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

```wl
In[5]:= Total[Flatten[data]^2] == Total[Flatten[dwd[Automatic][[All, 2]]]^2]

Out[5]= True
```

#### Image Data (2)

Transform an ``Image`` object:

```wl
In[1]:= img = Image[DiamondMatrix[All, {64, 64}]]

Out[1]= [image]

In[2]:= dwd = StationaryWaveletTransform[img, HaarWavelet[], 3]

Out[2]= DiscreteWaveletData[«SWT», <3>, {64, 64}]
```

The inverse transform yields a reconstructed ``Image`` object:

```wl
In[3]:= InverseWaveletTransform[dwd]

Out[3]= [image]
```

---

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

```wl
In[1]:= dwd = StationaryWaveletTransform[[image], HaarWavelet[], 2];

In[2]:= Dimensions[{0, 0} /. Normal[dwd]]

Out[2]= {3, 128, 128}
```

Number of channels and dimensions of the original image are the same:

```wl
In[3]:= Dimensions[ImageData[[image], Interleaving -> False]]

Out[3]= {3, 128, 128}
```

Get all coefficients as ``Image`` objects instead of arrays of data:

```wl
In[4]:= dwd[All, "Image"]

Out[4]= {{0} -> [image], {1} -> [image], {2} -> [image], {3} -> [image], {0, 0} -> [image], {0, 1} -> [image], {0, 2} -> [image], {0, 3} -> [image]}
```

Get raw ``Image`` objects with no rescaling of color levels:

```wl
In[5]:= dwd[All, {"Image", "ImageFunction" -> Identity}]

Out[5]= {{0} -> [image], {1} -> [image], {2} -> [image], {3} -> [image], {0, 0} -> [image], {0, 1} -> [image], {0, 2} -> [image], {0, 3} -> [image]}
```

Get the inverse transform of the ``{0, 1}`` coefficient as an ``Image`` object:

```wl
In[6]:= dwd[{0, 1}, {"Image", "Inverse"}]

Out[6]= {{0, 1} -> [image]}
```

#### Sound Data (3)

Transform a ``Sound`` object:

```wl
In[1]:= snd = ExampleData[{"Sound", "Apollo11ReturnSafely"}]

Out[1]= Sound[SampledSoundList[CompressedData["«65612»"], 11025]]

In[2]:= dwd = StationaryWaveletTransform[snd]

Out[2]= DiscreteWaveletData[«SWT», <15>, {28313}]
```

The inverse transform yields a reconstructed ``Sound`` object:

```wl
In[3]:= InverseWaveletTransform[dwd]

Out[3]= Sound[SampledSoundList[CompressedData["«68546»"], 11025]]
```

---

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

```wl
In[1]:= dwd = StationaryWaveletTransform[ExampleData[{"Sound", "PianoScale"}]];

In[2]:= Dimensions[{0, 0, 1} /. Normal[dwd]]

Out[2]= {2, 269827}
```

Number of channels and data length in the original sound are the same:

```wl
In[3]:= Dimensions[First[First[ExampleData[{"Sound", "PianoScale"}]]]]

Out[3]= {2, 269827}
```

Get the ``{0, 1}`` coefficient as a ``Sound`` object:

```wl
In[4]:= dwd[{0, 0, 1}, "Sound"]

Out[4]= {{0, 0, 1} -> Sound[«1»]}
```

Inverse transform of ``{0, 0, 1}`` coefficient as a ``Sound`` object:

```wl
In[5]:= dwd[{0, 0, 1}, {"Sound", "Inverse"}]

Out[5]= {{0, 0, 1} -> Sound[«2»]}
```

---

Browse all coefficients using a ``MenuView`` :

```wl
In[1]:= dwd = StationaryWaveletTransform[ExampleData[{"Sound", "Clarinet"}], SymletWavelet[3], 3];

In[2]:= MenuView[dwd[All, "Sound"]]

Out[2]= DynamicModule[«3»]
```

### Generalizations & Extensions (3)

``StationaryWaveletTransform`` works on arrays of symbolic quantities:

```wl
In[1]:= dwd = StationaryWaveletTransform[{a, b, c, d}, WorkingPrecision -> ∞];

In[2]:= Normal[dwd]//Simplify

Out[2]= {{0} -> {(a + d/2), (a + b/2), (b + c/2), (c + d/2)}, {1} -> {(a - d/2), (1/2) (-a + b), (1/2) (-b + c), (1/2) (-c + d)}, {0, 0} -> {(1/4) (a + b + c + d), (1/4) (a + b + c + d), (1/4) (a + b + c + d), (1/4) (a + b + c + d)}, {0, 1} -> {(1/4) (a - b - c + d), (1/4) (a + b - c - d), (1/4) (-a + b + c - d), (1/4) (-a - b + c + d)}}
```

Inverse transform recovers the input exactly:

```wl
In[3]:= InverseWaveletTransform[dwd]//Simplify

Out[3]= {a, b, c, d}
```

---

Specify any internal working precision:

```wl
In[1]:= dwd = StationaryWaveletTransform[{1, 2, 5, 3}, WorkingPrecision -> 20];

In[2]:= dwd[Automatic]

Out[2]= {{1} -> {-1.0000000000000000000, 0.5000000000000000000, 1.5000000000000000000, -1.0000000000000000000}, {0, 1} -> {-0.7500000000000000000, -1.2500000000000000000, 0.7500000000000000000, 1.2500000000000000000}, {0, 0} -> {2.7500000000000000000, 2.7500000000000000000, 2.7500000000000000000, 2.7500000000000000000}}
```

---

Use complex-valued data:

```wl
In[1]:= data = Exp[I RandomReal[1, 4]];

In[2]:= dwd = StationaryWaveletTransform[data]

Out[2]= DiscreteWaveletData[«SWT», <2>, {4}]
```

The wavelets coefficients are complex:

```wl
In[3]:= dwd[Automatic]

Out[3]= {{1} -> {-0.0787749 + 0.146366 I, -0.0771381 + 0.0792982 I, -0.0458365 + 0.0335276 I, 0.201749  - 0.259192 I}, {0, 1} -> {0.139444  - 0.169245 I, -0.0164692 + 0.0564191 I, -0.139444 + 0.169245 I, 0.0164692  - 0.0564191 I}, {0, 0} -> {0.728872  + 0.636577 I, 0.728872  + 0.636577 I, 0.728872  + 0.636577 I, 0.728872  + 0.636577 I}}
```

Inverse transform recovers the input:

```wl
In[4]:= Norm[InverseWaveletTransform[dwd] - data]

Out[4]= 2.220446049250313`*^-16
```

### Options (3)

#### WorkingPrecision (3)

By default, ``WorkingPrecision -> MachinePrecision`` is used:

```wl
In[1]:= data = RandomInteger[1, {10}];

In[2]:= dwd1 = StationaryWaveletTransform[data]

Out[2]= DiscreteWaveletData[«SWT», <3>, {10}]

In[3]:= dwd2 = StationaryWaveletTransform[data, WorkingPrecision -> MachinePrecision]

Out[3]= DiscreteWaveletData[«SWT», <3>, {10}]

In[4]:= dwd1 == dwd2

Out[4]= True
```

---

Use higher-precision computation:

```wl
In[1]:= data = {0, 0, 1, 1};

In[2]:= dwd = Normal@StationaryWaveletTransform[data, WorkingPrecision -> 25]

Out[2]= {{0} -> {0.500000000000000000000000, 0, 0.500000000000000000000000, 1.000000000000000000000000}, {1} -> {-0.500000000000000000000000, 0, 0.500000000000000000000000, 0}, {0, 0} -> {0.500000000000000000000000, 0.500000000000000000000000, 0.500000000000000000000000, 0.500000000000000000000000}, {0, 1} -> {0, -0.500000000000000000000000, 0, 0.500000000000000000000000}}

In[3]:= {Precision[dwd], Accuracy[dwd]}

Out[3]= {24.699, 24.699}
```

---

Use ``WorkingPrecision -> ∞`` for exact computation:

```wl
In[1]:= data = RandomInteger[10, {4}];

In[2]:= Normal@StationaryWaveletTransform[data, WorkingPrecision -> ∞]//Simplify

Out[2]= {{0} -> {2, 6, 8, 4}, {1} -> {1, 3, -1, -3}, {0, 0} -> {5, 5, 5, 5}, {0, 1} -> {-3, 1, 3, -1}}
```

### Applications (3)

#### Inverse Halftoning (1)

A simple wavelet-based inverse halftoning:

```wl
In[1]:= img  = ImageTake[ [image], 100]

Out[1]= [image]

In[2]:= swt  = StationaryWaveletTransform[img, DaubechiesWavelet[4], 2];
```

Apply ``GaussianFilter`` on the detail coefficients:

```wl
In[3]:= InverseWaveletTransform[WaveletMapIndexed[GaussianFilter[#, 4]&, swt, Except[{___, 0}]]]

Out[3]= [image]
```

#### Numerical Differentiation (1)

Differentiate noisy data using wavelet transform:

```wl
In[1]:= f[x_] := Log[2 + Sin[3 π Sqrt[x]]]

In[2]:= {t, fd} = Transpose[Table[{x, f[x] + RandomReal[NormalDistribution[0, 0.01]]}, {x, 0.01, 1, 0.001}]];

In[3]:= ListLinePlot[fd]

Out[3]= [image]
```

Translation-Rotation-Transform (TRT) is used to reduce boundary effects by subtracting a linear component from the input signal:

```wl
In[4]:= a = (Max[fd] - Min[fd]/Max[t] - Min[t]);

In[5]:= b = Min[fd] - a Min[t];

In[6]:= Subscript[fd, TRT] = fd - (a t + b);
```

Since ``HaarWavelet`` has one vanishing moment, choose it to perform a wavelet transform on $Subscript[fd, TRT]$:

```wl
In[7]:= wd = StationaryWaveletTransform[Subscript[fd, TRT], HaarWavelet[], 4];

In[8]:= j = wd["Refinement"];
```

Detail coefficients give the differentiation of the data. Coefficients at refinement level 4 are chosen to minimize noise:

```wl
In[9]:= du = Sqrt[2]^jFirst[wd[{0, 0, 0, 1}, "Values"]];
```

Rescale the differentiated values:

```wl
In[10]:= dx = 0.001;

In[11]:= dudx = (4 du /dx (2^j)^(3/2)) + a;
```

Compare wavelet-based numerical differentiation with exact differentiation:

```wl
In[12]:= Show[ListLinePlot[Transpose[{t, dudx}]], Plot[Evaluate[D[f[x], x]], {x, 0.01, 1}, PlotStyle -> Red], PlotRange -> All]

Out[12]= [image]
```

Compare with standard Wolfram Language numerical differentiation:

```wl
In[13]:= ifunc = Interpolation[Transpose[{t, fd}]];

In[14]:= Plot[ifunc'[x], {x, 0.01, 1}]

Out[14]= [image]
```

#### Image Fusion (1)

Add texture to an existing image:

```wl
In[1]:= {img, txt}  = { [image], [image]};
```

Perform wavelet transform on both images:

```wl
In[2]:= dwd1 = StationaryWaveletTransform[img, CDFWavelet[], 3];

In[3]:= dwd2 = StationaryWaveletTransform[txt, CDFWavelet[], 3];
```

Combine detail coefficients of the two images by taking their mean:

```wl
In[4]:= rval1 = dwd1[{___, 1 | 2 | 3}, "Values"];

In[5]:= rval2 = dwd2[{___, 1 | 2 | 3}, "Values"];

In[6]:= wind = Cases[dwd1["WaveletIndex"], {___, 1 | 2 | 3}];

In[7]:= nimg = (Image[#1, Interleaving -> False]&) /@ ((1/2) (rval1 + 2 rval2));

In[8]:= rnew = MapThread[Rule, {wind, nimg}];
```

Append the coarse coefficient of the first image:

```wl
In[9]:= rr = Append[rnew, First[dwd1[{0, 0, 0}, {"Image", "ImageFunction" -> Identity}]]];
```

Construct a new ``DiscreteWaveletData`` of the combined wavelet coefficients:

```wl
In[10]:= dwdnew = DiscreteWaveletData[rr, CDFWavelet[], StationaryWaveletTransform]

Out[10]= DiscreteWaveletData[«SWT», <3>, {512, 512}]
```

Reconstruct the combined image:

```wl
In[11]:= InverseWaveletTransform[dwdnew]

Out[11]= [image]
```

### Properties & Relations (12)

``StationaryWaveletPacketTransform`` computes the full tree of wavelet coefficients:

```wl
In[1]:= swpt = StationaryWaveletPacketTransform[{1, 1, 3, 1, 1}];

In[2]:= swpt[{"TreeView", Left}]

Out[2]= [image]
```

``StationaryWaveletTransform`` computes a subset of the full tree of coefficients:

```wl
In[3]:= swt = StationaryWaveletTransform[{1, 1, 3, 1, 1}];

In[4]:= swt[{"TreeView", Left}]

Out[4]= [image]
```

---

``DiscreteWaveletTransform`` coefficients halve in length with each level of refinement:

```wl
In[1]:= Normal[DiscreteWaveletTransform[{1, 2, 3, 4}]]

Out[1]= {{0} -> {2.12132, 4.94975}, {1} -> {-0.707107, -0.707107}, {0, 0} -> {5.}, {0, 1} -> {-2.}}
```

Rotated data gives different coefficients:

```wl
In[2]:= Normal[DiscreteWaveletTransform[{2, 3, 4, 1}]]

Out[2]= {{0} -> {3.53553, 3.53553}, {1} -> {-0.707107, 2.12132}, {0, 0} -> {5.}, {0, 1} -> {0.}}
```

``StationaryWaveletTransform`` coefficients have the same length as the original data:

```wl
In[3]:= Normal[StationaryWaveletTransform[{1, 2, 3, 4}]]

Out[3]= {{0} -> {2.5, 1.5, 2.5, 3.5}, {1} -> {-1.5, 0.5, 0.5, 0.5}, {0, 0} -> {2.5, 2.5, 2.5, 2.5}, {0, 1} -> {0., -1., 0., 1.}}
```

Rotated data gives rotated coefficients:

```wl
In[4]:= Normal[StationaryWaveletTransform[{2, 3, 4, 1}]]

Out[4]= {{0} -> {1.5, 2.5, 3.5, 2.5}, {1} -> {0.5, 0.5, 0.5, -1.5}, {0, 0} -> {2.5, 2.5, 2.5, 2.5}, {0, 1} -> {-1., 0., 1., 0.}}
```

---

The default refinement is given by $⌊Log2(n) + (1/2)⌋$:

```wl
In[1]:= data = RandomReal[1, {100}];

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

Out[2]= 7

In[3]:= StationaryWaveletTransform[data] == StationaryWaveletTransform[data, Automatic, r]

Out[3]= True
```

In higher dimensions:

```wl
In[4]:= data = RandomReal[1, {100, 10, 10}];

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

Out[5]= 3

In[6]:= StationaryWaveletTransform[data] == StationaryWaveletTransform[data, Automatic, r]

Out[6]= True
```

---

The energy norm is conserved for orthogonal wavelet families:

```wl
In[1]:= data = RandomReal[1, {100}];

In[2]:= swt = StationaryWaveletTransform[data];

In[3]:= Norm[data] == Norm[Flatten[Last /@ swt[Automatic]]]

Out[3]= True
```

---

The energy norm is approximately conserved for biorthogonal wavelet families:

```wl
In[1]:= data = RandomReal[1, {100}];

In[2]:= swt = StationaryWaveletTransform[data, BiorthogonalSplineWavelet[2, 4]];

In[3]:= Norm[data]

Out[3]= 5.43997

In[4]:= Norm[Flatten[Last /@ swt[Automatic]]]

Out[4]= 5.53104
```

---

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

```wl
In[1]:= data = RandomReal[1, 16];

In[2]:= swt = StationaryWaveletTransform[data, HaarWavelet[]];
```

Extract the coefficient for the maximum refinement level:

```wl
In[3]:= r = swt["Refinement"]

Out[3]= 4

In[4]:= swt[ConstantArray[0, {r}]]

Out[4]= {{0, 0, 0, 0} -> {0.381177, 0.381177, 0.381177, 0.381177, 0.381177, 0.381177, 0.381177, 0.381177, 0.381177, 0.381177, 0.381177, 0.381177, 0.381177, 0.381177, 0.381177, 0.381177}}

In[5]:= Mean[data]

Out[5]= 0.381177
```

---

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

```wl
In[1]:= data = Table[DiscreteDelta[n], {n, -2, 2}]

Out[1]= {0, 0, 1, 0, 0}

In[2]:= dwt = StationaryWaveletTransform[data];

In[3]:= dwt["TreeView"]

Out[3]= [image]
```

Individually inverse transform each wavelet coefficient array:

```wl
In[4]:= data1 = InverseWaveletTransform[dwt, Automatic, {0, 0}]

Out[4]= {0.1875, 0.1875, 0.25, 0.1875, 0.1875}

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

Out[5]= {-0.1875, 0.0625, 0.25, 0.0625, -0.1875}

In[6]:= data3 = InverseWaveletTransform[dwt, Automatic, {1}]

Out[6]= {0., -0.25, 0.5, -0.25, 0.}
```

The sum gives the original data:

```wl
In[7]:= data1 + data2 + data3

Out[7]= {0., 0., 1., 0., 0.}
```

---

Compute stationary wavelet coefficients for periodic data:

```wl
In[1]:= x  = Range[8];

In[2]:= dwd = StationaryWaveletTransform[x, HaarWavelet[]];

In[3]:=
J = dwd["Refinement"];
l  = First[ dwd["DataDimensions"]];
```

Compute filter coefficients:

```wl
In[4]:=
a = WaveletFilterCoefficients[HaarWavelet[], "PrimalLowpass"][[All, 2]];
b = WaveletFilterCoefficients[HaarWavelet[], "PrimalHighpass"][[All, 2]];

In[5]:= f = Length[a];
```

Coarse coefficients at level $j$ are given by $Subscript[c, j + 1, n] = Underoverscript[∑, m = 1, f]Subscript[a, m] Subscript[c, j, n - 2^j (1 - m mod l)]$ :

```wl
In[6]:= SetAttributes[c, Listable];

In[7]:=
c[0, n_] := x[[n]];
c[j_, n_] := Underoverscript[∑, m = 1, f]a[[m]] c[j - 1, Mod[n + 2^j - 1(1 - Mod[m, l]), l, 1]]

In[8]:= dwd[{___, 0}, "Values"] == Table[c[j, Range[l]], {j, 1, J}]

Out[8]= True
```

Detail coefficients at level $j$ are given by $Subscript[d, j + 1, n] = Underoverscript[∑, m = 1, f]Subscript[b, m] Subscript[c, j, n - 2^j (1 - m mod l)]$ :

```wl
In[9]:= SetAttributes[d, Listable];

In[10]:= d[j_, n_] := Underoverscript[∑, m = 1, f]b[[m]] c[j - 1, Mod[n + 2^j - 1 (1 - Mod[m, l]), l, 1]]

In[11]:= dwd[{___, 1}, "Values"] == Table[d[j, Range[l]], {j, 1, J}]

Out[11]= True
```

---

Compute partial stationary inverse wavelet transform:

```wl
In[1]:= x  = Range[8];

In[2]:= dwd = StationaryWaveletTransform[x, HaarWavelet[]];

In[3]:=
J = dwd["Refinement"];
l  = First[ dwd["DataDimensions"]];
```

Compute filter coefficients:

```wl
In[4]:=
a = WaveletFilterCoefficients[HaarWavelet[], "PrimalLowpass"][[All, 2]];
b = WaveletFilterCoefficients[HaarWavelet[], "PrimalHighpass"][[All, 2]];

In[5]:= f = Length[a];
```

Coarse coefficients at level $j$ are given:

```wl
In[6]:= SetAttributes[c, Listable];

In[7]:=
c[0, n_] := x[[n]];
c[j_, n_] := c[j, n] = Underoverscript[∑, m = 1, f]a[[m]] c[j - 1, Mod[n + 2^j - 1(1 - Mod[m, l]), l, 1]]
```

Detail coefficients at level $j$ are given:

```wl
In[8]:= SetAttributes[d, Listable];

In[9]:= d[j_, n_] := d[j, n] = Underoverscript[∑, m = 1, f]b[[m]] c[j - 1, Mod[n + 2^j - 1 (1 - Mod[m, l]), l, 1]]
```

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

```wl
In[10]:= SetAttributes[iwt, Listable];

In[11]:= iwt[j_Integer, n_Integer] := Underoverscript[∑, m = 1, f](a[[m]] c[j + 1, Mod[n + 2^j(-1 + Mod[m, l]), l, 1]] + b[[m]] d[j + 1, Mod[n + 2^j (-1 + Mod[m, l]), l, 1]])
```

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

```wl
In[12]:= iwt[2, Range[l]] == First[dwd[{0, 0}, "Values"]]

Out[12]= True
```

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

```wl
In[13]:= iwt[1, Range[l]] == First[dwd[{0}, "Values"]]

Out[13]= True
```

---

Compute a Haar stationary wavelet transform in one dimension:

```wl
In[1]:=
low[v_] := ListCorrelate[{1 / 2, 1 / 2}, v, -1]
high[v_] := ListCorrelate[{-1 / 2, 1 / 2}, v, -1]

In[2]:= HaarSWT[v_] := {{0} -> low[v], {1} -> high[v]};
```

Compute ``{0}`` and ``{1}`` wavelet coefficients:

```wl
In[3]:= HaarSWT[{a, b, c, d}]

Out[3]= {{0} -> {(a/2) + (d/2), (a/2) + (b/2), (b/2) + (c/2), (c/2) + (d/2)}, {1} -> {(a/2) - (d/2), -(a/2) + (b/2), -(b/2) + (c/2), -(c/2) + (d/2)}}
```

Compare with ``DiscreteWaveletPacketTransform`` :

```wl
In[4]:= StationaryWaveletTransform[{a, b, c, d}, HaarWavelet[], 1, WorkingPrecision -> ∞][All]

Out[4]= {{0} -> {(a/2) + (d/2), (a/2) + (b/2), (b/2) + (c/2), (c/2) + (d/2)}, {1} -> {(a/2) - (d/2), -(a/2) + (b/2), -(b/2) + (c/2), -(c/2) + (d/2)}}
```

---

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

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

Lowpass and highpass filters for a Haar wavelet:

```wl
In[2]:=
low[v_] := ListCorrelate[{1 / 2, 1 / 2}, v, -1]
high[v_] := ListCorrelate[{-1 / 2, 1 / 2}, v, -1]
```

Haar wavelet transform of matrix data:

```wl
In[3]:= data = Table[Sin[x y], {x, -2, 2, 4 / 63}, {y, -2, 2, 4 / 63}];

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

Out[4]= {[image], [image], [image], [image]}
```

Compare with ``DiscreteWaveletPacketTransform`` using ``HaarWavelet`` :

```wl
In[5]:= dwd = StationaryWaveletTransform[data, HaarWavelet[], 1];

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

Out[6]= {[image], [image], [image], [image]}
```

---

Image channels are transformed individually:

```wl
In[1]:= dwds = Map[StationaryWaveletTransform, ColorSeparate[[image]]];
```

Combine ``{0}`` coefficients of separately transformed image channels:

```wl
In[2]:= w = Image[Table[Part[t[{0}, "Values"], 1, 1], {t, dwds}], Interleaving -> False]

Out[2]= [image]
```

Compare with ``{0}`` coefficient of ``StationaryWaveletTransform`` of the original image:

```wl
In[3]:= dwd = StationaryWaveletTransform[[image]];

In[4]:= First[dwd[{0}, {"Values", {"Image", "ImageFunction" -> Identity}}]]

Out[4]= [image]
```

The images are identical:

```wl
In[5]:= ImageSubtract[w, %]

Out[5]= [image]
```

## See Also

* [`InverseWaveletTransform`](https://reference.wolfram.com/language/ref/InverseWaveletTransform.en.md)
* [`DiscreteWaveletData`](https://reference.wolfram.com/language/ref/DiscreteWaveletData.en.md)
* [`WaveletMapIndexed`](https://reference.wolfram.com/language/ref/WaveletMapIndexed.en.md)
* [`WaveletThreshold`](https://reference.wolfram.com/language/ref/WaveletThreshold.en.md)
* [`DiscreteWaveletTransform`](https://reference.wolfram.com/language/ref/DiscreteWaveletTransform.en.md)
* [`StationaryWaveletPacketTransform`](https://reference.wolfram.com/language/ref/StationaryWaveletPacketTransform.en.md)

## Related Guides

* [Wavelet Analysis](https://reference.wolfram.com/language/guide/Wavelets.en.md)
* [Signal Transforms](https://reference.wolfram.com/language/guide/SignalTransforms.en.md)

## History

* [Introduced in 2010 (8.0)](https://reference.wolfram.com/language/guide/SummaryOfNewFeaturesIn80.en.md) \| [Updated in 2017 (11.2)](https://reference.wolfram.com/language/guide/SummaryOfNewFeaturesIn112.en.md)