Skip to content
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

Document spline node requirements for RQSpline #26

Open
oschulz opened this issue Dec 27, 2024 · 4 comments
Open

Document spline node requirements for RQSpline #26

oschulz opened this issue Dec 27, 2024 · 4 comments
Assignees
Labels
bug Something isn't working

Comments

@oschulz
Copy link
Member

oschulz commented Dec 27, 2024

With

using MonotonicSplines, InverseFunctions, Plots

X = [-3.6, -3.51, -3.37, -3.23, -3.04, -2.83, -2.57, -2.33, -2.1, -1.87, -1.65, -1.44, -1.24, -1.03, -0.83, -0.63, -0.46, -0.29, -0.12, 0.04, 0.2, 0.35, 0.49, 0.62, 0.75, 0.88, 0.99, 1.11, 1.22, 1.33, 1.43, 1.53, 1.62, 1.72, 1.81, 1.9, 1.99, 2.08, 2.17, 2.26];
Y = [-3.09, -2.93, -2.77, -2.61, -2.46, -2.3, -2.14, -1.98, -1.82, -1.66, -1.51, -1.35, -1.19, -1.03, -0.87, -0.71, -0.55, -0.4, -0.24, -0.08, 0.08, 0.24, 0.4, 0.55, 0.71, 0.87, 1.03, 1.19, 1.35, 1.51, 1.66, 1.82, 1.98, 2.14, 2.3, 2.46, 2.61, 2.77, 2.93, 3.09];

dYdX = MonotonicSplines.estimate_dYdX(X, Y);

f = RQSpline(X, Y, dYdX)

(fairly smooth spline parameters) we get

julia> inverse(f)(-3.6)
ERROR: DomainError with -0.4346471879176269:
sqrt was called with a negative real argument but will only return a complex result if called with a complex argument. Try sqrt(Complex(x)).

and the spline is not monotonic and has discontinuities:

plot(-6:0.01:6, f)

spline

@oschulz oschulz added the bug Something isn't working label Dec 27, 2024
@Micki-D
Copy link
Collaborator

Micki-D commented Dec 27, 2024

I believe this issue arises due to the implicit requirements to the spline parameters under the hood:
- edge knots at the beginning and end of the interval must sit on the identity line
- the derivatives at the edge knots must be set to 1

When I modify your above example to comply with these requirements, I get the following spline:

X_new = deepcopy(X)
Y_new = deepcopy(Y)
dYdX_new = deepcopy(dYdX)

pushfirst!(X_new, -3.8)
pushfirst!(Y_new, -3.8)

push!(X_new, 3.4)
push!(Y_new, 3.4)

pushfirst!(dYdX_new, 1.)
push!(dYdX_new, 1.)

f_new = RQSpline(X_new, Y_new, dYdX_new)

plot(-6:0.01:6, f_new, label = "New spline")
scatter!(X,Y, label = "Previous knots")
scatter!([-3.8, 3.4], [-3.8, 3.4], color = :green, label = "Added edge knots on identity")

modified_spline

And the spline behaves correctly:

julia> f_new(-3.6)
-3.09

julia> f_new(-3.8)
-3.8

@Micki-D
Copy link
Collaborator

Micki-D commented Dec 27, 2024

So to fix this issue, I suggest we add an inbuilt mechanism that guarantees these requirements to the spline parameters are met.

Perhaps in rqs_forward() and rqs_inverse().

@oschulz
Copy link
Member Author

oschulz commented Dec 27, 2024

Good point - for now, let's just add this to the docs of RQSpline.

@Micki-D
Copy link
Collaborator

Micki-D commented Dec 27, 2024

Alright!

@oschulz oschulz changed the title Incorrect spline and failing inverse in some cases Document spline node requirements for RQSpline Dec 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants