# Interpolations.jl: different fill values left and right for FillExtrapolation

**URL:** <https://discourse.julialang.org/t/interpolations-jl-different-fill-values-left-and-right-for-fillextrapolation/92193>\
**Category:** General Usage\
**Tags:** interpolations\
**Created:** [December 27, 2022, 5:52pm UTC](https://discourse.julialang.org/t/interpolations-jl-different-fill-values-left-and-right-for-fillextrapolation/92193 "2022-12-27T17:52:04Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![tom-plaa](https://avatars.discourse-cdn.com/v4/letter/t/d26b3c/32.png) [@tom-plaa](https://discourse.julialang.org/u/tom-plaa)\
**Post date:** [December 27, 2022, 5:52pm UTC](https://discourse.julialang.org/t/interpolations-jl-different-fill-values-left-and-right-for-fillextrapolation/92193/1 "2022-12-27T17:52:04Z")

</div>

Is it possible to select different fill values for left and right for extrapolation?  
For example, imagine I want the interpolation object to return 0 when to left of the minimum existing value in the grid and 1 when it’s to the right of the maximum existing value in the grid.

My naive attempts:

```julia
julia> using Interpolations

julia> testvector = rand(10)
10-element Vector{Float64}:
 0.6057931199864178
 0.43856861325879903
 0.9548698226248755
 0.8378373282482391
 0.8473327381106962
 0.21294308592509092
 0.45082522330659225
 0.8614753487397658
 0.22748963029677682
 0.6711081947725003

julia> testitp1 = linear_interpolation(1:1:10, testvector, extrapolation_bc=(0.0,1.0))
10-element extrapolate(scale(interpolate(::Vector{Float64}, BSpline(Linear())), (1:1:10,)), (0.0, 1.0)) with element type Any:
 0.6057931199864178
 0.43856861325879903
 0.9548698226248755
 0.8378373282482391
 0.8473327381106962
 0.21294308592509092
 0.45082522330659225
 0.8614753487397658
 0.22748963029677682
 0.6711081947725003

julia> testitp1(0.5)
(0.0, 1.0)

```

So I get back the actual tuple. I tried it like this because we can specify, for example, `(Flat(),Linear())` to get different behaviours left and right.

I had a look at the code in [Interpolations.jl/filled.jl at master · JuliaMath/Interpolations.jl · GitHub](https://github.com/JuliaMath/Interpolations.jl/blob/master/src/extrapolation/filled.jl) but I couldn’t figure out how to achieve this.

The reason for this is to provide approximations for probability density functions and cumulative density functions. For pdf’s, the single value of 0 is sufficient, for cdf’s I need to put 0 to the left and 1 to the right.

EDIT: As a last resort I know I can define my interpolated function by branches and have it use the left branch with one value and the right branch with another, but I would like to know if there’s something more elegant.

---

<div class="post-metadata">

**Author:** ![Dan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dan/32/42581_2.png) [@Dan](https://discourse.julialang.org/u/Dan)\
**Post date:** [December 27, 2022, 7:05pm UTC](https://discourse.julialang.org/t/interpolations-jl-different-fill-values-left-and-right-for-fillextrapolation/92193/3 "2022-12-27T19:05:07Z")

</div>

If the goal is to make a CDF, then the `testvector` should be sorted (as a CDF is monotonic).

Additionally, for a `0.0` value to the left and `1.0` to the right of `testvector` domain, `0.0` can be added before, and `1.0` after `testvector` and `extrapolation_bc` set to `Flat()`.

In code:

```julia
julia> testitp1 = linear_interpolation(0:1:11, 
  vcat(0.0, sort(testvector), 1.0), extrapolation_bc=Flat())
12-element extrapolate(...)

julia> using UnicodePlots

```

```julia
julia> lineplot(x->testitp1[x], -4.0, 14.0; xlim=(-4.0,14.0))
          ┌────────────────────────────────────────┐       
        1 │⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡰⠋⠉⠉⠉⠉⠉⠉│ #11(x)
          │⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠜⠁⠀⠀⠀⠀⠀⠀⠀│       
          │⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡎⠀⠀⠀⠀⠀⠀⠀⠀⠀│       
          │⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⣀⡎⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│       
          │⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│       
          │⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣀⡤⠴⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│       
          │⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⢀⡔⠒⠋⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│       
   f(x) │⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⣀⠤⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│       
          │⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⡏⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│       
          │⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│       
          │⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⡜⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│       
          │⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⢀⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│       
          │⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│       
          │⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│       
        0 │⣀⣀⣀⣀⣀⣀⣀⣀⣸⡠⠎⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│       
          └────────────────────────────────────────┘       
          ⠀-4⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀14⠀       
          ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀x⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀       

```

Hope this helps. There might be better methods to generate CDFs from a sample.

---

<div class="post-metadata">

**Author:** ![tom-plaa](https://avatars.discourse-cdn.com/v4/letter/t/d26b3c/32.png) [@tom-plaa](https://discourse.julialang.org/u/tom-plaa)\
**Post date:** [December 27, 2022, 7:14pm UTC](https://discourse.julialang.org/t/interpolations-jl-different-fill-values-left-and-right-for-fillextrapolation/92193/4 "2022-12-27T19:14:17Z")

</div>

Thanks @Dan . My example is obviously not a cdf, it was just a MWE. The cdf bit was to contextualize.

I was currently defining my cdf by branches, although your solution could be used, but it requires me to also add 2 extra points to the x axis. In this MWE we go from 1:1:10 to 0:1:11, but in generalized context I would have to choose some small spacing, which could be tricky if the grid isn’t constant.

---

<div class="post-metadata">

**Author:** ![Dan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dan/32/42581_2.png) [@Dan](https://discourse.julialang.org/u/Dan)\
**Post date:** [December 27, 2022, 7:27pm UTC](https://discourse.julialang.org/t/interpolations-jl-different-fill-values-left-and-right-for-fillextrapolation/92193/5 "2022-12-27T19:27:01Z")

</div>

My example shows how to fix the interpolation function on both sides. There really needs to be some knots (in interpolation parlance) on the left and right with the values the extrapolation needs to take.  
If the example is not sufficient, maybe the MWE does not capture the whole problem.

---

<div class="post-metadata">

**Author:** ![tom-plaa](https://avatars.discourse-cdn.com/v4/letter/t/d26b3c/32.png) [@tom-plaa](https://discourse.julialang.org/u/tom-plaa)\
**Post date:** [December 27, 2022, 7:35pm UTC](https://discourse.julialang.org/t/interpolations-jl-different-fill-values-left-and-right-for-fillextrapolation/92193/6 "2022-12-27T19:35:34Z")

</div>

> [@Dan](#):
>
> There really needs to be some knots (in interpolation parlance) on the left and right with the values the extrapolation needs to take.

Exactly, this is the only thing I was pointing out, as your solution is evidently clean and does the job. It’s just that we might have knots that are not equidistant and we are just performing linear interpolation. In that case, the distance between knots x\_{-1} and x\_0 (for the left flat extrapolation) and the distance between knots x\_{N} and x\_{N+1} (for the right flat extrapolation) have to be decided by some kind of rule. If they the distance is too great, we might be inducing a fake slope that doesn’t exist in the original function on the end points whereas a smaller distance would result more like a truncation. The default Flat() methodology is a truncation, if I understand it correctly.

Now that I think about it, your solution never has distance = 0 so it is not a truncation, even with a constant grid, with equidistant knots.
