参考1:Apfloat arbitrary precision library

参考2:Arbitrary precision exponentiation in Clojure

参考3:プロジェクトを作らずにClojureライブラリをREPLで試す

参考4:clojure-emacs/inf-clojure

参考5:Clojure の開発環境をよりシンプルへ ~ inf-clojure 導入編


参考サイトが多くなってしまった。

Apfloatという任意精度数値計算ライブラリがある(C++とJava版がある)。これをClojureから使ってみたい。参考1参考2

それと共にClojureについて雑多に調べたことをまとめておきたい。というより、むしろこちらが主題かも知れない。

旧ブログでMPFRという任意精度数値計算ライブラリを使ってみたがそれはCで書いた。(MPFR を使ってみる - Tips)

ちょっとした計算をするのに一々Cで書くのも面倒なのでREPLでできれば便利だと思う。

ところがこういう用途だとプロジェクトも必要ないしEmacsのCiderでは巨大すぎる気がしたので、もっと手頃な環境がないかと探したところ参考4参考5を発見した。

ちょっと使ってみたところ自分には十分だと思われたので、しばらくはinf-clojureを使ってみることにした。

lein-tryを使うには~/.lein/profiles.clj

{:user {:plugins [[lein-try "0.4.3"]]}}

と書いておく。

とりあえずJava版のApfloatが無いことには始まらない。

参考2にあるようにLeiningenのプロジェクトに依存関係として書けば勝手にインストールしてくれるはずですが、ここではlein-try(参考3)とinf-clojureの組合せを試してみたい。

Emacsの設定ファイル.emacs.d/init.elclojure-mode-hook

(add-hook 'clojure-mode-hook #'inf-clojure-minor-mode)

という設定は加えておく。

とりあえず空のファイルtest.cljを開く。これは何のプロジェクトにも結び付けられていないファイルである。

ここでM-:を使ってミニバッファで

(setf inf-clojure-generic-cmd "lein try org.apfloat/apfloat")

を評価する。そしてC-c C-zでREPLを立ち上げるとApfloatをダウンロードしてくれる。

test.clj

(import '[org.apfloat Apfloat ApfloatMath])

(let [prec 100] ; pi = atan(1) * 4
  (. (ApfloatMath/atan (new Apfloat 1.0 prec)) multiply (new Apfloat 4.0 prec)))

と打ってそれぞれ評価(C-c C-e or C-M-x)すればREPLにpiが100桁表示される:

user=> 
3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117066

上でnew Apfloatのかわりにドット記法でApfloat.としても良い。なお定数piは上のように計算しなくてもApfloatが組み込みで持っているので

(ApfloatMath/pi 100) 

あるいは

(. ApfloatMath pi 100)

とすれば100桁表示される。詳しくはApfloatのドキュメントを参照。(JavaかC++のものしかないが)

まとめ

lein tryは重宝するものだとわかった。

上でinf-clojure-generic-cmdという変数を設定したが、これはプロジェクトを作らない場合に使う変数である。Leiningenのプロジェクトで使うならinf-clojure-lein-cmdという変数に設定する。bootというのを自分は使ったことがないがinf-clojure-boot-cmdという変数もあるのでboot使いの方はこちらの変数を設定することになるでしょう。(ただしlein tryに相当するものがあるのかどうかはわからない)

ApfloatをClojureから呼ぶだけでもREPLのおかげで随分と便利になる。

余談

init.elclojure-modeの設定を書くのはlisp-modeの設定の後ろでないといけない。そうしないとclojure-modeの設定がlisp-modeの設定で上書きされてしまう。自分はちょっとハマってしまった。

ClojureからMaximaを呼べれば使う機会が増えそうだけど調査中である。