関数で関数を微積しよう

平均変化率
定積分と短冊
1.微分積分のもとは細分
[b][size=150][b]このワークシートは[url=https://www.geogebra.org/m/twxxx3yq]Math by Code[/url]の一部です。[br][/b][br][br]<微分と積分の意味づけの確認>[br]微分[/size][/b]は曲線y=f(x)を細分することで、曲線を線分のあつまりとみなす。[br]すると、x=aでの[b][size=100][size=150]線分の傾き(平均変化率)[/size][/size][/b]がΔf/Δx=m(a)={f(a+Δx)-f(a)}/Δxとなった。[br]その[color=#0000ff][b]細分を微小化して瞬間的な傾きにして、それをxの各点で出せる関数y=m(x)にする[/b][/color]ことだった。[br]それを数式操作とすると、細分Δをさらに微小にしたdであらわすことで、[br]微分は曲線の関数式y=f(x)から、瞬間傾きを表す数式y=df(x)/dxを出すことになったね。[br][br]積分は数式操作では、微分の逆操作だったけど、[br][b][size=150]定積分[/size][/b]は曲線y=f(x)とx軸y=0と積分区間x=a,z=bの2直線で囲む[size=150][b]領域の面積[/b][/size]を出すことだった。[br]そのために、領域をキュウリのように同じ厚さに薄切りにする。[br]横からみると、中央での高さと厚みをかけた、短冊の面積をはじからはじまで合計しても出せたね。[br]その[color=#0000ff][b]細分を微小化して極限としての面積にする[/b][/color]ことだった。[br][br][b][size=150]<微分をコードにする>[br][/size][/b]haskellで微分してみよう。[br]t秒後の車の位置がcarPos(t)=cos tで表せるとき、[br]t秒後の車の位置の平均変化率つまり、速さを微分で求める関数を作り、[br]1秒後の速さを求めてみる。もちろん[br]数式微分ではd(cos x)/dx=-sin x だから、-sin(1)になるはずだ。[br][br]導関数derivativeはdt x tの3変数関数にみえるけど[br]dt=0.01, x=carPosとして、[color=#0000ff][b]カリー化[/b][/color]したから、[br]carV=derivative 0.01 carPosは、[br][color=#0000ff][b]時間を入れると速度がでる1変数関数[/b][/color]になりました。[br][br][color=#0000ff][b][IN]Haskell[br]---====================================================[br]type R= Double [br]type Derivative = (R -> R) -> R -> R[br]derivative :: R -> Derivative[br]derivative dt x t = (x (t + dt/2) - x (t - dt/2)) / dt[br][br]carPos :: R -> R[br]carPos = cos [br]carV :: R -> R[br]carV = derivative 0.01 carPos[br][br]carV1 = carV 1[br]carVf = -sin 1[br]--====================================================[br][/b][/color][OUT][br]ghci> carV1[br]-0.8414674786831666[br]ghci> carVf[br]-0.8414709848078965[br][b][br][/b]
2.微分を作ろう。
[b][u][size=150][color=#9900ff]質問:juliaやgeogebraで数値微分をどうやって作りますか。[br][/color][/size][/u][/b][br][b][size=150]<juliaで数値微分>[br][/size][/b]t秒後の車の位置がcarPos(t)=cos tで表せるとき、微分してcarV関数を作る。[br]そして、1秒後の速さを求めよう。[br]juliaでは関数は第1級オブジェクトだから、値として渡したり、返したりができる。[br]なので、Haskellと同様なコードがかけるね。Haskellよりも型の書き方が簡単でいいね。[br][color=#0000ff][b]#[IN]julia[br]#======================================[br]function derivative(f::Function)::Function [br] h=0.001[br] df(x)= (f(x +h) - f(x)) / h[br] return df[br]end[br]f(x)=cos(x)[br]carV = derivative(f)[br]x=1.0[br]println(carV(x), ":",-sin(x))[br]#======================================[br][/b][/color][OUT][br]-0.8414674786831666:-0.8414709848078965[br][br]また、xを点ではなく点集合としてリストにし、それを導関数でブロードキャストしてy座標を出す。[br]これをzipで組にすれば関数グラフのもとになるタプル(x,y)が作れるね。[br]さらにplots.jlなどの視覚化パッケージをインストールすれば、グラフを書いたりできる。[br][b][IN]julia[br]#======================================[br][/b]xs= -1.0:0.1:1.0[br]ys= carV.(x)[br]dot=[(x,y) for (x,y) in zip(xs,ys)][br]println(dot)[br][b]#======================================[br][/b][OUT][br][br][(-1.0, 0.841200693432298), (-0.9, 0.7830159741147869), (-0.8, 0.7170076180145202), (-0.7, 0.643835158806283), (-0.6, 0.5642297115148187), (-0.5, 0.47898666745549434), (-0.4, 0.3889577469469163), (-0.3, 0.2950424892033121), (-0.2, 0.19817926443543854), (-0.1, 0.0993358979667347), (0.0, -0.0004999999583255033), (0.1, -0.10033090204919493), (0.2, -0.19915933093161975), (0.3, -0.29599782561273713), (0.4, -0.3898788078642301), (0.5, -0.479864249944395), (0.6, -0.5650550470610582), (0.7, -0.644600000929918), (0.8, -0.7177043246657799), (0.9, -0.783637584031216), (1.0, -0.8417409956931188)][br][br]さて、geogebraにはderivative(関数)という関数があるので、苦も無く導関数は作れるだろう。[br]
位置と速度
2.定積分を作ろう。
定積分は短冊の面積を足し込めば得られる。[br]t=aからt=bの積分区間を細分した1つの幅をΔt=0.5とすると、[br]t=a+Δt/2, a+Δt+Δt/2,.....,b-Δt/2が短冊の幅の中点の時刻になるね。[br]そのときの高さf(t)と幅Δtの積和が領域の面積になるから、[br]integral(f, a, b)=sum( [ f(t)Δt | t = [ a+Δt/2, a+3Δt/2,.....,b-Δt/2 ] ] )[br]この細分Δtを微小部分dtにしていけば積分になる。[br]インテグラルを定義してから、0から1までのy=x[sup]2[/sup]を定積分すると、[br]integral(x[sup]2[/sup],0,1)=[1/3 x[sup]3[/sup]] from 0 to 1= 1/3となるはず。[br][br]haskellでやってみよう。[br][color=#0000ff][IN]Haskell[br]#=======================================[br][/color]type Integration = (R->R) [br] ->R --Lower limit[br] ->R --Upper limit[br] ->R --result[br]integral :: R -> Integration[br][color=#0000ff]integral dt f a b[br] = sum [f t * dt | t <- [a+dt/2, a+3*dt/2 .. b - dt/2]][br][/color][b][color=#0000ff]#=======================================[br][comand prompt][br][/color][/b]ghci> integral 0.01(\x->x**2) 0 1[br]0.33332499999999987[br][color=#9900ff][b][u][size=150][br]質問:juliaやgeogebraでは定積分はどうやりますか。[/size][/u][/b][/color][br][br]integraは、関数を与えると数値定積分したあとの関数を返す[br]だからinetgralの引数の関数を変えると、それに合わせて[br]定積分します。[br]数学的な定義をかくだけでプログラミングができてしまう。[br]これって、とても楽だし気分がいいです。[br][br]#[IN]julia[br][color=#0000ff]#================================================[br]#数値積分で定積分を作る[br]function integral(f::Function,a,b) [br] dt=0.01[br] return sum([f(t) * dt for t in a+dt/2 : dt : b-dt/2])[br]end [br]g(x)=x^2[br]integral(g,0,1)[br]#================================================[br][/color][OUT][br]0.33332500000000004[br][br]さて、geogebraではintegral(fx,a,b1)を作らなくても、[br]integral(関数,開始,終了)だけで定積分ができるね。
integral関数で定積分

Мэдээлэл: 関数で関数を微積しよう