Skip to content

Commit 234b387

Browse files
committed
func: adding squeeze functionallity and extrapolation indices
1 parent 3538e4d commit 234b387

File tree

2 files changed

+47
-13
lines changed

2 files changed

+47
-13
lines changed

src/diffpy/morph/morphs/morphsqueeze.py

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
import numpy as np
2+
from numpy.polynomial import Polynomial
3+
from scipy.interpolate import CubicSpline
4+
15
from diffpy.morph.morphs.morph import LABEL_GR, LABEL_RA, Morph
26

37

@@ -28,10 +32,13 @@ def morph(self, x_morph, y_morph, x_target, y_target):
2832
2933
Returns
3034
-------
31-
A tuple (x_morph_out, y_morph_out, x_target_out, y_target_out)
32-
where the target values remain the same and the morph data
33-
is shifted according to the squeeze. The morphed data is
34-
returned on the same grid as the unmorphed data.
35+
A tuple (x_morph_out, y_morph_out, x_target_out, y_target_out,
36+
min_index, max_index) where the target values remain the same and
37+
the morph data is shifted according to the squeeze. The morphed
38+
data is returned on the same grid as the unmorphed data.
39+
The min_index and max_index are the last index before the
40+
interpolated region and the first index after the interpolated
41+
region, respectively. If there is no extrapolation it returns None.
3542
3643
Example
3744
-------
@@ -54,4 +61,13 @@ def morph(self, x_morph, y_morph, x_target, y_target):
5461
"""
5562
Morph.morph(self, x_morph, y_morph, x_target, y_target)
5663

57-
return self.xyallout
64+
squeeze_polynomial = Polynomial(self.squeeze)
65+
x_squeezed = self.x_morph_in + squeeze_polynomial(self.x_morph_in)
66+
self.y_morph_out = CubicSpline(x_squeezed, self.y_morph_in)(
67+
self.x_morph_in
68+
)
69+
left_extrap = np.where(self.x_morph_in < x_squeezed[0])[0]
70+
right_extrap = np.where(self.x_morph_in > x_squeezed[-1])[0]
71+
min_index = left_extrap[-1] if left_extrap.size else None
72+
max_index = right_extrap[0] if right_extrap.size else None
73+
return self.xyallout + (min_index, max_index)

tests/test_morphsqueeze.py

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,19 @@
77
squeeze_coeffs_list = [
88
# The order of coefficients is [a0, a1, a2, ..., an]
99
# Negative cubic squeeze coefficients
10-
[-0.2, -0.01, -0.001, -0.001],
10+
[-0.2, -0.01, -0.001, -0.0001],
1111
# Positive cubic squeeze coefficients
12-
[0.2, 0.01, 0.001, 0.001],
12+
[0.2, 0.01, 0.001, 0.0001],
1313
# Positive and negative cubic squeeze coefficients
14-
[0.2, -0.01, 0.002, -0.001],
14+
[0.2, -0.01, 0.002, -0.0001],
1515
# Quadratic squeeze coefficients
1616
[-0.2, 0.005, -0.007],
1717
# Linear squeeze coefficients
1818
[0.1, 0.3],
1919
# 4th order squeeze coefficients
2020
[0.2, -0.01, 0.001, -0.001, 0.0004],
2121
# Zeros and non-zeros, the full polynomial is applied
22-
[0, 0.03, 0, -0.001],
22+
[0, 0.03, 0, -0.0001],
2323
# Testing zeros, expect no squeezing
2424
[0, 0, 0, 0, 0, 0],
2525
]
@@ -51,10 +51,28 @@ def test_morphsqueeze(x_morph, x_target, squeeze_coeffs):
5151
y_morph_expected = np.sin(x_morph)
5252
morph = MorphSqueeze()
5353
morph.squeeze = squeeze_coeffs
54-
x_morph_actual, y_morph_actual, x_target_actual, y_target_actual = morph(
55-
x_morph, y_morph, x_target, y_target
56-
)
57-
assert np.allclose(y_morph_actual, y_morph_expected)
54+
(
55+
x_morph_actual,
56+
y_morph_actual,
57+
x_target_actual,
58+
y_target_actual,
59+
low_extrap_idx,
60+
high_extrap_idx,
61+
) = morph(x_morph, y_morph, x_target, y_target)
62+
if low_extrap_idx is None and high_extrap_idx is None:
63+
assert np.allclose(y_morph_actual, y_morph_expected, atol=1e-6)
64+
else:
65+
interp_start = low_extrap_idx + 1 if low_extrap_idx is not None else 0
66+
interp_end = (
67+
high_extrap_idx
68+
if high_extrap_idx is not None
69+
else len(y_morph_actual)
70+
)
71+
assert np.allclose(
72+
y_morph_actual[interp_start:interp_end],
73+
y_morph_expected[interp_start:interp_end],
74+
atol=1e-6,
75+
)
5876
assert np.allclose(x_morph_actual, x_morph_expected)
5977
assert np.allclose(x_target_actual, x_target)
6078
assert np.allclose(y_target_actual, y_target)

0 commit comments

Comments
 (0)