トップ «前の日記(18-November-2021) 最新 次の日記(20-November-2021)» 編集

つれづれなるままに

これまでの訪問者人
本日の訪問者人  昨日の訪問者人
月齢20.7

AI | AIきりたん | Ast | Beat Saber | CeVIO | Cn | cover | de | Emacs | En | Es | fr | git | html | iPad | It | Just Dance | misc | MMD | MV | NEUTRINO | OVA | PC | PV | Ru | SF | SKK | stable diffusion | SynthesizerV | tDiary | Th | Vocaloid | VRC | VRChat MMD | Vsinger | Vtuber | was | YuNi | お茶 | アニメ | アメリカ | イラスト | オカリナ | カゲプロ | キズナアイ | テレビ | ノベル | ノーベル賞 | ビートセイバー | フィートセイバー | フランス | ラズパイ | ラノベ | 万葉語 | 世界 | 中国 | 予定 | 即売会 | 台湾 | 台風 | 合成してみた | 同人 | 地震 | 宇宙 | 家電 | 展示 | 描いてみた | 政治 | 旅行 | 日記 | 映画 | 時事 | 書道 | 歌ってみた | 歴史 | 海外 | 演奏してみた | 漫画 | 特撮 | 科学 | 英国 | 訃報 | 語学 | 踊ってみた | 陶笛 | 障害 | 音楽 | 飲み |

19-November-2021 ふむ [長年日記]

_ [Vtuber][cover] アカシア (Acacia) - BUMP OF CHICKEN // covered by 松永依織

RIOT MUSIC の松永依織のカヴァー。

ポケモンの曲なんですか。

彼女も最近は歌は歌ってるのだけど、配信が多いものだから聞くことができないでいた人です。

この人の歌は結構好きなのですがねぇ。

_ [科学][PC] fortran 版 モンテカルロ円周率計算 と GNU Scientific Library

昨日のやつをFortranにしてみましたが、メルセンヌツイスターのライブラリの定番ってないんですよね。

昨日失敗していたのは Multiple stream Mersenne Twister PRNG にあったソースを元にしたもの。

ライブラリのコンパイルで少々てこずりましたが、gfortranだけでやりたかったのでMakefile で USE_NTL = no とし、FCFLAG のところに -If_jump_ahead_coeff -fallow-invalid-boz を加え、-traceback をはずしました。FC は gfortran にします。下のディレクトリのMakefile にも -I.. を入れる必要があったり。

できあがった *.o と *.mod をプログラムと同じディレクトリに入れてからコンパイルします。ソースはこちら。

program pi
 use mt_kind_defs
 use mt_stream
 implicit none
 real(kind(0d0))::r,x,y,c,ttl,p
 integer(int64)::count=0,i
 integer(int64)::total=10000000000
 integer(int32)::iseed
 type(mt_state)::mts

 call set_mt19937
 call new(mts)
 call init(mts,iseed)
 do i=1,total
   x=genrand_double1(mts)-0.5d0
   y=genrand_double1(mts)-0.5d0
   r=sqrt(x*x+y*y)
   if(r.le.0.5d0) then
     count=count+1
   end if
 end do
 c=real(count,kind(0d0))
 ttl=real(total,kind(0d0))
 p=c/ttl*4.d0
 print *,p
end program

gfortranのバグなのか、整数の範囲にひっかかってしまうので、このソースをコンパイルするときは -fno-range-check を入れる必要があります。

$ gfortran -o run -I. -fno-range-check pi.f90
$ time ./run.exe
  3.1415799220000000

real    5m2.022s
user    0m0.000s
sys     0m0.000s

あまり精度が良くないのはやっぱり変数の取り方が悪いせいか。

Cのライブラリになってしまいますが、GNU Scientific Library のFortranラッパーである fgsl を使ってみることにしました。

MSYS2 に入ってるので pacman でインストールしておきます。

GitHubの例や、日本語翻訳版マニュアルを参考にコードを組みます。

program pi
 use fgsl
 implicit none
 real(kind(0d0))::ra,x,y,c,ttl,p
 integer(selected_int_kind(16))::count=0,i
 integer(selected_int_kind(16))::total=10000000000
 type(fgsl_rng) :: r
 type(fgsl_rng_type) :: t

 t=fgsl_rng_env_setup()
 t=fgsl_rng_default
 r=fgsl_rng_alloc(t)

 do i=1,total
   x=fgsl_rng_uniform(r)-0.5d0
   y=fgsl_rng_uniform(r)-0.5d0
   ra=sqrt(x*x+y*y)
   if(ra.le.0.5d0) then
     count=count+1
   end if
 end do
 c=real(count,kind(0d0))
 ttl=real(total,kind(0d0))
 p=c/ttl*4.d0
 print *,p
end program

コンパイルにはちょっとコツがあります。

$ gfortran -o run $(pkg-config --cflags fgsl)  -I/mingw64/include/fgsl -fno-range-check pi.f90 $(pkg-config --libs fgsl)
$ ls
pi.f90  pi.f90~  pi.o  run.exe*
$ time ./run.exe
  3.1415942239999999

real    2m8.332s
user    0m0.000s
sys     0m0.000s

これは変数の型の宣言が良かったのか、単精度ぐらいの精度が出てそうですね。

それでもこんなもん、と。


【PR】ブログへ記事を投稿して報酬ゲット!アフィリエイトのA8.net