---
title: "CanonicalWarpingCorrespondence"
language: "en"
type: "Symbol"
summary: "CanonicalWarpingCorrespondence[s1, s2] gives the canonical time warping (CTW) correspondence between sequences s1 and s2. CanonicalWarpingCorrespondence[s1, s2, warp] uses warp as initial warping correspondence. CanonicalWarpingCorrespondence[s1, s2, warp, win] uses a window win for local search."
keywords: 
- CTW
- canonical time warping
- DTW
- canonical correlation analysis
- CCA
- local canonical time warping
- LCTW
canonical_url: "https://reference.wolfram.com/language/ref/CanonicalWarpingCorrespondence.html"
source: "Wolfram Language Documentation"
related_guides: 
  - 
    title: "Sequence Alignment & Comparison"
    link: "https://reference.wolfram.com/language/guide/SequenceAlignmentAndComparison.en.md"
related_functions: 
  - 
    title: "CanonicalWarpingDistance"
    link: "https://reference.wolfram.com/language/ref/CanonicalWarpingDistance.en.md"
  - 
    title: "WarpingDistance"
    link: "https://reference.wolfram.com/language/ref/WarpingDistance.en.md"
  - 
    title: "WarpingCorrespondence"
    link: "https://reference.wolfram.com/language/ref/WarpingCorrespondence.en.md"
  - 
    title: "SmithWatermanSimilarity"
    link: "https://reference.wolfram.com/language/ref/SmithWatermanSimilarity.en.md"
  - 
    title: "NeedlemanWunschSimilarity"
    link: "https://reference.wolfram.com/language/ref/NeedlemanWunschSimilarity.en.md"
---
# CanonicalWarpingCorrespondence

CanonicalWarpingCorrespondence[s1, s2] gives the canonical time warping (CTW) correspondence between sequences s1 and s2.

CanonicalWarpingCorrespondence[s1, s2, warp] uses warp as initial warping correspondence.

CanonicalWarpingCorrespondence[s1, s2, warp, win] uses a window win for local search.

## Details and Options

* Canonical time warping (CTW) iteratively performs spatial transformations and dynamic time warping on the reference sequence ``s1`` and the query sequence ``s2`` to find the alignment with minimal distance between sequences.

* The sequences ``si`` can be lists of numeric scalars or vectors. In contrast to dynamic time warping, elements of ``s1`` and ``s2`` can be of different dimensions.

* ``CanonicalWarpingCorrespondence`` returns ``{{n1, …, nk}, {m1, …, mk}}`` of non-decreasing positions such that ``s1[[ni]]`` correspond to ``s2[[mi]]``.

* Corresponding positions attempt to minimize the distance $\sum _{i=1}^k \left(\alpha _i\cdot s_1\left[\left[n_i\right]\right]-\beta _i\cdot s_2\left[\left[m_i\right]\right]\right){}^2$ over all possible such positions and with the constraint that all elements of ``s1`` and ``s2`` are represented as some ``s1[[ni]]`` and ``s2[[mj]]``, respectively.

* Spatial transformation matrices ``α`` and ``β`` are computed in each iteration using canonical correlation analysis.

* Compute the effective distance using ``CanonicalWarpingDistance``.

* Possible settings for the search window ``win`` are:

|     |     |     |
| --- | --- | --- |
| [image] | Automatic | a full search |
| [image] | r   | a slanted band window of radius $r$ |
| [image] | {"SlantedBand", r} | a slanted band window of radius $r$ |
| [image] | {"Band", r} | band window of radius $r$ (Sakoe–Chiba) |
| [image] | {"Parallelogram", a} | parallelogram window placed at origin with slopes $a$ and $1/a$ (Itakura) |

* The following options are supported:

|                  |           |                                                |
| ---------------- | --------- | ---------------------------------------------- |
| DistanceFunction | Automatic | distance function used in dynamic time warping |
| MaxIterations    | Automatic | maximal number of iterations                   |
| Method           | Automatic | additional parameters                          |

* The following options are available through ``Method -> opts`` :

|                     |           |                                                                           |
| ------------------- | --------- | ------------------------------------------------------------------------- |
| "DimensionsToKeep"  | Automatic | dimensions after projection                                               |
| "EnergyThreshold"   | Automatic | fraction of "energy" to be kept                                           |
| "Lambdas"           | Automatic | regularization values                                                     |
| "MatchingIntervals" | Automatic | whether to match the query to the full reference or part of the reference |

* Possible settings for the ``"MatchingIntervals"`` option include:

|               |                                           |
| ------------- | ----------------------------------------- |
| Automatic     | a full match                              |
| "Flexible"    | flexible at both ends                     |
| "FlexibleEnd" | flexible only at the end of the interval  |

## Examples (13)

### Basic Examples (2)

Find the canonical time warping correspondence between two scalar sequences:

```wl
In[1]:= CanonicalWarpingCorrespondence[{1, 2, 3, 1}, {8, 8, 7, 7}]

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

---

Find the canonical time warping correspondence between a 3D path and a 2D line segment:

```wl
In[1]:= CanonicalWarpingCorrespondence[{{0, 0, 0}, {1, 1, 2}, {3, 5, 5}, {1, 3, 7}}, {{0, 0}, {4, 4}}]

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

### Scope (9)

#### Data (6)

Find the correspondence between two sequences of numerical scalars with different length:

```wl
In[1]:= CanonicalWarpingCorrespondence[{1, 1, 1, 2, 2, 3, 4}, {11, 13, 17, 19}]

Out[1]= {{1, 2, 3, 4, 5, 6, 7}, {1, 1, 1, 2, 2, 3, 4}}
```

---

Find the correspondence between two sequences of vectors:

```wl
In[1]:= CanonicalWarpingCorrespondence[{{0, 0}, {-1, 0}, {-1, 1}}, {{-1, 2}, {1, -2}, {0, 7}}]

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

---

Find the correspondence between a sequence of scalars and a sequence of 3D points:

```wl
In[1]:= CanonicalWarpingCorrespondence[{1, 1, 1, 2, 2, 3, 4}, {{-1, -2, -3}, {1, 2, 3}, {0, 0, 0}}]//TextGrid

Out[1]=
|   |   |   |   |   |   |   |
| - | - | - | - | - | - | - |
| 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 1 | 1 | 1 | 2 | 3 | 3 | 3 |
```

---

Find the correspondence between two sequences of quantities with compatible units:

```wl
In[1]:=
s1 = QuantityArray[{1, 2.5, 4}, "Decimeters"];
s2 = {Quantity[0.1, "Kilometers"], Quantity[200, "Inches"]};

In[2]:= CanonicalWarpingCorrespondence[s1, s2]

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

All units are converted to base SI units:

```wl
In[3]:= CanonicalWarpingCorrespondence[s1, s2] == CanonicalWarpingCorrespondence[UnitConvert[s1], UnitConvert[s2]]

Out[3]= True
```

---

Find the correspondence between two sequences of quantity vectors with compatible units:

```wl
In[1]:= s1 = QuantityArray[{{1, 2.5}, {4, 5}, {5, 4}}, {"Seconds", "Minutes"}]

Out[1]=
QuantityArray[StructuredArray`StructuredData[{3, 2}, {{{1, 2.5}, {4, 5}, {5, 4}}, 
   {"Seconds", "Minutes"}, {{1}, {2}}}]]

In[2]:= s2 = Table[Quantity[(i + j) / 60, "Hours"], {i, 5}, {j, 2}]

Out[2]= {{Quantity[1/30, "Hours"], Quantity[1/20, "Hours"]}, {Quantity[1/20, "Hours"], Quantity[1/15, "Hours"]}, {Quantity[1/15, "Hours"], Quantity[1/12, "Hours"]}, {Quantity[1/12, "Hours"], Quantity[1/10, "Hours"]}, {Quantity[1/10, "Hours"], Quantity[7/60, "Hours"]}}

In[3]:= CanonicalWarpingCorrespondence[s1, s2]//TextGrid

Out[3]=
|   |   |   |   |   |
| - | - | - | - | - |
| 1 | 2 | 2 | 2 | 3 |
| 1 | 2 | 3 | 4 | 5 |
```

---

Find the correspondence between a sequence of quantities and a sequence of scalars:

```wl
In[1]:=
squant = QuantityArray[{1, 2.5, 4, 5}, "Kilometers"];
sscal = {500, 400, 300};

In[2]:= CanonicalWarpingCorrespondence[squant, sscal]//TextGrid

Out[2]=
|   |   |   |   |
| - | - | - | - |
| 1 | 2 | 3 | 4 |
| 1 | 2 | 2 | 3 |
```

The scalars are interpreted as if they had a compatible unit from SI base units:

```wl
In[3]:= CanonicalWarpingCorrespondence[squant, QuantityArray[sscal, "meters"]]//TextGrid

Out[3]=
|   |   |   |   |
| - | - | - | - |
| 1 | 2 | 3 | 4 |
| 1 | 2 | 2 | 3 |
```

#### Initial Warping (1)

By default, the shorter sequence is first warped uniformly to match the length of the longer sequence:

```wl
In[1]:=
s1 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
s2 = {1, 1, 1, 1, 1, 2, 3, 7, 8, 9, 10};

In[2]:= CanonicalWarpingCorrespondence[s1, s2]

Out[2]= {{1, 2, 3, 3, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, {1, 2, 3, 4, 5, 6, 7, 7, 7, 8, 8, 8, 9, 10, 11}}
```

Construct the initial uniform warping manually:

```wl
In[3]:= CanonicalWarpingCorrespondence[s1, s2, {Range[Length[s1]], ArrayResample[Range[Length[s2]], Length[s1], Resampling -> "NearestLeft"]}]

Out[3]= {{1, 2, 3, 3, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, {1, 2, 3, 4, 5, 6, 7, 7, 7, 8, 8, 8, 9, 10, 11}}
```

#### Search Window (2)

By default, an unconstrained search is performed:

```wl
In[1]:=
s1 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
s2 = {1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

In[2]:= CanonicalWarpingCorrespondence[s1, s2]

Out[2]= {{1, 2, 2, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, {1, 2, 3, 4, 5, 6, 7, 7, 8, 9, 10, 11, 11, 12, 13, 14}}
```

---

Use a ``"SlantedBand"`` search window:

```wl
In[1]:=
s1 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
s2 = {1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

In[2]:= CanonicalWarpingCorrespondence[s1, s2, Automatic, {"SlantedBand", 1}]

Out[2]= {{1, 2, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 11, 12, 13, 14}}
```

### Options (1)

#### MaxIterations (1)

By default, the maximal number of iterations is 50:

```wl
In[1]:=
s1 = Table[{7t * Cos[1.8t], 3t * Sin[1.8t]}, {t, Range[0, 4Pi, 4Pi / 650]}];
s2 = Table[{5t * Cos[t], -3t * Sin[t]}, {t, Range[0, 6Pi, 6Pi / 500]}];
Graphics[{{Red, Point[s1]}, {Blue, Point[s2]}}]

Out[1]= [image]

In[2]:= AbsoluteTiming[CanonicalWarpingCorrespondence[s1, s2];]

Out[2]= {1.67922, Null}
```

Decreasing the maximal number of iterations may reduce the timing:

```wl
In[3]:= AbsoluteTiming[CanonicalWarpingCorrespondence[s1, s2, MaxIterations -> 20];]

Out[3]= {0.675765, Null}
```

### Properties & Relations (1)

Canonical time warping is robust to spatial transformations.

Translation invariance:

```wl
In[1]:=
s1 = Table[{Cos[0.6t] * Cos[t], Cos[0.6t] * Sin[t]}, {t, 0, 6Pi, 2Pi / 100}];
s2 = TranslationTransform[{2, 2}] /@ s1;

In[2]:= ListLinePlot[{s1, s2}]

Out[2]= [image]

In[3]:= CanonicalWarpingCorrespondence[s1, s2]//ListLinePlot

Out[3]= [image]
```

Scale invariance:

```wl
In[4]:=
s1 = Table[{2Cos[t], Sin[t]}, {t, 0, 2Pi, 2Pi / 20}];
s2 = 3s1;
ListLinePlot[{s1, s2}]

Out[4]= [image]

In[5]:= CanonicalWarpingCorrespondence[s1, s2]//ListLinePlot

Out[5]= [image]
```

Rotation invariance:

```wl
In[6]:=
s1 = Table[{Cos[3t] * Cos[t], Cos[3t] * Sin[t]}, {t, 0, 2Pi, 2Pi / 100}];
s2 = RotationTransform[Pi] /@ s1;

In[7]:= ListLinePlot[{s1, s2}]

Out[7]= [image]

In[8]:= CanonicalWarpingCorrespondence[s1, s2]//ListLinePlot

Out[8]= [image]
```

## See Also

* [`CanonicalWarpingDistance`](https://reference.wolfram.com/language/ref/CanonicalWarpingDistance.en.md)
* [`WarpingDistance`](https://reference.wolfram.com/language/ref/WarpingDistance.en.md)
* [`WarpingCorrespondence`](https://reference.wolfram.com/language/ref/WarpingCorrespondence.en.md)
* [`SmithWatermanSimilarity`](https://reference.wolfram.com/language/ref/SmithWatermanSimilarity.en.md)
* [`NeedlemanWunschSimilarity`](https://reference.wolfram.com/language/ref/NeedlemanWunschSimilarity.en.md)

## Related Guides

* [Sequence Alignment & Comparison](https://reference.wolfram.com/language/guide/SequenceAlignmentAndComparison.en.md)

## History

* [Introduced in 2016 (11.0)](https://reference.wolfram.com/language/guide/SummaryOfNewFeaturesIn110.en.md)