diff --git a/docs/make.jl b/docs/make.jl index 6438f482..a6b062b5 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -12,7 +12,8 @@ makedocs(modules = [DataInterpolations], linkcheck = true, format = Documenter.HTML(assets = ["assets/favicon.ico"], canonical = "https://docs.sciml.ai/DataInterpolations/stable/"), - pages = ["index.md", "Methods" => "methods.md", + pages = ["index.md", "Interpolation methods" => "methods.md", + "Extrapolation methods" => "extrapolation_methods.md", "Interface" => "interface.md", "Using with Symbolics/ModelingToolkit" => "symbolics.md", "Manual" => "manual.md", "Inverting Integrals" => "inverting_integrals.md"]) diff --git a/docs/src/extrapolation_methods.md b/docs/src/extrapolation_methods.md new file mode 100644 index 00000000..ad431027 --- /dev/null +++ b/docs/src/extrapolation_methods.md @@ -0,0 +1,56 @@ +# Extrapolation methods + +We will use the following interpolation to demonstrate the various extrapolation methods. + +```@example tutorial +using DataInterpolations, Plots + +u = [0.86, 0.65, 0.44, 0.76, 0.73] +t = [0.0022, 0.68, 1.41, 2.22, 2.46] +t_eval_down = range(-1, first(t), length = 25) +t_eval_up = range(last(t), 3.5, length = 25) +A = QuadraticSpline(u, t) +plot(A) +``` + +Extrapolation behavior can be set for `t` beyond the data in the negative and positive direction separately with the `extrapolation_down` and `extrapolation_up` keywords of the interpolation constructors respectively. + +## `ExtrapolationType.none` + +This extrapolation type will throw an error when the input `t` is beyond the data in the specified direction. + +## `ExtrapolationType.constant` + +This extrapolation type extends the interpolation with the boundary values of the data `u`. + +```@example tutorial +A = QuadraticSpline(u, t; extrapolation_down = ExtrapolationType.constant, + extrapolation_up = ExtrapolationType.constant) +plot(A) +plot!(t_eval_down, A.(t_eval_down); label = "extrapolation down") +plot!(t_eval_up, A.(t_eval_up); label = "extrapolation up") +``` + +## `ExtrapolationType.linear` + +This extrapolation type extends the interpolation with a linear continuation of the interpolation, making it $C^1$ smooth at the data boundaries. + +```@example tutorial +A = QuadraticSpline(u, t; extrapolation_down = ExtrapolationType.linear, + extrapolation_up = ExtrapolationType.linear) +plot(A) +plot!(t_eval_down, A.(t_eval_down); label = "extrapolation down") +plot!(t_eval_up, A.(t_eval_up); label = "extrapolation up") +``` + +## `ExtrapolationType.extension` + +This extrapolation type extends the interpolation with a continuation of the expression for the interpolation at the boundary intervals for maximum smoothness. + +```@example tutorial +A = QuadraticSpline(u, t; extrapolation_down = ExtrapolationType.extension, + extrapolation_up = ExtrapolationType.extension) +plot(A) +plot!(t_eval_down, A.(t_eval_down); label = "extrapolation down") +plot!(t_eval_up, A.(t_eval_up); label = "extrapolation up") +``` diff --git a/docs/src/interface.md b/docs/src/interface.md index cfc9ed0b..05dd0760 100644 --- a/docs/src/interface.md +++ b/docs/src/interface.md @@ -17,7 +17,7 @@ t = [0.0, 62.25, 109.66, 162.66, 205.8, 252.3] All interpolation methods return an object from which we can compute the value of the dependent variable at any time point. -We will use the `CubicSpline` method for demonstration, but the API is the same for all the methods. We can also pass the `extrapolate = true` keyword if we want to allow the interpolation to go beyond the range of the timepoints. The default value is `extrapolate = false`. +We will use the `CubicSpline` method for demonstration, but the API is the same for all the methods. We can also pass the `extrapolation_up = ExtrapolationType.extension` keyword if we want to allow the interpolation to go beyond the range of the timepoints in the positive `t` direction. The default value is `extrapolation_up = ExtrapolationType.none`. For more information on extrapolation see [Extrapolation methods](extrapolation_methods.md). ```@example interface A1 = CubicSpline(u, t) @@ -25,7 +25,7 @@ A1 = CubicSpline(u, t) # For interpolation do, A(t) A1(100.0) -A2 = CubicSpline(u, t; extrapolate = true) +A2 = CubicSpline(u, t; extrapolation_up = ExtrapolationType.extension) # Extrapolation A2(300.0) diff --git a/src/interpolation_methods.jl b/src/interpolation_methods.jl index 209e2541..d7d4dce0 100644 --- a/src/interpolation_methods.jl +++ b/src/interpolation_methods.jl @@ -13,7 +13,8 @@ function _extrapolate_down(A, t) if extrapolation_down == ExtrapolationType.none throw(DownExtrapolationError()) elseif extrapolation_down == ExtrapolationType.constant - first(A.u) + zero(eltype(A.p.slope)) * t + slope = derivative(A, first(A.t)) + first(A.u) + slope * zero(t) elseif extrapolation_down == ExtrapolationType.linear slope = derivative(A, first(A.t)) first(A.u) + slope * (t - first(A.t)) @@ -28,7 +29,8 @@ function _extrapolate_up(A, t) if extrapolation_up == ExtrapolationType.none throw(UpExtrapolationError()) elseif extrapolation_up == ExtrapolationType.constant - last(A.u) + zero(eltype(A.p.slope)) * t + slope = derivative(A, last(A.t)) + last(A.u) + slope * zero(t) elseif extrapolation_up == ExtrapolationType.linear slope = derivative(A, last(A.t)) last(A.u) + slope * (t - last(A.t))