Skip to content

Commit 6436942

Browse files
committed
add: use ws interp for nyq grid
1 parent 792e22d commit 6436942

File tree

2 files changed

+75
-17
lines changed

2 files changed

+75
-17
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)
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)
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)
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+
tp,
737+
left=sum(self.dGobs[:1]),
738+
right=sum(self.dGobs[-1:]),
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)
@@ -819,6 +813,47 @@ def grid_interpolation(x0, y0, x1, youtleft=0.0, youtright=0.0):
819813
y1[m1] = w0lo * y0[ilo0] + w0hi * y0[ihi0]
820814
return y1
821815

816+
def grid_interpolation(x0, y0, x1, tp, left=None, right=None):
817+
"""
818+
Interpolate values from one grid onto another using either linear
819+
or 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+
822857

823858
# simple test code
824859
if __name__ == "__main__":

0 commit comments

Comments
 (0)