Skip to content

Commit

Permalink
Merge pull request #25 from cjekel/pcm
Browse files Browse the repository at this point in the history
Don't scale length segments by max x and y with PCM
  • Loading branch information
cjekel committed Oct 8, 2022
2 parents bfcd744 + 3d45e3a commit 2439d7a
Show file tree
Hide file tree
Showing 7 changed files with 135 additions and 68 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.5, 3.6, 3.7, 3.8, 3.9]
python-version: [3.6, 3.7, 3.8, 3.9]

steps:
- uses: actions/checkout@v2
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.6.0] - 2022-10-08
### Changed
- `similaritymeasures.pcm` now produces different values! This was done to better follow the original algorithm. To get the same results from previous versions, set `norm_seg_length=True`. What this option does is scale each segment length by the maximum values of the curve (borrowed from the `curve_length_measure`). This scaling should not be needed with the PCM method because both curves are always scaled initially.
- Fix docstring documentation for returns in `similaritymeasures.dtw` and `similaritymeasures.curve_length_measure`

## [0.5.0] - 2022-08-06
### Added
- Added mean absolute error as `similaritymeasures.mae` thanks to a contribution by [HarshRaoD](https://github.com/HarshRaoD)
Expand Down
130 changes: 84 additions & 46 deletions docs/similaritymeasures.html
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ <h1 class="title">Module <code>similaritymeasures.similaritymeasures</code></h1>
return np.sum(area)


def get_length(x, y):
def get_length(x, y, norm_seg_length=True):
r&#34;&#34;&#34;
Compute arc lengths of an x y curve.

Expand All @@ -346,6 +346,8 @@ <h1 class="title">Module <code>similaritymeasures.similaritymeasures</code></h1>
the x locations of a curve
y : array_like
the y locations of a curve
norm_seg_length : boolean
Whether to divide the segment length of each curve by the maximum.

Returns
-------
Expand All @@ -362,15 +364,20 @@ <h1 class="title">Module <code>similaritymeasures.similaritymeasures</code></h1>

&#34;&#34;&#34;
n = len(x)
xmax = np.max(np.abs(x))
ymax = np.max(np.abs(y))

# if your max x or y value is zero... you&#39;ll get np.inf
# as your curve length based measure
if xmax == 0:
xmax = 1e-15
if ymax == 0:
ymax = 1e-15
if norm_seg_length:
xmax = np.max(np.abs(x))
ymax = np.max(np.abs(y))

# if your max x or y value is zero... you&#39;ll get np.inf
# as your curve length based measure
if xmax == 0:
xmax = 1e-15
if ymax == 0:
ymax = 1e-15
else:
ymax = 1.0
xmax = 1.0

le = np.zeros(n)
le[0] = 0.0
Expand All @@ -397,7 +404,7 @@ <h1 class="title">Module <code>similaritymeasures.similaritymeasures</code></h1>
num_data : ndarray (2-D)
Curve from your numerical data.

Retruns
Returns
-------
r : float
curve length based similarity distance
Expand Down Expand Up @@ -587,7 +594,7 @@ <h1 class="title">Module <code>similaritymeasures.similaritymeasures</code></h1>
return xi, eta, xiP, etaP


def pcm(exp_data, num_data):
def pcm(exp_data, num_data, norm_seg_length=False):
&#34;&#34;&#34;
Compute the Partial Curve Mapping area.

Expand All @@ -600,6 +607,10 @@ <h1 class="title">Module <code>similaritymeasures.similaritymeasures</code></h1>
Curve from your experimental data.
num_data : ndarray (2-D)
Curve from your numerical data.
norm_seg_length : boolean
Whether to divide the segment length of each curve by the maximum. The
default value is false, which more closely follows the algorithm
proposed in [1]_. Versions prior to 0.6.0 used `norm_seg_length=True`.

Returns
-------
Expand All @@ -611,6 +622,9 @@ <h1 class="title">Module <code>similaritymeasures.similaritymeasures</code></h1>
Your x locations of data points should be exp_data[:, 0], and the y
locations of the data points should be exp_data[:, 1]. Same for num_data.

PCM distance was changed in version 0.6.0. To get the same results from
previous versions, set `norm_seg_length=True`.

References
----------
.. [1] Katharina Witowski and Nielen Stander. &#34;Parameter Identification of
Expand Down Expand Up @@ -640,8 +654,8 @@ <h1 class="title">Module <code>similaritymeasures.similaritymeasures</code></h1>
xi1, eta1, xi2, eta2 = normalizeTwoCurves(exp_data[:, 0], exp_data[:, 1],
num_data[:, 0], num_data[:, 1])
# compute the arc lengths of each curve
le, le_nj, le_sum = get_length(xi1, eta1)
lc, lc_nj, lc_sum = get_length(xi2, eta2)
le, le_nj, le_sum = get_length(xi1, eta1, norm_seg_length)
lc, lc_nj, lc_sum = get_length(xi2, eta2, norm_seg_length)
# scale each segment to the total polygon length
le = le / le_nj
le_sum = le_sum / le_nj
Expand All @@ -651,8 +665,8 @@ <h1 class="title">Module <code>similaritymeasures.similaritymeasures</code></h1>
# make sure a is shorter than a&#39;, if not swap the defintion
if lc_nj &gt; le_nj:
# compute the arc lengths of each curve
le, le_nj, le_sum = get_length(xi2, eta2)
lc, lc_nj, lc_sum = get_length(xi1, eta1)
le, le_nj, le_sum = get_length(xi2, eta2, norm_seg_length)
lc, lc_nj, lc_sum = get_length(xi1, eta1, norm_seg_length)
# scale each segment to the total polygon length
le = le / le_nj
le_sum = le_sum / le_nj
Expand Down Expand Up @@ -723,7 +737,6 @@ <h1 class="title">Module <code>similaritymeasures.similaritymeasures</code></h1>
**kwargs : dict, optional
Extra arguments to `metric`: refer to each metric documentation in
scipy.spatial.distance.

Some examples:

p : scalar
Expand All @@ -746,7 +759,7 @@ <h1 class="title">Module <code>similaritymeasures.similaritymeasures</code></h1>
The output array
If not None, the distance matrix Y is stored in this array.

Retruns
Returns
-------
r : float
DTW distance.
Expand Down Expand Up @@ -1109,9 +1122,11 @@ <h2 id="parameters">Parameters</h2>
<dt><strong><code>num_data</code></strong> :&ensp;<code>ndarray (2-D)</code></dt>
<dd>Curve from your numerical data.</dd>
</dl>
<h2 id="retruns">Retruns</h2>
<p>r : float
curve length based similarity distance</p>
<h2 id="returns">Returns</h2>
<dl>
<dt><strong><code>r</code></strong> :&ensp;<code>float</code></dt>
<dd>curve length based similarity distance</dd>
</dl>
<h2 id="notes">Notes</h2>
<p>This uses the OF2 method from [1]_.</p>
<h2 id="references">References</h2>
Expand Down Expand Up @@ -1154,7 +1169,7 @@ <h2 id="examples">Examples</h2>
num_data : ndarray (2-D)
Curve from your numerical data.

Retruns
Returns
-------
r : float
curve length based similarity distance
Expand Down Expand Up @@ -1239,8 +1254,8 @@ <h2 id="parameters">Parameters</h2>
<dt><strong><code>**kwargs</code></strong> :&ensp;<code>dict</code>, optional</dt>
<dd>
<p>Extra arguments to <code>metric</code>: refer to each metric documentation in
scipy.spatial.distance.</p>
<p>Some examples:</p>
scipy.spatial.distance.
Some examples:</p>
<p>p : scalar
The p-norm to apply for Minkowski, weighted and unweighted.
Default: 2.</p>
Expand All @@ -1258,11 +1273,13 @@ <h2 id="parameters">Parameters</h2>
If not None, the distance matrix Y is stored in this array.</p>
</dd>
</dl>
<h2 id="retruns">Retruns</h2>
<p>r : float
DTW distance.
d : ndarray (2-D)
Cumulative distance matrix</p>
<h2 id="returns">Returns</h2>
<dl>
<dt><strong><code>r</code></strong> :&ensp;<code>float</code></dt>
<dd>DTW distance.</dd>
<dt><strong><code>d</code></strong> :&ensp;<code>ndarray (2-D)</code></dt>
<dd>Cumulative distance matrix</dd>
</dl>
<h2 id="notes">Notes</h2>
<p>The DTW distance is d[-1, -1].</p>
<p>This has O(M, P) computational cost.</p>
Expand Down Expand Up @@ -1331,7 +1348,6 @@ <h2 id="examples">Examples</h2>
**kwargs : dict, optional
Extra arguments to `metric`: refer to each metric documentation in
scipy.spatial.distance.

Some examples:

p : scalar
Expand All @@ -1354,7 +1370,7 @@ <h2 id="examples">Examples</h2>
The output array
If not None, the distance matrix Y is stored in this array.

Retruns
Returns
-------
r : float
DTW distance.
Expand Down Expand Up @@ -1776,7 +1792,7 @@ <h2 id="notes">Notes</h2>
</details>
</dd>
<dt id="similaritymeasures.similaritymeasures.get_length"><code class="name flex">
<span>def <span class="ident">get_length</span></span>(<span>x, y)</span>
<span>def <span class="ident">get_length</span></span>(<span>x, y, norm_seg_length=True)</span>
</code></dt>
<dd>
<div class="desc"><p>Compute arc lengths of an x y curve.</p>
Expand All @@ -1789,6 +1805,8 @@ <h2 id="parameters">Parameters</h2>
<dd>the x locations of a curve</dd>
<dt><strong><code>y</code></strong> :&ensp;<code>array_like</code></dt>
<dd>the y locations of a curve</dd>
<dt><strong><code>norm_seg_length</code></strong> :&ensp;<code>boolean</code></dt>
<dd>Whether to divide the segment length of each curve by the maximum.</dd>
</dl>
<h2 id="returns">Returns</h2>
<dl>
Expand All @@ -1806,7 +1824,7 @@ <h2 id="examples">Examples</h2>
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def get_length(x, y):
<pre><code class="python">def get_length(x, y, norm_seg_length=True):
r&#34;&#34;&#34;
Compute arc lengths of an x y curve.

Expand All @@ -1820,6 +1838,8 @@ <h2 id="examples">Examples</h2>
the x locations of a curve
y : array_like
the y locations of a curve
norm_seg_length : boolean
Whether to divide the segment length of each curve by the maximum.

Returns
-------
Expand All @@ -1836,15 +1856,20 @@ <h2 id="examples">Examples</h2>

&#34;&#34;&#34;
n = len(x)
xmax = np.max(np.abs(x))
ymax = np.max(np.abs(y))

# if your max x or y value is zero... you&#39;ll get np.inf
# as your curve length based measure
if xmax == 0:
xmax = 1e-15
if ymax == 0:
ymax = 1e-15
if norm_seg_length:
xmax = np.max(np.abs(x))
ymax = np.max(np.abs(y))

# if your max x or y value is zero... you&#39;ll get np.inf
# as your curve length based measure
if xmax == 0:
xmax = 1e-15
if ymax == 0:
ymax = 1e-15
else:
ymax = 1.0
xmax = 1.0

le = np.zeros(n)
le[0] = 0.0
Expand Down Expand Up @@ -2223,7 +2248,7 @@ <h2 id="examples">Examples</h2>
</details>
</dd>
<dt id="similaritymeasures.similaritymeasures.pcm"><code class="name flex">
<span>def <span class="ident">pcm</span></span>(<span>exp_data, num_data)</span>
<span>def <span class="ident">pcm</span></span>(<span>exp_data, num_data, norm_seg_length=False)</span>
</code></dt>
<dd>
<div class="desc"><p>Compute the Partial Curve Mapping area.</p>
Expand All @@ -2235,6 +2260,10 @@ <h2 id="parameters">Parameters</h2>
<dd>Curve from your experimental data.</dd>
<dt><strong><code>num_data</code></strong> :&ensp;<code>ndarray (2-D)</code></dt>
<dd>Curve from your numerical data.</dd>
<dt><strong><code>norm_seg_length</code></strong> :&ensp;<code>boolean</code></dt>
<dd>Whether to divide the segment length of each curve by the maximum. The
default value is false, which more closely follows the algorithm
proposed in [1]_. Versions prior to 0.6.0 used <code>norm_seg_length=True</code>.</dd>
</dl>
<h2 id="returns">Returns</h2>
<dl>
Expand All @@ -2244,6 +2273,8 @@ <h2 id="returns">Returns</h2>
<h2 id="notes">Notes</h2>
<p>Your x locations of data points should be exp_data[:, 0], and the y
locations of the data points should be exp_data[:, 1]. Same for num_data.</p>
<p>PCM distance was changed in version 0.6.0. To get the same results from
previous versions, set <code>norm_seg_length=True</code>.</p>
<h2 id="references">References</h2>
<p>.. [1] Katharina Witowski and Nielen Stander. "Parameter Identification of
Hysteretic Models Using Partial Curve Mapping", 12th AIAA Aviation
Expand All @@ -2270,7 +2301,7 @@ <h2 id="examples">Examples</h2>
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def pcm(exp_data, num_data):
<pre><code class="python">def pcm(exp_data, num_data, norm_seg_length=False):
&#34;&#34;&#34;
Compute the Partial Curve Mapping area.

Expand All @@ -2283,6 +2314,10 @@ <h2 id="examples">Examples</h2>
Curve from your experimental data.
num_data : ndarray (2-D)
Curve from your numerical data.
norm_seg_length : boolean
Whether to divide the segment length of each curve by the maximum. The
default value is false, which more closely follows the algorithm
proposed in [1]_. Versions prior to 0.6.0 used `norm_seg_length=True`.

Returns
-------
Expand All @@ -2294,6 +2329,9 @@ <h2 id="examples">Examples</h2>
Your x locations of data points should be exp_data[:, 0], and the y
locations of the data points should be exp_data[:, 1]. Same for num_data.

PCM distance was changed in version 0.6.0. To get the same results from
previous versions, set `norm_seg_length=True`.

References
----------
.. [1] Katharina Witowski and Nielen Stander. &#34;Parameter Identification of
Expand Down Expand Up @@ -2323,8 +2361,8 @@ <h2 id="examples">Examples</h2>
xi1, eta1, xi2, eta2 = normalizeTwoCurves(exp_data[:, 0], exp_data[:, 1],
num_data[:, 0], num_data[:, 1])
# compute the arc lengths of each curve
le, le_nj, le_sum = get_length(xi1, eta1)
lc, lc_nj, lc_sum = get_length(xi2, eta2)
le, le_nj, le_sum = get_length(xi1, eta1, norm_seg_length)
lc, lc_nj, lc_sum = get_length(xi2, eta2, norm_seg_length)
# scale each segment to the total polygon length
le = le / le_nj
le_sum = le_sum / le_nj
Expand All @@ -2334,8 +2372,8 @@ <h2 id="examples">Examples</h2>
# make sure a is shorter than a&#39;, if not swap the defintion
if lc_nj &gt; le_nj:
# compute the arc lengths of each curve
le, le_nj, le_sum = get_length(xi2, eta2)
lc, lc_nj, lc_sum = get_length(xi1, eta1)
le, le_nj, le_sum = get_length(xi2, eta2, norm_seg_length)
lc, lc_nj, lc_sum = get_length(xi1, eta1, norm_seg_length)
# scale each segment to the total polygon length
le = le / le_nj
le_sum = le_sum / le_nj
Expand Down
2 changes: 1 addition & 1 deletion docs/version.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ <h1 class="title">Module <code>similaritymeasures.version</code></h1>
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">__version__ = &#34;0.5.0&#34;</code></pre>
<pre><code class="python">__version__ = &#34;0.6.0&#34;</code></pre>
</details>
</section>
<section>
Expand Down
Loading

0 comments on commit 2439d7a

Please sign in to comment.