Skip to main content

Differences from SciPy

Signal Processing follows SciPy 1.18.1 in names, parameters, defaults and results. This page lists every place where it deliberately does something else, and why.

Everywhere​

  • Data must be clean numbers. None, NaN and infinity in a signal raise ValueError, where SciPy would let NaN spread silently through every result. Historian gaps arrive as None, so fill or drop them first.
  • Signals are one-dimensional. axis accepts -1 and 0, which mean the same for a list.
  • Lists and tuples are interchangeable. Jython cannot always tell them apart, so ['kaiser', 8.6] works like ('kaiser', 8.6).
  • Whole-number arguments must be integers. Orders, lengths and factors (N, nperseg, noverlap, nfft, window_length, polyorder, num, q) refuse floats with TypeError. SciPy truncates floats in some places and fails on them in others.
  • Errors are Python ValueError and TypeError, raised where SciPy raises them; messages may be worded differently.
  • Script functions only. There are no expression functions in this version.

Function by function​

FunctionDifference
get_windowThe dpss window is not available.
detrendAn empty breakpoint list means no breakpoints (SciPy raises TypeError).
butter, cheby1, cheby2, ellip, besselOrders above 500 are refused (Bessel: above 100).
freqzplot must be None: there is nothing to plot to in a gateway.
filtfiltmethod='gust' is not supported; the default 'pad' is.
savgol_coeffs, savgol_filterThe least-squares fits are solved exactly (see below).
find_peaksTies under distance are ranked by position (see below). Per-sample borders, numpy arrays of len(x) in SciPy, are not available; a list is compared with the peaks as in SciPy.
peak_widthsprominence_data may be lists (SciPy needs numpy arrays).
welch, periodogram, spectrogramdetrend is 'constant', 'linear' or off; functions are not accepted.
resample, resample_polyA window given as a list of numbers is used as the window's values (SciPy needs a numpy array).
decimateftype is 'iir' or 'fir'; dlti systems are not accepted.

Where it does better than SciPy 1.18.1​

These came out of testing against SciPy and are kept on purpose.

  • Savitzky-Golay coefficients stay correct at high orders. SciPy's floating-point least-squares solver discards information when the fit is badly conditioned: its coefficients are accurate to about 1e-8 for polynomial orders up to 4, but entirely wrong at order 8 over 201 points. Signal Processing solves the fit exactly and rounds once. Where SciPy is accurate, the results agree.
  • find_peaks with distance is deterministic. When equal-height peaks compete, SciPy ranks them with an unstable sort whose order for ties depends on the processor; on quantized data that changed SciPy's answer in about 3% of tested calls. Signal Processing keeps the later peak, as a stable sort does.
  • Prominences and widths are fast on trending signals. SciPy searches back to the nearest higher sample for every peak, which on a rising signal costs time proportional to the square of its length: 1.4 s for 100,000 points. Signal Processing finds the same answers in 57 ms.
  • Plain lists work for welch and spectrogram. SciPy 1.18.1 raises AttributeError for a list in both.
  • resample_poly cannot crash the interpreter. With padtype='reflect' or 'antireflect' on a 1-sample signal, SciPy 1.18.1 kills the Python process ("Floating point exception"). Signal Processing raises ValueError.
  • Bessel filters work up to order 100. SciPy's root finding fails from about order 90.

How closely results agree​

AgreementFunctions
Identical to the last bitlfilter (IIR), sosfilt, sosfiltfilt, filtfilt, lfilter_zi, sosfilt_zi, medfilt, find_peaks, peak_prominences, peak_widths, and the interior of savgol_filter
Within a few roundings of the result's sizedetrend, get_window, freqz, freqz_sos, the FFT-based welch, periodogram, spectrogram, hilbert and resample, and resample_poly
Within the problem's own sensitivityFilter designs, order selection, and decimate's IIR filter: where a design is ill-conditioned, a tiny change in the input moves SciPy's own answer more than any difference between the two