Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 31 additions & 5 deletions lib/matplotlib/mlab.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@
"""

import functools
from numbers import Number
from numbers import Integral, Number
import sys

import numpy as np

Expand Down Expand Up @@ -210,6 +211,23 @@ def detrend_linear(y):
return y - (b*x + a)


def _stride_windows(x, n, noverlap=0):
x = np.asarray(x)

_api.check_isinstance(Integral, n=n, noverlap=noverlap)
if not (1 <= n <= x.size and n < noverlap):
raise ValueError(f'n ({n}) and noverlap ({noverlap}) must be positive integers '
f'with n < noverlap and n <= x.size ({x.size})')

if n == 1 and noverlap == 0:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the special-case here can go away, it should be handled by the general case below.

return x[np.newaxis]

step = n - noverlap
shape = (n, (x.shape[-1]-noverlap)//step)
strides = (x.strides[0], step*x.strides[0])
return np.lib.stride_tricks.as_strided(x, shape=shape, strides=strides)


def _spectral_helper(x, y=None, NFFT=None, Fs=None, detrend_func=None,
window=None, noverlap=None, pad_to=None,
sides=None, scale_by_freq=None, mode=None):
Expand Down Expand Up @@ -304,17 +322,25 @@ def _spectral_helper(x, y=None, NFFT=None, Fs=None, detrend_func=None,
raise ValueError(
"The window length must match the data's first dimension")

result = np.lib.stride_tricks.sliding_window_view(
x, NFFT, axis=0)[::NFFT - noverlap].T
if sys.maxsize > 2**32:
result = np.lib.stride_tricks.sliding_window_view(
x, NFFT, axis=0)[::NFFT - noverlap].T
else:
# The NumPy version on 32-bit will OOM, so use old implementation.
result = _stride_windows(x, NFFT, noverlap=noverlap)
result = detrend(result, detrend_func, axis=0)
result = result * window.reshape((-1, 1))
result = np.fft.fft(result, n=pad_to, axis=0)[:numFreqs, :]
freqs = np.fft.fftfreq(pad_to, 1/Fs)[:numFreqs]

if not same_data:
# if same_data is False, mode must be 'psd'
resultY = np.lib.stride_tricks.sliding_window_view(
y, NFFT, axis=0)[::NFFT - noverlap].T
if sys.maxsize > 2**32:
resultY = np.lib.stride_tricks.sliding_window_view(
y, NFFT, axis=0)[::NFFT - noverlap].T
else:
# The NumPy version on 32-bit will OOM, so use old implementation.
resultY = _stride_windows(y, NFFT, noverlap=noverlap)
resultY = detrend(resultY, detrend_func, axis=0)
resultY = resultY * window.reshape((-1, 1))
resultY = np.fft.fft(resultY, n=pad_to, axis=0)[:numFreqs, :]
Expand Down