-
-
Notifications
You must be signed in to change notification settings - Fork 55
Add derivatives for the splines #72
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
Conversation
I am finding it hard to get the BSpline derivative right. From my understanding the derivative of a BSpline is another BSpline of lower order. Reference N = spline_coefficients(n, A.d - 1, A.k[2:(end - 1)], t)
ducum = zero(eltype(A.u))
for i = 1:(n - 1)
ducum += N[i] * (A.c[i + 1] - A.c[i]) / (A.k[i + A.d + 1] - A.k[i + 1])
end
ducum * A.d But the gradients seem to be way off. |
That looks like it might introduce some numerical errors? I think @YingboMa might have comments on this. |
@YingboMa any thoughts on this? |
Is there a version where BSplines are left off that we can open an issue on to complete later? |
Sorry, I missed this PR. I will review it today. |
Co-authored-by: Yingbo Ma <[email protected]>
I can help with the BSpline derivative later today. |
For the BSpline derivative, you should check pg. 72 of the NURBS book https://www.springer.com/gp/book/9783642973857. I am not familiar with BSplines, but I think a bulletproof way of differentiating BSplines is just to differentiate each basis function individually. |
The current implementation was differentiating each basis function itself. I removed the BSpline implementation for the time being so that we can move forward with the PR, and can tackle that later. |
I think you have an off-by-one error in your code, also the derivative of the coordinate transformation is missing. This gives the correct derivative using DataInterpolations, Calculus
ts = 0:4
data = sin.(ts)
A = BSplineInterpolation(data,float.(ts),3,:ArcLen,:Average)
n = length(A.t)
t = 0.1
idx = searchsortedlast(A.t,t)
idx == length(A.t) ? idx -= 1 : nothing
t_ = A.p[idx] + (t - A.t[idx])/(A.t[idx+1] - A.t[idx]) * (A.p[idx+1] - A.p[idx])
Nm1 = DataInterpolations.spline_coefficients(n, A.d-1, A.k, t_)
scale = (A.t[idx+1] - A.t[idx]) * (A.p[idx+1] - A.p[idx])
ducum = zero(eltype(A.u))
for i = 1:(n - 1)
ducum += Nm1[i+1] * (A.c[i + 1] - A.c[i]) / (A.k[i + A.d + 1] - A.k[i + 1])
end
ducum * A.d * scale
Calculus.derivative(A, t) julia> ducum * A.d * scale
1.0854013436178458
julia> Calculus.derivative(A, t)
1.0854013436149472 |
Co-authored-by: Yingbo Ma <[email protected]>
d15d17e
to
484749d
Compare
I rebased this branch back to current master since it was falling behind a bit. |
TODOs:
Follow up from SciML/DiffEqFlux.jl#380