# Cubic spline for non monotonic vector

**URL:** https://discourse.julialang.org/t/cubic-spline-for-non-monotonic-vector/112599
**Category:** Performance
**Tags:** splines
**Created:** [April 6, 2024, 5:16am UTC](https://discourse.julialang.org/t/cubic-spline-for-non-monotonic-vector/112599 "2024-04-06T05:16:34Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![jgr](https://avatars.discourse-cdn.com/v4/letter/j/cdc98d/32.png) [@jgr](https://discourse.julialang.org/u/jgr)
#### Post date: [April 6, 2024, 5:16am UTC](https://discourse.julialang.org/t/cubic-spline-for-non-monotonic-vector/112599/1 "2024-04-06T05:16:35Z")

</div>

I am using Spline1D from Dierckx package, and my code is

```julia
Ev = [2, 1, 3,4]
sgrid = [0, 1, 2,4]
spl = Spline1D(Ev,sgrid)

```

The error I got is

```julia
Error on entry, no approximation returned. The following conditions
must hold:
1<=k<=5
x[1] < x[2] < ... < x[end]
w[i] > 0.0 for all i

```

My understanding is that Spline1D does not allow `Ev` to be non-monotonic. But first I don’t understand why they have this requirement – can’t we do cubic spline on non-monotonic vectors? Second, I was wondering what method I should use for interpolation in this case?

---

<div class="post-metadata">

### Author: ![SteffenPL](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/steffenpl/32/206270_2.png) [@SteffenPL](https://discourse.julialang.org/u/SteffenPL)
#### Post date: [April 6, 2024, 5:25am UTC](https://discourse.julialang.org/t/cubic-spline-for-non-monotonic-vector/112599/2 "2024-04-06T05:25:08Z")

</div>

Splines always describe a parameterisation of a curve or surface.

Like a function f(x) cannot have two values for the same x value, a spline cannot have two values for the same input.

If you want to describe an arbitrary curve in 2D, you can do it with a map s: [0,1] \to \mathbb{R}^2 instead where the first component s\_1 would describe the non-monotonic X values.

---

<div class="post-metadata">

### Author: ![jgr](https://avatars.discourse-cdn.com/v4/letter/j/cdc98d/32.png) [@jgr](https://discourse.julialang.org/u/jgr)
#### Post date: [April 6, 2024, 5:30am UTC](https://discourse.julialang.org/t/cubic-spline-for-non-monotonic-vector/112599/3 "2024-04-06T05:30:06Z")

</div>

Thank you for the reply. But I’m not sure I get what you mean. What is R^2 supposed to be? Another question is that for each x (sgrid element), I indeed only have 1 value in Ev?

---

<div class="post-metadata">

### Author: ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)
#### Post date: [April 6, 2024, 9:09am UTC](https://discourse.julialang.org/t/cubic-spline-for-non-monotonic-vector/112599/4 "2024-04-06T09:09:42Z")

</div>

Can you provude a minimal working example (MWE) that reproduces the issue? That would make it much easier to give a concrete advise…

---

<div class="post-metadata">

### Author: ![bertschi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bertschi/32/33462_2.png) [@bertschi](https://discourse.julialang.org/u/bertschi)
#### Post date: [April 6, 2024, 9:54am UTC](https://discourse.julialang.org/t/cubic-spline-for-non-monotonic-vector/112599/5 "2024-04-06T09:54:24Z")

</div>

Can’t you just sort them before passing to the constructor?

```julia-repl
julia> using Dierckx

julia> Ev = [2, 1, 3]; sgrid = [0, 1, 2];

julia> ord = sortperm(Ev)
3-element Vector{Int64}:
 2
 1
 3

julia> spl = Spline1D(Ev[ord],sgrid[ord]; k=2)
Spline1D(knots=[1.0, 3.0], k=2, extrapolation="nearest", residual=0.0)

# Check that spline passes through your points
julia> spl.(Ev) .- sgrid
3-element Vector{Float64}:
 0.0
 0.0
 0.0

```

---

<div class="post-metadata">

### Author: ![jgr](https://avatars.discourse-cdn.com/v4/letter/j/cdc98d/32.png) [@jgr](https://discourse.julialang.org/u/jgr)
#### Post date: [April 6, 2024, 7:48pm UTC](https://discourse.julialang.org/t/cubic-spline-for-non-monotonic-vector/112599/6 "2024-04-06T19:48:59Z")

</div>

Thanks. I just modified my question acccordingly.
