-
-
Notifications
You must be signed in to change notification settings - Fork 5.2k
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
add b-splines #3174
add b-splines #3174
Conversation
The last commit fixes the out-of-bounds behavior to be almost consistent with the b-spline definition in the literature: the interpolation interval is closed, so that the spline is left-continuous at the right-hand endpoint; outside of the interval it is zero, unless extrapolation is requested. A corner case is |
|
||
""" | ||
def __init__(self, t, c, k, extrapolate=False): | ||
super(BSpline, self).__init__() |
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 line doesn't do anything. Leftover from some subclass?
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 is deliberate: super
calls the next class in the MRO. Which can be anything if a user uses multiple inheritance (whether this is a good idea or not is a different question).
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.
Ah OK. I'm not a big fan of multiple inheritance, but this line makes sense now.
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.
Me neither.
Still, if a user decides to use it, leaving it out causes weird bugs: __init__
s will not be called.
The |
Have you considered how to replace the spline implementations in the |
Have you seen this thread: http://thread.gmane.org/gmane.comp.python.scientific.devel/17349 ? Both @pv and @charris were also working on / thinking about b-splines. |
@rgommers in fact this code heavily uses things done by Pauli, borderline shameless stealing. Thanks for the link, I'll have w closer look --- I only saw gh-1408 and scattered older ML discussions. The point of this PR is mostly to provide a stab at an implementation and to have something concrete to discuss. I'll happily scrap all this if there's a better implementation and/or if there are objections to details of the format (tck padding etc). I think this can be used for both replacing much of the fitpack in the interpolate module (interp1d, shudder), either as a replacement or making user-facing interp1d, UnivariateSpline use these under the hood. Same for cardinal splines in signal and ndimage. I'll address your comments, but for the moment I've run out of time for today, time for a New Year :-). |
Agreed that signal/ndimage is not for this PR. My question on Happy New Year! |
Happy New Year! |
Have added a couple of commits with improvements to documentation [shameless stealing from Pauli, again], small tweaks in the Also timed the evaluations (in a rather ad hoc way) against fitpack: |
Sorry for the delay. I have one bigger comment about the spline representation: I really think we should go with the representation used in FITPACK. The argument for this is:
A separate constructor could be added for the finite interval case. |
I'll just add a few comments about things that should be kept in mind for the future.
These can probably be built on top of 1D, scalar valued splines, but some thought up front may make that easier to do. |
@charris: Tensor product support should be done similarly as for piecewise polynomials in gh-3104 (not merged yet, if you have ideas how to improve that, it would be appreciated). This PR already supports vector-valued splines, if I understand what you mean correctly. Periodic splines: for evaluation, does this mean that the knot set is treated as periodic, identifying t[0] and t[-1]? |
Vector valued splines is essentially a stack of splines with the same knot points and end conditions, i.e., a map of a line segment into a multidimensional space. If they are already there, great. It also makes solving for multiple rhs more efficient. Yes, the coefficients are periodic. This mostly affects the spline construction, it is a boundary condition. I've looked at the Sherman-Morrison formula and its generalizations for doing this in the uniform spline case, but I don't know what the current state of the art is. |
I'll add that when I was looking at splines, my impression was that cubic splines were nearly optimal for most problems, apart from the results of differentiation and integration, and some boundary conditions -- not-a-knot, etc. -- made more sense with that restriction. So it might be worth while offering some options that are only available for cubic splines. |
OK, time to stop this from bitrotting completely. Rebased, squashed, addressed the review comments. Have also updated the notebook with timings (as crude as they are). Which indicate this is still very much WIP: being two to three times slower than fitpack is no good at all. The prime suspect is my half-baked evaluation routine, will investigate. |
The last commit adds the constructor for interpolating splines. Several boundary conditions are supported (natural, not-a-knot, explicit derivatives, periodic). All linear algebra uses banded matrices. Still WIP: periodic boundary conditions need a bit more work. |
Thanks. Brief look at the last commits seems to indicate that this is close to the minimal set of feature completeness. I'll hope to look at this closer soon(TM) (probably not within the next week however...) |
And use it in BSpline.basis_element.
Make splrep/splprep return tck-tuples for backwards compat, and make other spl* functions accept either tck-tuples or BSplines. Raise warnings when using spl*(Bspline, ...) with c.ndim > 1, as suggested in the code review.
OK, pushed an update where I believe I addressed @pv's review comments. Apparently Github does not hide outdated comments anymore. Relevant commits start from e6c5b72. The main change is that Also, tuple-like unpacking of BSplines is gone. This was needed for backwards compat if |
Ok, looks good to me currently, and OK to merge from my side. |
OK, I'm going to hit the green button in a couple of days, unless further comments. |
Great - thanks very much for your persistence on this one. |
Thanks @ev-br, let's get it in! |
Thanks all for the code, for the reviews, for encouragement and for evolving this from where it started to a useful state! |
Yay! Great job & persistence @ev-br. Maybe a PR to say "this is the way of the future" and clarify some of the existing text on splines in the roadmap would be a good idea? |
Here's a PR: #6715 |
Note that this introduced some performance regressions: |
Or more precisely, the |
Hmm, evaluations for |
Note that there are some performance issues that may need looking into:
https://pv.github.io/scipy-bench/regressions.xml
|
This PR implements a base class for evaluation of b-splines without fitpack.
Representation is compatible with
splrep
andsplev
though.The plan is to have a base class with a sensible API usable by both human users and interpolation / fitting to data (the latter is on an immediate plan).