fortran66のブログ

fortran について書きます。

Winodows10 anniversary edition Bash on windows で GFortran 楽々

Winodows10 anniversary edition がダウンロード可能になっていますが、目玉機能の一つとして Ubuntu と互換性のある bash shell が利用できるようになりました。

インストール後、
1.更新とセキュリティ左メニューから、開発者用オプション->開発者モードを選択し。
2.コントロールパネル、プログラム->Windowsの機能の有効化または無効化->Windows Subsystem for Linux (Beta)をチェック
3.CMDプロンプトから bash->y
4.bash コンソールで gfortran と打つと、インストール手引きが出るのでそのまま打つ

という手順でかなり楽に使えるようになりました。

Intel Fortran Linux 版も行けるのか?最近インストーラGUI 化しているので、手作業でスクリプト起動で行くのかな?

分割数 p(n) の直接計算 Haskell 版

ずいぶん前に Hutton の Haskell 本を読んで、階乗くらいしかプログラムを書かずに放置していましたが、夏にもう一度勉強しようかなと思ってみました。

とりあえず Fortran で書いた 分割数 p(n) の直接計算を移植してみることにしました。文法をよく知らないのでものすごく時間がかかりました。結果が微妙におかしい感じがしますが、デバッグ・プリントが難しくてあきらめました。

fortran66.hatenablog.com

実行結果

インストールするのもかったるいのでオンライン・コンパイラにて。
Free Online IDE and Terminal

1から10までの分割数、1,2,3,5,7,11,15,22,30,42 を計算しています。

sh-4.3$ ghc -O2 --make *.hs -o main -threaded -rtsopts                                                                                                                                           
[1 of 1] Compiling Main             ( main.hs, main.o )                                                                                                                                          
Linking main ...                                                                                                                                                                                 
sh-4.3$ main                                                                                                                                                                                     
[0.9810639,2.0009859,3.0242445,5.014357,6.9633565,11.030045,14.987319,21.990871,30.022284,41.988766]                                                                                             
sh-4.3$ ^C  

ソース・プログラム

複素数の使い方が分からなくて泣きました。型変換がよく分からなくて・・・

import Data.Complex

dsn :: RealFloat a => Int -> a -> a 
dsn k z = ( f * cosh(f * x) - sinh(f * x) / x ) / (2 * x * x)
          where f = pi / fromIntegral k * sqrt(2.0 / 3.0)
                x = sqrt(z - 1.0 / 24.0)

f :: RealFloat a => Int -> Int -> Int -> a -> Complex a
f n k h x = (sqrt (fromIntegral k) / (pi * sqrt 2.0) :+ 0.0) * exp (0:+ x) * (dsn k (fromIntegral n):+ 0.0) 

w :: Int -> Int -> Int -> Float
w n k h = pi * (w1 n k h + w2 k h)

w1 :: Int -> Int -> Int -> Float
w1 n k h = (-2.0) * (fromIntegral n) * (fromIntegral h) / (fromIntegral k) 

w2 :: Int -> Int -> Float
w2   k h = sum [(fromIntegral j) / (fromIntegral k) * (frac ((fromIntegral h) * (fromIntegral j) / (fromIntegral k)) - 0.5) |j <- [1..k-1]]

frac :: Float -> Float
frac x = x - fromIntegral (floor x)

gg :: Int -> [Complex Float]
gg n = [f n k h (w n k h) | k <- [1..], h <- [1..k], gcd k h == 1]

partition :: Int -> Float
partition n = realPart ( sum (take max_k (gg n)) )
             where max_k = 10

main = print ([partition i| i <- [1..10]])

トランプ大統領の方が日本の得?

www.youtube.com

去年の秋ごろは、どうせブッシュ弟が勝つだろうと思っていたらこの展開。勢いがあり、しがらみがなく、建前論を排す。トランプは、人々が無意識に抑圧していることを単純明解に語り、自由度が大きいので強い。

演説の最初と最後で Political Correctness を気にしないで自由に思うことを言えるようにするというのを二度繰り返して、やんやの喝采を受けていたので、これは行けるかもしれないと思った。

演説では触れられなかったが、クリントン政権時に骨抜きにされたグラス・スティーガル法の復活も共和党綱領に入ったらしいので、金持ち連中には受け入れられないだろうが、サンダース支持者のような連中を引き入れることも可能になっている。

鳩山・菅の精神異常者によるポピュリズム政治を経験して、散々な目にあった日本から見れば、トランプを選ぶ政治的冒険は止めておけと言いたいところだが、その一方で日本の損得面からすればトランプ大統領の方が利益が多い気がする。

プーチンとアメリカが和解して、日本の対露政策の自由度が上がれば、ロシアに中国の背後を脅かさせることが出来るようになる。またロシアに北欧や東欧を圧迫させて、綺麗ごとをほざきながら戦前のように日支事変を引き起こして金儲けをたくらんでいる西ヨーロッパ勢に報復ができる。いずれにせよヨーロッパには、何食わぬ顔で人道援助と称して、もっとイスラム教徒を送り込んで、内部から崩壊させるべき。

またTPPは、経済的には一部多国籍企業を除いてどの国民も得をしないが、対支那プラットフォームとしての消極的価値があるだけだったが、別の形で対支構造が構築されたうえで、むこうから潰してくれれば願ったりかなったり。日本の防衛費負担に関しても、防衛義務の契約上の強制、軍回復が可能になるので、いいことづくめだと思う。


クリントン(メス)は、クリントン(オス)の方が40代でケネディー以来の若大統領になってすぐ、夫婦で日本に来たときに、自民党の政治家たちと会って、老人ばかりだったと老人政界批判をしたが、今や自分が老人となり既得権益層にどっぷり浸った老人政界の代表になっているのだから笑える。姑息な小さな嘘では、トランプの大法螺には勝てない。

f:id:fortran66:20160723023114g:plain

分割数 p(n) の直接計算

Hardy & Ramanujan と Rademacher によって、分割数 p(n) を漸化式を使わずに、直接計算できる式が与えられています。これを使って分割数を求めてみたいと思います。なお式の証明には、かなり高度な知識が要求されるようなので、結果だけ頂戴します。


分割数を直接計算できる式は、整数の分割という素朴なものとは思えないような複雑な形をしているので、数学科の連中が我等純真な素人を驚かすのによく持ち出してきます。ところが、計算して確かめてみることが可能な形で、はっきりと与えられることが少なく、しかも無限級数になっているので、ありがたみも少なめです。



G.E.Andrews の The Theory of Partitions に計算例が載っていますが、式が複雑で計算する気が起きませんでした。

J.Remmel & A.Mendes の Counting with Symmetric Functions に計算してみる気が起きる程度に簡単にまとめられた式が載っていたので、ここでは実際に数値を入れて計算してみます。

f:id:fortran66:20160709154256p:plain


この式は、G.E.Andrews の与える式と微妙に違っていますが、別途計算して見たところ、結果は同じになるようなので、24乗根の取り方の違いなのかなんなのか(追記:デデキント和の別表現のようです。)、どっちでもよさそうな感じです。(一度計算できると、 Andrews の式も微修正で計算できました。)

準備

とりあえず、\sinh({\pi\over k}\sqrt{{2\over3}(z-{1\over24})}) \over \sqrt{z-{1\over24}}微分を求めます。素直に微分すればいいのですが、プログラムすることを考えて、適当に変数置換してやると、f={\pi\over k}\sqrt{2\over3}, x_s=\sqrt{z-{1\over24}} とおいて、{f \cosh(f x_s) - {\sinh(f x_s)\over x_s}\over 2x_s^2}
と表わせます。


なお式中の h に関する総和のところは、実際は  0\lt h\le k で等号が抜けていると思われます。k=1の時に問題になります。

ソース・プログラム

本来は、変数 k に関する和は無限和ですが、10 までで止めておきます。これでも大体十分です。k=100 まで和をとった場合と比較して、n ~ 1000 までで、結果に 0.3 程度の誤差が出ますが、四捨五入すると関係ありません。

    module m_part
      implicit none
      integer , parameter :: kd = kind(1.0q0)
      real(kd), parameter :: pi = 4 * atan(1.0_kd)
    contains  
      complex(kd) pure function cpartition(n)
        integer, intent(in) :: n
        integer, parameter :: kmax = 10
        real(kd) :: f, s, t
        complex(kd) :: c
        integer :: j, m, k
        cpartition = (0.0_kd, 0.0_kd)
        do k = 1, kmax
          f = sqrt(k / 2.0_kd) / pi 
          c = (0.0_kd, 0.0_kd)
          do m = 1, k
            if (igcd(m, k) == 1) then
              s = -real(2 * n * m, kd) / k 
              do j = 1, k - 1
                t = real(m * j, kd) / k
                s = s + real(j, kd) / k * (t - floor(t) - 0.5_kd)                
              end do
              c = c + exp(cmplx(0.0_kd, pi * s, kind = kd)) 
            end if
          end do
          cpartition = cpartition + f * c * da(k, n) 
        end do  
      end function cpartition
  
      integer pure function igcd(ia, ib)
        integer, intent(in) :: ia, ib
        integer :: m(2)
        m = [ia, ib]
        do 
          m = [m(2), mod(m(1), m(2))]
          if (m(2) == 0) exit
        end do
        igcd = m(1)
      end function igcd  
      
      real(kd) pure function da(k, n) ! d/dx sinh( f * xs ) / xs ; xs = sqrt(x - 1/24)
        integer, intent(in) :: k, n 
        real(kd) :: xs, f
        xs = sqrt( real(n, kd) - 1.0_kd / 24.0_kd )
        f  = pi / k * sqrt(2.0_kd / 3.0_kd)
        da = ( f * cosh(f * xs) - sinh(f * xs) / xs ) / (2 * xs * xs) 
      end function da
    end module m_part
  
    program Pn
      use m_part
      implicit none
      integer :: i
      complex(kind = kd) :: z
      do i = 1, 1000
        print '(i7, f45.3, i30)', i, real( cpartition(i), kd ), nint(real( cpartition(i), kd ), kind = 8)
      end do  
    end program Pn

実行結果

      1                                        1.006                             1
      2                                        2.004                             2
      3                                        3.002                             3
      4                                        4.996                             5
      5                                        6.997                             7
      6                                       10.989                            11
      7                                       15.000                            15
      8                                       21.994                            22
      9                                       30.004                            30
     10                                       42.008                            42

400 近傍で 8 バイト整数の範囲を越えます。

    400                      6727090051741041925.961           6727090051741041926
    401                      7154640222653942320.999           7154640222653942321
    402                      7608802843339879269.005           7608802843339879269
    403                      8091200276484465580.978           8091200276484465581
    404                      8603551759348655060.036           8603551759348655060
    405                      9147679068859117602.063           9147679068859117602
    406                      9725512513742021729.066          -9223372036854775808
    407                     10339097267123947240.969          -9223372036854775808
    408                     10990600063775926994.010          -9223372036854775808
    409                     11682316277192317779.980          -9223372036854775808
    990         16183531619906475296861224625026.766          -9223372036854775808
    991         16839773100833956878604913215476.879          -9223372036854775808
    992         17522282609145324707635966077021.986          -9223372036854775808
    993         18232098083140097717852712346115.225          -9223372036854775808
    994         18970297947002453464660671155989.793          -9223372036854775808
    995         19738002669751617842096992232436.119          -9223372036854775808
    996         20536376383452971700767593594020.746          -9223372036854775808
    997         21366628562913781584556907794729.258          -9223372036854775808
    998         22230015769169865076825741905554.660          -9223372036854775808
    999         23127843459154899464880444632250.039          -9223372036854775808
   1000         24061467864032622473692149727991.395          -9223372036854775808
続行するには何かキーを押してください . . .

漸化式によって求めた p(1000) の値は p(1000)=24061467864032622473692149727991 となっていて、四捨五入後の結果と一致します。

乞食速報!Springer 電子本 $9.99 セール

Springer の電子本の一部が $9.99 または 9.99EUR ないし £9.99 になっています。八月まで。国を選ぶと値段の単位が変わります。$で買えれば一番安くなります。
www.promopro.com

古めの Fortran 本もいくつか $9.99 になっています。ドイツ語の FORTRAN IV 本なんかいかがでしょうかw

Springerは時々無茶苦茶な値引きや、金券をくれたりするので、馬鹿らしくて普通に買う気が失せます。知らずに定価で買っていた分を損失補てんしろ!

図書館などが Springer の一括パッケージを買っていたりすると、電子本が結構無料だったりします。タイトルはローテーションしているようですが。

ポスト京は ARM

前々から噂が出ていた、ポスト京が ARM になるというのが富士通から公式に確認されたようです。

www.hpcwire.jp

20160702


数年前、欧米から経済制裁を受けたロシアのプーチン大統領が、CPU をアメリカ製に依存するのは危険と、ARM ベースのスパコン開発を指示したとか、ニュースになっていた気がします。

そういえば、プーチン大統領は、欧米からロシアの銀行発行の VISA や MASTER のクレジットカード決済を拒否されるようになってから、日本には JCB カードという独自決済のクレジットカードがあるから、ロシア独自の世界に通用するクレジットカードを作るとも言っていた記憶もあります。中国は、クレジットカードは諦めてデビットカードで誤魔化しています。まぁ支那人同士ですらお互いを信じらんでしょうw

インテルは中国のスパコン開発に対して7割引きのダンピング販売をして、不公正な貿易を行っていたわけで、実に怪しからんと思います。かつてアメリカは日本のスパコンにはダンピングしていると言いがかりをつけ300%の関税をかけて保護貿易に走り、自由で公正なw市場経済を破壊した不埒千万な過去がありますが、今度もうまくゆけばゆくほど、様々な妨害をしてくるでしょうから、馬鹿な中国を弾除けに使って、こそこそと開発するのが良かろうと思います。

ロシアがらみで富士通がアメリカの妨害を受けないことを祈ります。あら^~、がんば~る