fork download
  1. // 『パラレルテンパリングを用いた近似ベイズ計算』 http://b...content-available-to-author-only...n.jp/archives/2901
  2. // 本コードは概ね http://a...content-available-to-author-only...v.org/abs/1108.3423v3 の例題にそって作成していますが,一部異なる点があります。
  3. // 標準出力に混合正規分布 0.45 * N(0, 1^2) + 0.45 * N(0, 0.1^2) + 0.10 * N(5, 1^2) からのランダムサンプルを出力します。
  4.  
  5. open System
  6.  
  7. type Random with
  8. member this.NextUniform inf sup =
  9. let u = this.NextDouble ()
  10. inf + u * (sup - inf)
  11.  
  12. member this.NextNormal mean variance =
  13. // Box-Muller 法による正規乱数の生成。
  14. let u1 = this.NextDouble ()
  15. let u2 = this.NextDouble ()
  16. let r = sqrt <| -2.0 * log u1
  17. let x = r * cos (2.0 * Math.PI * u2) // 効率は悪いが,面倒なので sin の方は捨てる。
  18. mean + x * sqrt variance
  19.  
  20. // お題は [-10, 10] だけど [-10, 10) とするが,特に問題はない。
  21. let samplePrior (random : Random) = random.NextUniform -10.0 10.0
  22.  
  23. // サンプルされたパラメーターをもとにデータをシミュレーションする。
  24. let simulateValue (random : Random) theta =
  25. let r = random.NextDouble ()
  26. if r < 0.45
  27. then
  28. random.NextNormal theta 1.0
  29. elif r < 0.90
  30. then
  31. random.NextNormal theta 0.01
  32. else
  33. random.NextNormal (theta - 5.0) 1.0
  34.  
  35. // 観察データを 0.0 として |observed - simulated| を計算する。
  36. let distance x = abs x
  37.  
  38. type AbcResult =
  39. | Accept of float (* parameter *) * float (* distance *)
  40. | Reject
  41.  
  42. let rejection random tolerance theta =
  43. let x = simulateValue random theta
  44. let d = distance x
  45. if d < tolerance
  46. then
  47. Accept (theta, d)
  48. else
  49. Reject
  50.  
  51. let rec rejectionInfinite random tolerance =
  52. seq {
  53. yield rejection random tolerance (samplePrior random)
  54. yield! rejectionInfinite random tolerance
  55. }
  56.  
  57. // 頻繁にスワップするので配列が速いと思われる。
  58. let swapInPlace i j (array : 'a []) =
  59. let tmp = array.[i]
  60. array.[i] <- array.[j]
  61. array.[j] <- tmp
  62.  
  63. let sampleWithReplacement (random : Random) size (source : 'a []) =
  64. let length = Array.length source
  65. let result = Array.zeroCreate size
  66. for index = 0 to size - 1 do
  67. let randomIndex = random.Next (length)
  68. result.[index] <- source.[randomIndex]
  69. result
  70.  
  71. let random = Random ()
  72. let chainLength = 600000
  73. let currentLength = ref 0
  74. let burnin = 150000
  75. let sampleStep = 500 // ブログでは 100 にしている。
  76. let n = 15
  77. let split length (min, max) =
  78. let l = length - 1
  79. let r = Math.Pow (max / min, 1.0 / float l)
  80. in [| for i in 0 .. l -> min * pown r i |]
  81. let tolerance = split n (0.025, 2.0)
  82. let temperature = split n (1.0, 4.0)
  83.  
  84. // 最初だけ ABC-RS を行う。
  85. let current =
  86. let chooseAcceptance = Seq.choose (function | Accept (theta, d) -> Some (theta, d) | Reject -> None)
  87. Array.map (rejectionInfinite random >> chooseAcceptance >> Seq.head) tolerance
  88. incr currentLength
  89.  
  90. let inline q (theta, temperature) = random.NextNormal theta (0.10 * 0.10 * temperature)
  91. let inline isInPriorRange x = -10.0 <= x && x < 10.0
  92. let chainIndexes = [| 0 .. n - 1 |]
  93. while !currentLength < chainLength do
  94. // ABC-MCMC ステップ
  95. let theta = Array.zip (Array.map fst current) temperature |> Array.map q
  96. let values = Array.map (simulateValue random) theta
  97. // alpha = min { 1, (π(candidate) * q(current -> candidate)) / (π(current) * q(candidate -> current)) } * 1_ρ(values)
  98. // 1_ρ は indicator。
  99. // q は平均 0 の正規分布なので比は常に 1 になる。
  100. // π は一様分布なので範囲外で 0,範囲内で 1 で current は常に範囲内にあることが保障される。
  101. // したがって
  102. // * candidate が一様分布の範囲内の時 alpha = 1_ρ(values)
  103. // * candidate が一様分布の範囲外の時 alpha = 0
  104. for index = 0 to n - 1 do
  105. let t = theta.[index]
  106. let x = values.[index]
  107. let e = tolerance.[index]
  108. let d = distance x
  109. if isInPriorRange t && d < e
  110. then
  111. current.[index] <- (t, d)
  112.  
  113. // 交換ステップ
  114. for loop = 1 to n do
  115. let index = sampleWithReplacement random 2 chainIndexes
  116. Array.sortInPlace index
  117. let i = Array.min index
  118. let j = Array.max index
  119. if i <> j
  120. then
  121. let (_, d) = current.[j]
  122. let e = tolerance.[i]
  123. if d < e
  124. then
  125. swapInPlace i j current
  126.  
  127. // 出力
  128. incr currentLength
  129. if !currentLength > burnin && !currentLength % sampleStep = 0
  130. then
  131. printfn "%f" (fst current.[0])
Success #stdin #stdout 10.38s 12536KB
stdin
Standard input is empty
stdout
-0.118819
5.265918
0.028296
0.049107
-0.718571
0.004398
-0.083374
0.078990
-1.621615
0.225420
-1.384409
-0.987586
-0.066208
-0.131485
-0.017359
-0.014721
0.022589
-1.506826
0.012013
0.018844
0.011057
0.752805
-0.077104
-0.927193
-0.012464
-0.049499
0.792258
-1.077942
-0.092582
-0.111923
0.152045
0.079144
-0.393966
3.694000
4.430809
0.216540
-0.074548
0.033399
1.878495
-0.177615
0.043382
1.826982
4.951349
0.177444
0.002438
0.446600
-0.048691
5.780528
0.027939
-0.066948
-0.379158
-0.114988
-0.675303
0.006243
0.035725
-1.690631
-0.026340
4.164721
-0.024473
0.102088
-1.438116
0.179034
0.457445
0.142775
0.154895
-0.031643
-0.109459
0.185654
-0.148243
5.150715
-0.184633
6.134255
2.011769
-0.957493
-0.148149
5.598653
-0.304358
1.110902
5.784142
5.598537
5.860343
-0.288713
0.854652
-0.133100
0.077136
5.613270
0.139243
-0.133149
0.012974
0.232061
-0.384250
0.936545
-0.002910
-0.082748
0.170384
0.599812
0.500033
-0.036493
0.633301
0.204899
0.771868
-0.984759
-0.397590
-0.086585
-0.123356
1.866951
0.131280
-0.430772
1.897561
0.454318
-0.111110
-0.269022
0.183569
-0.114298
-0.105588
0.035689
-0.442169
-0.001866
0.177753
0.132908
0.174924
1.015035
-1.190085
0.645416
0.757842
0.267698
-0.034489
-0.000761
0.002944
1.126527
0.079334
-0.186761
-0.044181
-1.019251
1.003846
0.530472
0.138973
7.379286
-0.143112
7.379286
0.135278
0.292835
-0.798659
-1.978503
-0.064533
-0.210917
-1.088613
-0.055185
0.121514
0.792328
-0.021540
0.041687
-0.405386
0.627743
0.009855
0.122500
1.417043
-0.097962
-0.257606
-0.207919
-1.618806
0.499374
-0.008599
-0.734986
-0.105801
1.488835
0.391476
0.045975
0.157921
-0.094537
0.306280
4.616794
0.036864
4.522774
5.595804
0.000133
-0.051580
0.067224
-0.159751
-0.913242
4.386369
-0.139567
1.227706
-0.052379
0.009712
-0.800387
-0.387964
-0.661035
-1.558372
2.535216
-0.021703
6.454781
0.098940
0.039062
-0.035662
0.072090
4.417576
0.451053
-0.069770
4.112414
-0.072211
5.162649
3.954076
0.044462
0.529996
6.101265
-0.992264
0.112528
-1.886430
0.078399
0.074869
5.555865
5.172652
-0.568740
0.014073
1.615148
1.236255
0.197452
-0.353564
-0.040759
0.118673
-0.685723
-0.088743
0.236700
-1.272717
1.354866
-0.064594
0.090681
1.772164
-0.200808
0.410345
5.732327
5.732327
0.016504
5.966151
-0.149083
0.096587
0.016450
4.486176
6.727388
4.731989
-0.002341
0.968134
0.158079
-0.003465
0.756014
0.921664
-1.421749
0.070923
0.041104
-1.187951
0.193347
0.039074
-0.127570
5.128223
4.631017
-0.071991
-0.123146
-0.061115
1.227975
-0.145136
4.721296
-0.099676
4.758756
4.730915
2.039314
-0.044497
-0.000319
-1.445597
-0.944539
3.376653
0.794110
0.087578
-2.364537
0.339218
0.044713
-2.044779
0.002376
1.028490
-0.768349
4.811347
0.726411
0.020663
0.533404
0.003871
-0.029137
0.615302
-0.997053
0.099310
-0.033311
0.048338
-0.056181
-0.083624
6.422760
-0.560323
1.164080
0.317548
0.200816
-0.088628
3.530128
-0.008004
4.993744
0.166389
-0.023516
-1.162164
4.423485
-0.893759
0.758633
-0.008655
0.270959
-0.154152
4.867134
-1.108067
-0.233465
-0.946889
0.070207
0.127625
-0.058843
-0.522972
-0.185684
-0.684658
1.011919
-0.391588
0.079108
-0.174926
0.057223
-0.020001
0.213274
0.029655
-0.193520
0.039607
0.125984
-0.642553
0.120832
0.029441
0.135255
0.285201
-0.033626
-0.066535
-0.013666
0.071244
0.200911
-0.940416
-0.057585
-2.328560
-2.543599
0.886917
-0.119398
-2.106266
-0.137575
0.087449
-0.599242
0.018918
0.180185
-1.096568
-0.037366
0.036444
-0.011408
0.899218
-0.033470
0.412252
0.319655
0.050019
0.429890
-0.153269
0.014220
-0.173575
-0.209299
0.095306
-0.047375
-0.503643
-1.040535
0.290734
0.060252
-0.885500
0.048794
0.034662
1.202504
-0.469105
-0.564664
0.044063
0.267068
0.102173
-0.451075
-0.142559
0.212171
-0.062087
0.179273
-0.003488
-1.033210
0.206865
0.508081
6.124548
0.383458
0.007800
-0.070460
1.655746
-0.024154
-0.149718
-0.172551
0.242470
-0.090995
0.102838
-0.144471
-0.780062
-0.070119
0.061029
-0.138412
4.260821
-0.104230
0.140170
0.132639
1.719685
0.014366
4.057488
0.019297
-0.183490
4.504778
-0.065261
0.032950
4.884889
0.053016
-0.196001
0.159647
-0.031209
4.504320
1.667542
-0.168747
-0.095299
-0.071339
0.090001
0.088590
0.062242
0.055982
-0.835695
0.112107
0.012212
0.042512
-0.254899
-0.290294
-0.043431
-0.492167
4.484856
-0.240641
0.115118
-0.017384
0.047520
-0.908698
0.581398
-0.102841
-1.523802
0.072629
0.079593
-0.253669
1.631629
2.729527
0.781184
-0.009224
-0.009639
0.026781
-0.012746
-0.087450
-0.663020
0.100554
0.107433
0.049792
0.045149
0.865636
-0.579012
-0.952581
-0.002963
0.834701
-0.004498
0.835057
0.227910
-0.670954
0.270834
-0.012748
-0.043722
-0.074630
0.173224
0.122809
-0.003399
0.139100
0.144493
-0.287906
0.002103
-0.139868
-0.049124
-0.052674
0.155707
-0.046988
-0.193983
-0.513397
0.085511
0.414505
0.015185
-0.201202
0.148982
0.274724
-1.144198
-0.024207
-0.091415
-0.159898
-1.923803
0.115939
5.994956
-0.129468
-0.086961
-0.129826
-0.835458
4.949843
0.047967
1.775514
-0.158856
-1.176580
4.318368
-0.080559
0.332740
-1.641640
5.653906
5.457665
-0.108466
-0.010198
-0.136855
-0.180784
-0.542118
0.330112
0.054978
4.721714
-0.044970
-0.037986
-0.327950
-0.018228
-2.009242
-1.087963
-0.001278
4.998323
-0.222102
0.082383
-0.249798
3.533656
0.040629
-1.418693
0.031173
0.064654
-0.610069
-1.077249
0.064023
0.321708
0.368059
-1.163366
0.364014
-0.094674
0.070129
5.746619
5.700341
-0.552955
-0.095459
0.124441
-1.793465
-0.046800
-2.069593
1.039528
-0.045578
-0.038269
0.052669
-0.667626
0.905038
4.967717
0.071576
0.070907
0.120838
-1.319994
-0.017323
5.988486
0.258340
0.831021
-0.732992
-0.040732
-0.146345
0.010728
0.775987
-1.168028
1.624362
-0.051349
5.685700
5.523847
0.689284
0.142995
0.207912
-0.127686
0.017771
-0.130947
0.068695
5.237124
-0.163874
0.091049
-0.074005
-0.013403
-0.032052
-0.024175
-1.638773
0.110123
1.148552
-0.132650
-0.445771
-0.007353
0.101892
5.301611
-0.674091
0.076025
-0.040043
-0.199930
0.349823
0.236404
-1.428510
0.777086
0.349559
0.665915
-0.010906
-0.162933
-0.759919
0.028001
-0.682418
-0.377615
-0.400240
-0.446942
0.072055
-0.057500
1.138446
0.006525
6.917462
-0.020650
-0.256491
-1.346220
0.761413
-0.306374
-0.118164
-0.010702
-1.426933
-2.201307
-0.005773
-0.987717
-0.031492
-0.843101
0.003212
0.049684
-0.019102
0.021699
0.615667
1.353494
-0.803638
3.866157
0.868782
-0.549285
-1.691410
0.499871
-0.191589
1.235914
-0.119764
-1.182771
0.007733
0.097946
0.070671
-1.100174
-1.341350
-0.050353
0.026955
0.121844
0.188021
-0.040770
-2.047906
1.078936
-0.413888
-0.891463
0.436769
0.064813
-0.010791
-0.142795
0.052206
-0.091924
-0.405707
-0.030742
0.100584
0.174271
0.031245
0.884249
-0.036626
-0.576067
-1.222445
1.687449
0.433202
-1.557014
-1.697392
0.051952
0.062048
0.640556
0.135635
-0.255511
0.855917
-0.066005
0.273614
0.000189
0.040840
0.109116
0.032145
-0.080608
-0.034530
-0.005433
-0.138844
-1.838127
-0.057874
-0.003950
-0.974009
-0.625801
-0.041519
0.699770
-0.438629
0.073307
-0.510687
0.054513
1.230603
0.014912
-0.089562
0.000044
-0.474163
0.034441
0.262653
-0.639936
-1.285681
-0.037620
-0.790059
1.094430
0.098680
0.299997
0.613343
-1.859514
-0.016624
0.099021
0.087153
-0.518829
0.046101
0.491168
0.247759
-0.186449
-1.577339
0.037681
1.103517
0.238204
-0.062619
-0.030397
0.017873
0.079852
0.420997
0.167002
-0.088916
0.387572
0.959497
-1.004368
0.066349
0.039826
-0.554682
0.096096
-1.823307
1.282162
2.231041
0.223413
1.328143
-0.064660
0.653358
1.609342
0.043989
0.590655
1.548959
3.138224
1.329383
-0.042348
0.218976
0.011400
-0.080569
4.247700
-0.829272
4.223985
-0.014981
4.698902
0.578908
0.139444
5.794235
-0.001048
-0.035959
1.540758
0.006945
0.304389
4.229575
5.801617
1.141784
-0.014789
-0.141551
0.038796
-0.039307
-0.040018
-0.839075
0.063392
-0.144061
0.727770
-0.125364
1.226735
-0.415507
0.830000
-0.278500
-0.622737
4.906003
0.450160
4.841793
1.677141
-0.082777
-0.128873
5.460385
-0.047177
-1.482707
-0.065134
-1.637055
-0.125964
4.708925
-0.047038
0.115266
0.038010
-0.387902
-0.055401
-0.079949
0.466638
-0.606020
0.025171
0.848413
0.005204
1.436263
-0.730969
4.135823
0.107133
-1.247509
0.012782
-0.561284
-0.378495
0.601119
0.062925
-0.112902
0.106025
-0.062191
0.088372
0.663270
-1.863301
-0.060862
0.702244
0.051968
0.176764
-0.163219
6.047525
0.178137
-0.026877
0.288075
0.860233
5.386448
-0.018960
1.152838
1.053251
0.183025
0.060589
-1.823730
4.775625
-0.232955
0.098975
0.036206
-0.624513
0.133401
0.006164
2.387638
-1.536595
0.097671
0.564853
-0.239580
1.268375
1.033708
-0.042958
0.444032
-1.117587
0.104752
-0.011153
-0.803884
0.884723
0.307136
-0.178439
-1.235143
-0.065422
-0.389157
0.804120
0.996889
-0.135445
-1.322196
-0.080560