RESAMPLE_POLY
Polyphase resampling changes a signal’s sampling rate by first inserting additional samples, then applying a low-pass FIR filter, and finally keeping every selected output sample. It is often preferred over FFT-based resampling for long signals or lengths with large prime factors.
For an upsampling factor u and downsampling factor d, the resulting sample-rate conversion ratio is:
\frac{f_{s,\text{out}}}{f_{s,\text{in}}} = \frac{u}{d}
The low-pass filter is designed so that spectral images created during upsampling are suppressed before downsampling. Boundary behavior is controlled with the selected padding mode.
Excel Usage
=RESAMPLE_POLY(x, up, down, window, poly_padtype, cval)
x(list[list], required): The data to be resampled.up(int, required): The upsampling factor.down(int, required): The downsampling factor.window(str, optional, default: “kaiser”): Desired window to use for the FIR filter (defaults to Kaiser window with beta=5).poly_padtype(str, optional, default: “constant”): The signal extension mode to use at boundaries.cval(float, optional, default: 0): Value to use if padtype is ‘constant’.
Returns (list[list]): A 2D array of the resampled data.
Example 1: Upsample by 2
Inputs:
| x | up | down | ||
|---|---|---|---|---|
| 1 | 2 | 3 | 2 | 1 |
Excel formula:
=RESAMPLE_POLY({1,2,3}, 2, 1)
Expected output:
| Result | |||||
|---|---|---|---|---|---|
| 1.00052 | 1.29462 | 2.00103 | 2.96514 | 3.00155 | 1.60706 |
Example 2: Downsample by 2
Inputs:
| x | up | down | |||||
|---|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | 1 | 2 |
Excel formula:
=RESAMPLE_POLY({1,2,3,4,5,6}, 1, 2)
Expected output:
| Result | ||
|---|---|---|
| 1.06167 | 2.7954 | 5.46644 |
Example 3: Resample by a 3-to-2 polyphase ratio
Inputs:
| x | up | down | |||||
|---|---|---|---|---|---|---|---|
| 0 | 1 | 0 | -1 | 0 | 1 | 3 | 2 |
Excel formula:
=RESAMPLE_POLY({0,1,0,-1,0,1}, 3, 2)
Expected output:
| Result | ||||||||
|---|---|---|---|---|---|---|---|---|
| 2.79341e-17 | 0.761991 | 0.925732 | 3.1772e-17 | -0.876403 | -0.876403 | 3.1772e-17 | 0.925732 | 0.761991 |
Example 4: Resample with line boundary extension
Inputs:
| x | up | down | poly_padtype | ||||
|---|---|---|---|---|---|---|---|
| 2 | 3 | 5 | 7 | 11 | 2 | 1 | line |
Excel formula:
=RESAMPLE_POLY({2,3,5,7,11}, 2, 1, "line")
Expected output:
| Result | |||||||||
|---|---|---|---|---|---|---|---|---|---|
| 2.00103 | 2.44091 | 3.00155 | 3.98362 | 5.00259 | 5.81483 | 7.00362 | 8.92601 | 11.0057 | 12.392 |
Python Code
Show Code
import numpy as np
from scipy.signal import resample_poly as scipy_resample_poly
def resample_poly(x, up, down, window='kaiser', poly_padtype='constant', cval=0):
"""
Resample x along the matrix using polyphase filtering.
See: https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.resample_poly.html
This example function is provided as-is without any representation of accuracy.
Args:
x (list[list]): The data to be resampled.
up (int): The upsampling factor.
down (int): The downsampling factor.
window (str, optional): Desired window to use for the FIR filter (defaults to Kaiser window with beta=5). Default is 'kaiser'.
poly_padtype (str, optional): The signal extension mode to use at boundaries. Valid options: Constant, Line, Mean, Median, Maximum, Minimum. Default is 'constant'.
cval (float, optional): Value to use if padtype is 'constant'. Default is 0.
Returns:
list[list]: A 2D array of the resampled data.
"""
try:
def to_1d(v):
if isinstance(v, list):
return np.array([float(x) for row in v for x in row])
return np.array([float(v)])
x_arr = to_1d(x)
# Preserve SciPy's default Kaiser tuple when users leave the window as the wrapper default.
win = window
if win == "kaiser":
win = ("kaiser", 5.0)
kwargs = {
"window": win,
"padtype": poly_padtype,
}
if poly_padtype == "constant":
kwargs["cval"] = float(cval)
result = scipy_resample_poly(x_arr, int(up), int(down), **kwargs)
return [result.tolist()]
except Exception as e:
return f"Error: {str(e)}"