tsujimotterのノートブック

日曜数学者 tsujimotter の「趣味で数学」実践ノート

Rubyで小難しい数式の計算を一行で書く

Railsを使えない素人 Rubyist の tsujimotter です。
今回のお話は、Ruby の inject メソッドについて。




たとえばこんな数式の計算をしたいとします。

 \displaystyle y = \gamma + \sum_{i=1}^{100} \cos(a_i x)

級数展開とかでよくありそうな形ですよね。

というか実際ついさっきあったのですが。


で、Rubyとかでバカ正直に書くと、こんな感じになるわけです。

sum = 0 
for i in 1..100 do
    sum += Math::cos(a[i] * x)
end
y = gamma + sum

まぁ普通こうですよね。
これでいいと思うんですよ。


でもね。これ、なんか気持ち悪くないですか?


だって、数式だったら一行で書けるところを、5行もかかってるんですよ!


私は、とても、気持ち悪いです。


どうにかして一行で書きたいと思いませんか。
(こんなことを思うのは私だけかもしれませんが。笑)


ブロックとか使えば、うまいこと書けそうですよね。

とネットの海を探していたら、ありましたよ!

inject メソッド。

参考:
ちょっとわかりにくいけど非常に便利なinjectメソッド - 勉強日記


injectメソッドについては、上のサイトで丁寧に書いてあるのでよいと思うのですが、
さっきの問題の解決策をコードにすると次のようになります。



y = gamma + (1..100).to_a.inject(0) do |sum, i| sum + Math::cos(a[i]*x) end


ほら、一行で書けた!

こうしてみると、なんとなく元の数式の形に見えてきませんか?

y = gamma

定数部分と、

          + (1..100).to_a.inject(0) do |sum, i| sum + Math::cos(a[i]*x) end

和の部分。


位置関係もピッタリ!!


しいて言えば、injectの中の 0 が気になるぐらい。


まぁそんなことは気にしない。


そこまで気にする数式大好きさんは、


Haskellをやればいいんですよ!

(Haskellよくしらないですが・・・)



というわけで、数式大好きなプログラマーしか、あまり需要がなさそうな豆知識の紹介でした。

簡単ですが、この辺で。