HW1 - step by step

g(x)の式が間違っていました. すみません.

step1

まず, 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


LoadError: syntax: misplaced return statement
while loading In[2], in expression starting on line 9

In [3]:
print(g(2.5))  #  5が表示されてほしい


LoadError: UndefVarError: g not defined
while loading In[3], in expression starting on line 1

step2

次に, 上の関数を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))


[0,2,4,6,8,10]
xi <= 3.5 <= xi+1 を満たすiは: 2
xi <= -2 <= xi+1 を満たすiは: 0
xi <= 11 <= xi+1 を満たすiは: 6

これを用いれば, 関数find_xは


In [10]:
function find_x(grid, x)
    return searchsortedlast(grid, x)
end


Out[10]:
find_x (generic function with 1 method)

と書けます.

あとは, 関数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]:
h (generic function with 1 method)

In [12]:
grid = [0, 2, 4, 6, 8, 10]
vals = [1, 4, 5, 8, 9, 11]
println(h(grid, vals, 3)) # 4.5を返してほしい


LoadError: UndefVarError: lower_index not defined
while loading In[12], in expression starting on line 3

 in h at In[11]:4

step3

最後に, 関数hを次のように, 「関数を返す関数」に書き換えます.


In [13]:
function my_lin_interp(grid, vals)
    function func(x)
        
        # ここに処理を書く
    
    end

    return func
end


LoadError: syntax: invalid identifier name "..."
while loading In[13], in expression starting on line 3

In [ ]:
grid = [0, 2, 4, 6, 8, 10]
vals = [1, 4, 5, 8, 9, 11]
my_func = my_lin_i