-
-
Notifications
You must be signed in to change notification settings - Fork 5.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ENH: Improve FIR path of signal.decimate #5975
Conversation
@@ master #5975 diff @@
======================================
Files 238 238
Stmts 43803 43814 +11
Branches 8211 8214 +3
Methods 0 0
======================================
+ Hit 34230 34244 +14
+ Partial 2603 2602 -1
+ Missed 6970 6968 -2
|
It's good to add that capability. I didn't do it originally to keep the PR simple, and to offload the work of getting it right on the next developer. Looks like you fell into my trap :) |
@@ -1896,6 +1896,9 @@ def resample_poly(x, up, down, axis=0, window=('kaiser', 5.0)): | |||
Desired window to use to design the low-pass filter. See | |||
`scipy.signal.get_window` for a list of windows and required | |||
parameters. | |||
num : array_like, optional | |||
FIR filter coefficients of the low-pass filter to be used. Overrides | |||
the `window` argument if not None. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just roll this into window
. See e.g. how resample
allows multiple types for window
:
http://docs.scipy.org/doc/scipy-0.16.0/reference/generated/scipy.signal.resample.html
So we're swapping in (currently) |
BTW can you add a comment about the speed gains? We doing Speaking of which, this is one way that you might need to change the code -- I think that |
Thanks for the feedback @Eric89GXL! I've incorporated much of your feedback. The speed gains of As for the |
A comment in the code saying why
I don't expect the zero-padding to really matter.
|
Ok, testing vs I was unclear before, the zero-padding I was referring to was in regards to the input signal, not the filter. |
That makes sense. Glad they match. I'll look deeper soon.
Any practical numbers on what the resample_poly speedup is like over
filtfilt? I'm curious how close it gets to being `down` times faster.
|
Decimating x=np.random.randn(10**7) with
This comes from the additional time cost of slicing the output of |
Excellent. Is this good to go from your end, then? |
yep! |
f_c = 1. / max_rate # cutoff of FIR filter (rel. to Nyquist) | ||
half_len = 10 * max_rate # reasonable cutoff for our sinc-like function | ||
h = firwin(2 * half_len + 1, f_c, window=window) | ||
n_out = int(np.ceil(x.shape[axis] * up / down)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This used to effectively be floor
, why the change to ceil
?
I assume it's for the extra sample in case it doesn't divide evenly, In that case it would actually be better to use integer arithmetic if possible so we stay exact, like:
n_out = x.shape['axis'] * up
n_out = n_out // down + bool(n_out % down)
Other than my minor comments, LGTM. |
Good points all around, addressed and squashed. Thanks! The short answer about the change of Incidentally, you'll see in the |
IIRC |
Is this good to go? |
step, so it should be designed to operate on a signal at a sampling | ||
frequency higher than the original by a factor of `up//gcd(up, down)`. | ||
This function's output will be centered with respect to this array, so it | ||
is best to pass a symmetric filter with an odd number of samples to if, as |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"number of samples to if" -> "number of samples if"
Other than my one new gripe, +1 for merge. After the rewording, let's wait a day or two to see if anyone else wants to comment then merge |
This PR aims to relieve the phase shift due to the group delay of an FIR downsampling filter in signal.decimate through the use of `resample_poly`. This requires modifying `resample_poly` to accept arbitrary FIR filter coefficients, as `decimate` itself advertises that capability. A test for `resample_poly` has been added for this capability. Additionally, the "traditional" FIR path has been sped up via the use of `upfirdn` which only calculates every q'th output.
Since `resample_poly` is used instead of `filtfilt` in `decimate` for FIR decimation for speed reasons, this adds a test to ensure equivalent output of these two methods.
Thanks for the look! The wording has been addressed.
|
Thanks @e-q |
@@ -3,12 +3,29 @@ | |||
import numpy as np | |||
|
|||
try: | |||
from scipy.signal import lfilter, firwin | |||
from scipy.signal import lfilter, firwin, decimate |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Usually best to put these in a separate import statement, so that not having decimate does not prevent running eg the firwin benchmarks
This PR aims to relieve the phase shift due to the group delay of an FIR downsampling filter in signal.decimate through the use of
resample_poly
.This requires modifying
resample_poly
to accept arbitrary FIR filter coefficients, asdecimate
itself advertises that capability. A test forresample_poly
has been added for this capability. Hopefully this isn't too much of a hack. (Thoughts, @Eric89GXL ?)