Skip to content

Commit 6544a93

Browse files
add: use ws interp for nyq grid (#263)
* add: use ws interp for nyq grid * [pre-commit.ci] auto fixes from pre-commit hooks * update tests and small param order adjustment * [pre-commit.ci] auto fixes from pre-commit hooks --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 792e22d commit 6544a93

File tree

3 files changed

+76
-18
lines changed

3 files changed

+76
-18
lines changed

news/ws.rst

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
**Added:**
2+
3+
* Added Whittaker-Shannon interpolation option for grid_interpolation.
4+
5+
**Changed:**
6+
7+
* Use WS interpolation for Nyquist grid.
8+
9+
**Deprecated:**
10+
11+
* <news item>
12+
13+
**Removed:**
14+
15+
* <news item>
16+
17+
**Fixed:**
18+
19+
* <news item>
20+
21+
**Security:**
22+
23+
* <news item>

src/diffpy/pdfgui/control/fitdataset.py

Lines changed: 52 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
from diffpy.pdfgui.control.controlerrors import ControlStatusError
2323
from diffpy.pdfgui.control.parameter import Parameter
2424
from diffpy.pdfgui.control.pdfdataset import PDFDataSet
25+
from diffpy.utils.resampler import wsinterp
2526

2627

2728
class FitDataSet(PDFDataSet):
@@ -610,13 +611,14 @@ def _updateRcalcSampling(self):
610611
if frmax - (rcalcfirst + nrcalc * frstep) > frstep * 1e-8:
611612
nrcalc += 1
612613
newrcalc = rcalcfirst + frstep * numpy.arange(nrcalc + 1)
614+
tp = self.getFitSamplingType()
613615
# Gcalc:
614616
if len(self._Gcalc) > 0:
615-
newGcalc = grid_interpolation(self._rcalc, self._Gcalc, newrcalc)
617+
newGcalc = grid_interpolation(self._rcalc, self._Gcalc, newrcalc, tp=tp)
616618
self._Gcalc = list(newGcalc)
617619
# dGcalc
618620
if len(self._dGcalc) > 0:
619-
newdGcalc = grid_interpolation(self._rcalc, self._dGcalc, newrcalc)
621+
newdGcalc = grid_interpolation(self._rcalc, self._dGcalc, newrcalc, tp=tp)
620622
self._dGcalc = list(newdGcalc)
621623
# invalidate Gtrunc and dGtrunc
622624
self._Gtrunc = []
@@ -709,7 +711,8 @@ def _set_dGcalc(self, value):
709711
def _get_Gtrunc(self):
710712
self._updateRcalcSampling()
711713
if not self._Gtrunc:
712-
newGtrunc = grid_interpolation(self.robs, self.Gobs, self.rcalc)
714+
tp = self.getFitSamplingType()
715+
newGtrunc = grid_interpolation(self.robs, self.Gobs, self.rcalc, tp=tp)
713716
self._Gtrunc = list(newGtrunc)
714717
return self._Gtrunc
715718

@@ -724,13 +727,15 @@ def _set_Gtrunc(self, value):
724727
def _get_dGtrunc(self):
725728
self._updateRcalcSampling()
726729
if not self._dGtrunc:
730+
tp = self.getFitSamplingType()
727731
# use sum to avoid index error for empty arrays
728732
newdGtrunc = grid_interpolation(
729733
self.robs,
730734
self.dGobs,
731735
self.rcalc,
732-
youtleft=sum(self.dGobs[:1]),
733-
youtright=sum(self.dGobs[-1:]),
736+
left=sum(self.dGobs[:1]),
737+
right=sum(self.dGobs[-1:]),
738+
tp=tp,
734739
)
735740
self._dGtrunc = list(newdGtrunc)
736741
return self._dGtrunc
@@ -775,19 +780,8 @@ def _set_crw(self, value):
775780
##############################################################################
776781
# helper functions
777782
##############################################################################
783+
def _linear_interpolation(x0, y0, x1, youtleft, youtright):
778784

779-
780-
def grid_interpolation(x0, y0, x1, youtleft=0.0, youtright=0.0):
781-
"""Linear interpolation of x0, y0 values to a new grid x1.
782-
783-
x0 -- original x-grid, must be equally spaced
784-
y0 -- original y values
785-
x1 -- new x-grid, it can have any spacing
786-
youtleft -- value for interpolated y1 for x1 below the x0 range
787-
youtright -- value for interpolated y1 for x1 above the x0 range
788-
789-
Return numpy.array of interpolated y1 values.
790-
"""
791785
x0 = numpy.asarray(x0, copy=None, dtype=float)
792786
y0 = numpy.asarray(y0, copy=None, dtype=float)
793787
n0 = len(x0)
@@ -820,6 +814,47 @@ def grid_interpolation(x0, y0, x1, youtleft=0.0, youtright=0.0):
820814
return y1
821815

822816

817+
def grid_interpolation(x0, y0, x1, left=None, right=None, tp=None):
818+
"""Interpolate values from one grid onto another using either linear or
819+
Whittaker–Shannon interpolation.
820+
821+
Parameters
822+
----------
823+
x0 : array_like
824+
Original x-grid, must be equally spaced.
825+
y0 : array_like
826+
Original values defined on x0.
827+
x1 : array_like
828+
New x-grid upon which to interpolate.
829+
tp : {'data', 'Nyquist', 'custom'}, optional
830+
Corresponding fit sampling type. Use Whittaker–Shannon interpolation
831+
for Nyquist resampling and linear interpolation otherwise.
832+
If not provided, linear interpolation is used.
833+
left : float, optional
834+
Value for interpolated y1 for x1 below the x0 range.
835+
Default: if tp='Nyquist' then y1[0] is used. Otherwise 0.0 is used.
836+
right : float, optional
837+
Value for interpolated y1 for x1 above the x0 range.
838+
Default: if tp='Nyquist' then y1[-1] is used. Otherwise 0.0 is used.
839+
840+
Returns
841+
-------
842+
numpy.ndarray
843+
Array of interpolated values on the new grid x1.
844+
845+
Notes
846+
-----
847+
When tp='Nyquist', the function calls :func:`wsinterp` to perform Whittaker–Shannon interpolation.
848+
Otherwise it uses the internal :func:`_linear_interpolation` routine.
849+
"""
850+
if tp == "Nyquist":
851+
return wsinterp(x1, x0, y0, left, right)
852+
else:
853+
left = 0.0 if left is None else left
854+
right = 0.0 if right is None else right
855+
return _linear_interpolation(x0, y0, x1, left, right)
856+
857+
823858
# simple test code
824859
if __name__ == "__main__":
825860
FitDataSet("name")

tests/test_fitdataset.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ def test_grid_interpolation(self):
3939
y0 = numpy.sin(x0)
4040
x1 = [-6, x0[0], -0.2, x0[-1], 37]
4141
y1a = fds.grid_interpolation(x0, y0, x1)
42-
y1b = fds.grid_interpolation(x0, y0, x1, youtleft=637, youtright=638)
42+
y1b = fds.grid_interpolation(x0, y0, x1, left=637, right=638)
4343
# outside values
4444
self.assertEqual(0.0, y1a[0])
4545
self.assertEqual(637, y1b[0])

0 commit comments

Comments
 (0)