Skip to content

Commit ca74353

Browse files
Extrapolation (#53)
* use latest nimib and nimibook * fix links to Clonkk's github * add section on extrapolation * Update book/numerical_methods/interpolation.nim Co-authored-by: Vindaar <[email protected]> * Update book/numerical_methods/interpolation.nim Co-authored-by: Vindaar <[email protected]> --------- Co-authored-by: Vindaar <[email protected]>
1 parent 86b6e6b commit ca74353

File tree

3 files changed

+53
-4
lines changed

3 files changed

+53
-4
lines changed

book/external_language_integration/julia/basics.nim

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ nbInit(theme = useNimibook)
55
nbText: """
66
# Using Julia with Nim
77
8-
In this tutorial, we explore how to use [Nimjl](https://github.com/Clokk/nimjl) to integrate [Julia](https://julialang.org/) code with Nim.
8+
In this tutorial, we explore how to use [Nimjl](https://github.com/Clonkk/nimjl) to integrate [Julia](https://julialang.org/) code with Nim.
99
1010
## What is Julia ?
1111
@@ -20,7 +20,7 @@ Most notably, it has a strong emphasis on scientific computing and Julia's Array
2020
2121
# Tutorial
2222
23-
[Nimjl](https://github.com/Clokk/nimjl) already has some [examples](https://github.com/Clonkk/nimjl/examples/) that explains the basics, make sure to go through them in order.
23+
[Nimjl](https://github.com/Clonkk/nimjl) already has some [examples](https://github.com/Clonkk/nimjl/examples/) that explains the basics, make sure to go through them in order.
2424
2525
## Basic stuff
2626

book/numerical_methods/interpolation.nim

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,55 @@ We can now evaluate it on a denser set of points and compare it to the original
9292
As we can see, the interpolant does a decent job of approximating the function.
9393
It is worse where the function is changing a lot and closer to the original
9494
in the middle where there is less happening.
95+
96+
### Extrapolation
97+
For 1D interpolators, extrapolation is supported. The available methods are:
98+
- `Constant`: Set all points outside the range of the interpolator to a specified value.
99+
- `Edge`: Use the value of the left/right edge.
100+
- `Linear`: Uses linear extrapolation using the two points closest to the edge.
101+
- `Native` (default): Uses the native method of the interpolator to extrapolate. For Linear1D it will be a linear extrapolation, and for Cubic and Hermite splines it will be cubic extrapolation.
102+
- `Error`: Raises an `ValueError` if `x` is outside the range.
103+
104+
The extrapolation method is optionally supplied as an argument to `eval` and `derivEval`:
105+
"""
106+
107+
nbCode:
108+
echo "Edge: ", interp.eval(-1.0, Edge) # will use the value at x=0
109+
echo "Constant: ", interp.eval(-1.0, Constant, NaN) # will return NaN
110+
echo "Linear: ", interp.eval(-1.0, ExtrapolateKind.Linear)
111+
echo "Native: ", interp.eval(-1.0) # will use Native by default
112+
113+
nbText: hlMd"""
114+
As you can see, the choice of extrapolation method affects the values considerably.
115+
Keep in mind though that `-1.0` is quite a big extrapolation and the further away we go, the worse the approximation gets.
116+
117+
Here is a visual example of how the different methods behave. I have removed the two outermost points on each side from the example before (ignore the point at `(0, 0)`, it's a bug):
118+
"""
119+
block:
120+
let t = linspace(0.0, 4.2, 100)
121+
let yOriginal = t.map(f)
122+
let x = x[2..^3]
123+
let y = y[2..^3]
124+
let interp = newHermiteSpline(x, y)
125+
let yLinear = interp.eval(t, ExtrapolateKind.Linear)
126+
let yConstant = interp.eval(t, ExtrapolateKind.Constant, 0.0)
127+
let yEdge = interp.eval(t, ExtrapolateKind.Edge)
128+
let yNative = interp.eval(t, ExtrapolateKind.Native)
129+
var df = toDf({"x": x, "y": y, "t": t, "f(t)": yOriginal, "Linear": yLinear, "Constant": yConstant, "Edge": yEdge, "Native": yNative})
130+
df = df.gather(@["f(t)", "Linear", "Constant", "Edge", "Native"], key = "Class", value = "Value")
131+
ggplot(df, aes("t", "Value", color="Class")) +
132+
geom_line() +
133+
geom_point(aes("x", "y")) +
134+
ylim(-3.5, 3.5, "drop") +
135+
ggsave("images/compare_interp_extrapolate.png")
136+
137+
nbImage("images/compare_interp_extrapolate.png", caption="Showcase of the extrapolation methods.")
138+
139+
nbText: hlMd"""
140+
As we can see, the `Edge` and `Constant` are just horizontal lines while `Linear` has the same slope as the edge of the interpolant.
141+
`Native` on the other hand is smooth but quite quickly starts to take off towards $\pm \infty$ (for the linear interpolator it would behave the same as `Linear` though).
142+
Which method you should use is very dependent on the application and what behavior you want it to exhibit.
143+
Of course, you should try to avoid extrapolation whenever possible.
95144
"""
96145

97146
block Part2:

scinim_getting_started.nimble

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ binDir = "bin"
99

1010
# Dependencies
1111
requires "nim >= 1.2.0"
12-
requires "nimib#head"
13-
requires "nimibook#280a626a902745b378cc2186374f14c904c9a606"
12+
requires "nimib"
13+
requires "nimibook"
1414
requires "ggplotnim == 0.5.6"
1515
requires "datamancer >= 0.2.1"
1616
requires "mpfit"

0 commit comments

Comments
 (0)