# Changing the ExtrapolationHandler Function in Any Interpolation

This is a related question to What's inside InterpolatingFunction[{{1., 4.}}, <>]? and Suppress extrapolation of interpolating function in a ContourPlot.

When interpolating a set of points, one might need to change the extrapolation behaviour, especially setting the function value to zero outside the original bounds of the data without reducing the performance time considerably.

It is possible to change the ExtrapolationHandler when a polynomial interpolation is performed as described in the answer by @Michael E2.

However, the same procedure does not work with spline interpolation (see the minimal code below).

Is there a way to change the default ExtrapolationHandler in spline interpolation?

Is it possible to change the default ExtrapolationHandler for all interpolating commands, like FunctionInterpolation, ListInterpolation, and BSplineFunction?

points = Transpose[{Range[0, 10*1.0]/10,RandomReal[{0, 10}, 10+1]}];
(* 10 points on x-axis from 0 to 1 with random numbers between 0 and
10 for the y-axis values *)

polyintpF = Interpolation[points, InterpolationOrder -> 2,
"ExtrapolationHandler" -> {(0.0 &), "WarningMessage" -> False}];
(* polynomial interpolation of order 2 *)

splineintpF = Interpolation[points, Method -> "Spline",
"ExtrapolationHandler" -> {(0.0 &), "WarningMessage" -> False}];
(* spline interpolation *)

polyintpF[2.0] (* gives zero as expected *)

(* extrapolates the function by the 'Automatic ExtrapolationHandler' ! *)
splineintpF[2.0]


A walk-around defining an intermediary function (you may want a macro instead):

Needs["DifferentialEquationsInterpolatingFunctionAnatomy"];
makeNoExtrapFun[fun_, var_, def_] :=
If[IntervalMemberQ[Interval@@InterpolatingFunctionDomain@fun, var],fun[var],def,def]

f = Interpolation[{1, 2, 1, 2, 1}, Method -> "Spline"];
k[x_] := makeNoExtrapFun[f, x, 0]
Plot[k@x, {x, 0, 8}] • k[x] evaluates to 0. Perhaps IntervalMemberQ is not the best choice. I would do something like Piecewise[{{fun[var], LessEqual @@ Riffle[First[fun["Domain"]], var]}}, def] for the body of makeNoExtrapFun. – Michael E2 Apr 12 '15 at 15:32
• @MichaelE2 I used If[ ] just because of its fourth argument – Dr. belisarius Apr 12 '15 at 16:09
• If vs. Piecewise is debatable. The main point is that IntervalMemberQ makes the function evaluate to def on non-numeric input. For instance, I'm not sure how to get the derivative of the function k[x] with D; I believe with my definition, both D[k[x], x] and k'[x] work. – Michael E2 Apr 12 '15 at 16:16
• @MichaelE2 Thanks! – Dr. belisarius Apr 12 '15 at 16:20

Recently, after trying several methods, I found that the following easy trick works the best and the fastest (in case of large number of function calls): Suppose that f is a deliberate interpolated function or spline (or B-spline),

(* note that 'points' cover the range [xmin, xmax]; see the original question above *)

splineintpF = Interpolation[points, Method -> "Spline"]; (* e.g., spline interpolation *)

f[x_] := 0.; (* first, define f for all x; this will be the 'extrapolation method' *)
f[x_?(xmin <= # <= xmax &)] := splineintpF[x]; (* then, define f for x
in the interpolated range [xmin, xmax] *)


Now, interpolation/extrapolation yields the expected result in the whole range of the variable, $(-\infty, +\infty)$. This works particularly faster than defining a Piecewise function -- as far as I could measure.