前年度に Fresnel 積分
繰り返しになるが、Mathematica, Python, Julia などでは正規化 Fresnel 積分
Mathematica で確認 |
In[] := mys[x_]:=Sqrt[Pi/2]FresnelS[Sqrt[2/Pi]x] In[] := myc[x_]:=Sqrt[Pi/2]FresnelC[Sqrt[2/Pi]x] In[] := {FresnelC[1.0],FresnelS[1.0]} Out[] = {0.779893, 0.438259} In[] := {myc[1.0],mys[1.0]} Out[] = {0.904524, 0.310268} |
C には、Cで書かれたプログラム (これも正規化 Fresnel 積分を計算する) が公開されている (NETLIB で入手できる cephes に含まれている)。
まあ、それでとりあえずの用は足りるけれど、 古めかしいプログラムのお世話になるのではなく、 最近の整備されたのを利用できると良いかも、と考えて少し調べてみた。
C++だと、Boost クラス・ライブラリィに特殊関数が含まれているはずだ、 ということで Boost を調べたのだけれど、Fresnel積分は入ってなかった。
Abramowitz-Stegun [#!Abramowitz-Stegun!#] によると、
Fresnel積分は誤差関数
の親戚扱いをされている。
実際、
を使って Fresnel 積分を表すことができる。
件の学生は、この公式を使って Fresnel 積分を計算するコードを作成した。 おお、なるほど。馬力がありますね、
学生は Python でやったのだけれど、効率とか調べたいので、C++でやってみるか、 と思い立った。誤差関数ならば Boost にも入っているはずだ …ところが残念なことに Boost の誤差関数は実数引数にしか対応していない。
複素引数の特殊関数が欲しい、という人は検索するとすぐ出て来るのだけれど (当たり前だよね)、 そういう要求って出てなかったなあ、 とか言う反応が Boost やっている人達にあったり。 やはり複素数計算はなんとなく袖にされがちなのか。 こういうのは昔から相似形をたくさん見ている。
そう考えると、Python の誤差関数が複素引数に対応しているって、 すごいなあ、と感心した。
さて、どうしよう?
ふと、ChatGPT 様にお伺いを立ててみよう、と浮かんだ。 色々なアイディアを出してくれたが、自分が思いつかなかったものが一つ。
曰く、Faddeeva function を使え。
Wikipedia の Faddeeva function を見る (ちなみに日本語バージョンは存在しない)。
![]() |
(1) |
ACM Transactions on Mathematical Softwareに に2つのアルゴリズムと実装が発表されているそうである。
MITライセンスで利用できる実装 libcerf がある。
さらに同じ MIT で The Faddeeva Package というのもある。こちらでやってみるか。
curl -O http://ab-initio.mit.edu/Faddeeva.cc curl -O http://ab-initio.mit.edu/Faddeeva.hh c++ -O -c Faddeeva.ccCバージョンもあるみたい (中で include していたりする)。 curl -O http://ab-initio.mit.edu/Faddeeva.c curl -O http://ab-initio.mit.edu/Faddeeva.h cc -O -c Faddeeva.c |
Faddeeva パッケージの中に
を計算する関数が含まれているので、
私の目的にはそれを呼び出せば良い。
testfaddeeva.cpp |
/Users/mk/.tex-inputs/knowhow-2024-fig/testfaddeeva.cpp |
(20253/7追記) 関数ごとにこういう探索を繰り返すのは、暇つぶしには良いけれど、 何か間違えているような気がする。 「面白そうだけどそのうちに」と考えていて放置してあるものをチェックするのかな。