Rubyの魔神 このページをアンテナに追加 RSSフィード

   「Ruby」は宝石の魔神のイメージ(The Jinn of the Ruby)
   [VB] [VB6] [Android] [電子工作] [個人メモ] [仕事メモ] [アイデア] [TstLink] [開発] [CE] [LTSA] [自動化] [Qt] [OCaml] [TOOLS]
   [3Dプリンタ] [RAA] [Forge]   [機能別索引] [逆引きRuby] [マニュアル] [るびま] [標準ライブラリ] [るりまサーチ] [Try! Ruby] [PRaggerまとめ] [ピジョン・ブラッド]
   [Rubyコーディング規約] [プログラミングのオキテ] [Rubyist SNS] [TOOLBIS]
   [RubyネットワークProg] [druby] [コードなにがし] [RDocテンプレ] [Ruby/Tkサンプル]
   [WAVE] [Xperia] [github] [twitterなど] [Java] [EA] [マクロ]

2013-09-22

ラムダ式で任意に与えられた関数を微分と積分してみる

ラムダ式で任意に与えられた関数を微分と積分してみる - Rubyの魔神 を含むブックマーク はてなブックマーク - ラムダ式で任意に与えられた関数を微分と積分してみる - Rubyの魔神 ラムダ式で任意に与えられた関数を微分と積分してみる - Rubyの魔神 のブックマークコメント

微分

include Math
#幅dxで微分する関数
differential = ->dx,f,x{(f[x + dx] - f[x])/dx}

#与える関数
mysin = -> x {sin(x)}
myexp = -> x {exp(x)}

#カリー化しておく
diff_curried = differential.curry

#幅を0.1e-6にする
diff_dx = diff_curried[0.1e-6] #dxを 0.1e-6にしてみる。

#微分した関数を作る
mycos = diff_dx[mysin]
myexp2 = diff_dx[myexp]

#引数を与えてみる
puts mycos[PI/3]  #=>0.49999995699323563
puts myexp2[1]           #=>2.7182819684057336

積分

include Math
integ = ->f,x,dx{(f[x+dx] + f[x])*dx/2}

#f(x)をaからbまでn等分してから積分する関数
integration = -> f,a,b,n{n.times.to_a.inject(0){|s,x|s + integ[f,(b-a)/n*x,(b-a)/n]}}

mycos = -> x {cos(x)}
myf = -> x {x*x*x -3*x*x + 3*x -1}
myexp = -> x{exp(x)}

puts integration[mysin,0,PI,1000]    #=>1.999998355065662
puts integration[myf,-1.0,1.0,1000]        #=>1.205632815803881e-16
puts integration[myexp,1.0,2.0,1000]       #=>1.718281971649196

Math.sinを直接proc型に変換する方法は無いのかな?

追記

id:iwadonさんに以下の方法を教えてもらいました。

http://q.hatena.ne.jp/1379862097

a = Math.method(:sin)

mapの引数に無名関数

mapの引数に無名関数 - Rubyの魔神 を含むブックマーク はてなブックマーク - mapの引数に無名関数 - Rubyの魔神 mapの引数に無名関数 - Rubyの魔神 のブックマークコメント

[1..1].map(&:to_s)

ができるので

(1..10).map(&->x{x * 2})

も試したら動いた

(1..10).map{|x| x * 2}

とより便利かというと何ともいえない。

->も[ ]もなんかいや。面白いけど

->も[ ]もなんかいや。面白いけど - Rubyの魔神 を含むブックマーク はてなブックマーク - ->も[ ]もなんかいや。面白いけど - Rubyの魔神 ->も[ ]もなんかいや。面白いけど - Rubyの魔神 のブックマークコメント

[[->x{x*2},4],[->x{x*4},5]].map{|x|x[0][x[1]]}
 x[0][x[1]]

 上記は x[0]に入っている関数にx[1]を引数として渡しているけど

わかりにくい。自分で書いてて噴出しそうになった。

パーサ作ってる方は大変だろうな。

a=(1..10).map &(->x,y{x * 4+y}).curry
a[2][3] #=>15

多重配列にしか見えない


Dir.globとDir[]

Dir.globとDir[] - Rubyの魔神 を含むブックマーク はてなブックマーク - Dir.globとDir[] - Rubyの魔神 Dir.globとDir[] - Rubyの魔神 のブックマークコメント

青木 (笑)。あれは俺も嫌い。あと、Dir.glob の代わりにも使えるでしょ。あれも嫌だ。

ささだ え、Dir[]っていうの? あー、なるほど。ほんとだほんとだ。

Rubyist Magazine - Rubyist Hotlinks 【第 17 回】 青木峰郎さん

Dir.glob良く使うけど、Dir[]というのは知らなかった。

確かに

Dir[**/*.*]

と書くと、ファイル一覧を配列で返してくれる。すごく便利そうだけど。

Proc型の呼び出し

Proc型の呼び出し - Rubyの魔神 を含むブックマーク はてなブックマーク - Proc型の呼び出し - Rubyの魔神 Proc型の呼び出し - Rubyの魔神 のブックマークコメント

色々あるのでメモ

f=Proc.new{|x|x+1}
f=proc{|x|x+1}
f=lambda{|x|x+1}
f=->x{x+1}

で定義して

f.(2)
f.call(2)
f[2]
f.yield(2)
特別な呼び出しで
f === 2
これはcase文用で引数は1つ。戻り値はtrue,falseを返すといいそうです。

で実行


メソッドの最後の引数に&をつけるとブロックとして渡されるので

f=->x{x*2}
[1,2,3].map(&f)

括弧は無くてもいい

[1,2,3].map &f

シンボルにはto_proc関数があるので

:+も関数だから以下で呼べる

(:+).to_proc[1,2]


curry関数

curry関数 - Rubyの魔神 を含むブックマーク はてなブックマーク - curry関数 - Rubyの魔神 curry関数 - Rubyの魔神 のブックマークコメント

procにはcurryという関数もあるみたい。

プロックの中身をカリー化してしまうとのこと。

f = ->x,y{x*2 + 1}

という多変数の関数を作って

g = f.curry

とやると、gはカリー化された関数になる。

h = g[2]

でhはx=2でyを引数に持つ関数になるので

h[3]#=>7
トラックバック - http://ruby.g.hatena.ne.jp/garyo/20130922