まず, 2点のx座標(grid)とy座標(vals)に対して, その間を結ぶ直線に相当する関数を書いてください.
つまり, grid = [$a, b$], vals = [$f(a), f(b)$], $a \leq x \leq b$ に対し,
$$ g(x) = \frac{f(b) - f(a)}{b - a} (x - a) + f(a) \hspace{10pt} a \leq x \leq b$$を返すような, 関数 g(x) をプログラムとして書いてください.
In [2]:
function g(x)
grid = [2, 3]
vals = [4, 6]
# ここに処理を書く
interpolated_value =
return interpolated_value
end
In [3]:
print(g(2.5)) # 5が表示されてほしい
次に, 上の関数を3点以上の場合にも使えるよう拡張します. x座標(grid)とy座標(vals)がn個ずつ与えられたとして, それらを
$\hspace{25pt} $ grid = [$x_1, x_2, \ldots, x_n$], vals = [$f(x_1), f(x_2), \ldots, f(x_n)$] (ただし, $x_1 \leq x_2 \leq \ldots \leq x_n$ の順に並んでいるとする)
としましょう.
まず, 引数として与えられたある数xが,
$$ x_i \leq x \leq x_{i+1}$$を満たすような $i \in \{0, 1, 2, \ldots , n\}$ を見つける関数 find_x(grid, x) を考えます. ($x \leq x_1$ の時は $i=0$ になります)
そのためには, 配列から, ある数x以上であるような最初の要素のインデックス(配列番号)を返す関数, searchsortedlast() を使います. 使用例を見てみます.
In [8]:
grid = [0, 2, 4, 6, 8, 10]
println(grid)
# Return the index of the first value in a greater than or equal to x
println("xi <= 3.5 <= xi+1 を満たすiは: ", searchsortedlast(grid, 3.5))
println("xi <= -2 <= xi+1 を満たすiは: ", searchsortedlast(grid, -2))
println("xi <= 11 <= xi+1 を満たすiは: ", searchsortedlast(grid, 11))
これを用いれば, 関数find_xは
In [10]:
function find_x(grid, x)
return searchsortedlast(grid, x)
end
Out[10]:
と書けます.
あとは, 関数find_xと関数gを組み合わせて, n個のx座標およびy座標が与えられた時, それらを折れ線でつなげたグラフを表わす関数 h を考えるだけです.
つまり,
$$ \begin{eqnarray} h(x) = \begin{cases} \hspace{20pt} 0 & x \leq x_1 \\ \dfrac{f(x_{i+1}) - f(x_i)}{x_{i+1} - x_i} (x - x_i) + f(x_i) & x_i \leq x \leq x_{i+1}, i \in \{1, 2, \ldots, n\} \\ \hspace{20pt} 0 & x_n \leq x \\ \end{cases} \end{eqnarray} $$となるような関数を考えます. ($ x \leq x_1$ 及び $x_n \leq x$ のケースは, 0を返してもいいし, ERRORを返してもいいです)
In [11]:
function h(grid, vals, x)
i = searchsortedlast(grid, x)
if lower_index == 0 || lower_index == length(grid)
return 0
end
# ここに処理を書く
return interpolated_value
end
Out[11]:
In [12]:
grid = [0, 2, 4, 6, 8, 10]
vals = [1, 4, 5, 8, 9, 11]
println(h(grid, vals, 3)) # 4.5を返してほしい
最後に, 関数hを次のように, 「関数を返す関数」に書き換えます.
In [13]:
function my_lin_interp(grid, vals)
function func(x)
# ここに処理を書く
end
return func
end
In [ ]:
grid = [0, 2, 4, 6, 8, 10]
vals = [1, 4, 5, 8, 9, 11]
my_func = my_lin_i