September 2017 Update

This commit is contained in:
Ingy döt Net 2017-09-23 10:01:46 +02:00
parent bba7bfd280
commit ba8067c3b7
14570 changed files with 153136 additions and 63871 deletions

View file

@ -0,0 +1,82 @@
* Monte Carlo methods 08/03/2017
MONTECAR CSECT
USING MONTECAR,R13 base register
B 72(R15) skip savearea
DC 17F'0' savearea
STM R14,R12,12(R13) save previous context
ST R13,4(R15) link backward
ST R15,8(R13) link forward
LR R13,R15 set addressability
LA R8,1000 isamples=1000
LA R6,4 i=4
DO WHILE=(C,R6,LE,=F'7') do i=4 to 7
MH R8,=H'10' isamples=isamples*10
ZAP HITS,=P'0' hits=0
LA R7,1 j=1
DO WHILE=(CR,R7,LE,R8) do j=1 to isamples
BAL R14,RNDPK call random
ZAP X,RND x=rnd
BAL R14,RNDPK call random
ZAP Y,RND y=rnd
ZAP WP,X x
MP WP,X x**2
DP WP,ONE ~
ZAP XX,WP(8) x**2 normalized
ZAP WP,Y y
MP WP,Y y**2
DP WP,ONE ~
ZAP YY,WP(8) y**2 normalized
AP XX,YY xx=x**2+y**2
IF CP,XX,LT,ONE THEN if x**2+y**2<1 then
AP HITS,=P'1' hits=hits+1
ENDIF , endif
LA R7,1(R7) j++
ENDDO , enddo j
CVD R8,PSAMPLES psamples=isamples
ZAP WP,=P'4' 4
MP WP,ONE ~
MP WP,HITS *hits
DP WP,PSAMPLES /psamples
ZAP MCPI,WP(8) mcpi=4*hits/psamples
XDECO R6,WC edit i
MVC PG+4(1),WC+11 output i
MVC WC,MASK load mask
ED WC,PSAMPLES edit psamples
MVC PG+6(8),WC+8 output psamples
UNPK WC,MCPI unpack mcpi
OI WC+15,X'F0' zap sign
MVC PG+31(1),WC+6 output mcpi
MVC PG+33(6),WC+7 output mcpi decimals
XPRNT PG,L'PG print buffer
LA R6,1(R6) i++
ENDDO , enddo i
L R13,4(0,R13) restore previous savearea pointer
LM R14,R12,12(R13) restore previous context
XR R15,R15 rc=0
BR R14 exit
RNDPK EQU * ---- random number generator
ZAP WP,RNDSEED w=seed
MP WP,RNDCNSTA w*=cnsta
AP WP,RNDCNSTB w+=cnstb
MVC RNDSEED,WP+8 seed=w mod 10**15
MVC RND,=PL8'0' 0<=rnd<1
MVC RND+3(5),RNDSEED+3 return rnd
BR R14 ---- return
PSAMPLES DS 0D,PL8 F(15,0)
RNDSEED DC PL8'613058151221121' linear congruential constant
RNDCNSTA DC PL8'944021285986747' "
RNDCNSTB DC PL8'852529586767995' "
RND DS PL8 fixed(15,9)
ONE DC PL8'1.000000000' 1 fixed(15,9)
HITS DS PL8 fixed(15,0)
X DS PL8 fixed(15,9)
Y DS PL8 fixed(15,9)
MCPI DS PL8 fixed(15,9)
XX DS PL8 fixed(15,9)
YY DS PL8 fixed(15,9)
PG DC CL80'10**x xxxxxxxx samples give Pi=x.xxxxxx' buffer
MASK DC X'40202020202020202020202020202120' mask CL16 15num
WC DS PL16 character 16
WP DS PL16 packed decimal 16
YREGS
END MONTECAR

View file

@ -0,0 +1,50 @@
import 'dart:async';
import 'dart:html';
import 'dart:math' show Random;
// We changed 5 lines of code to make this sample nicer on
// the web (so that the execution waits for animation frame,
// the number gets updated in the DOM, and the program ends
// after 500 iterations).
main() async {
print('Compute π using the Monte Carlo method.');
var output = querySelector("#output");
await for (var estimate in computePi().take(500)) {
print('π ≅ $estimate');
output.text = estimate.toStringAsFixed(5);
await window.animationFrame;
}
}
/// Generates a stream of increasingly accurate estimates of π.
Stream<double> computePi({int batch: 100000}) async* {
var total = 0;
var count = 0;
while (true) {
var points = generateRandom().take(batch);
var inside = points.where((p) => p.isInsideUnitCircle);
total += batch;
count += inside.length;
var ratio = count / total;
// Area of a circle is A = πr², therefore π = A/r².
// So, when given random points with x <0,1>,
// y <0,1>, the ratio of those inside a unit circle
// should approach π / 4. Therefore, the value of π
// should be:
yield ratio * 4;
}
}
Iterable<Point> generateRandom([int seed]) sync* {
final random = new Random(seed);
while (true) {
yield new Point(random.nextDouble(), random.nextDouble());
}
}
class Point {
final double x, y;
const Point(this.x, this.y);
bool get isInsideUnitCircle => x * x + y * y <= 1;
}

View file

@ -0,0 +1,19 @@
let print x = printfn "%A" x
let MonteCarloPiGreco niter =
let eng = System.Random()
let action () =
let x: float = eng.NextDouble()
let y: float = eng.NextDouble()
let res: float = System.Math.Sqrt(x**2.0 + y**2.0)
if res < 1.0 then
1
else
0
let res = [ for x in 1..niter do yield action() ]
let tmp: float = float(List.reduce (+) res) / float(res.Length)
4.0*tmp
MonteCarloPiGreco 1000 |> print
MonteCarloPiGreco 10000 |> print
MonteCarloPiGreco 100000 |> print

View file

@ -1,6 +1,8 @@
import "futlib/math"
default(f32)
fun dirvcts(): [2][30]int =
fun dirvcts(): [2][30]i32 =
[
[
536870912, 268435456, 134217728, 67108864, 33554432, 16777216, 8388608, 4194304, 2097152, 1048576, 524288, 262144, 131072, 65536, 32768, 16384, 8192, 4096, 2048, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1
@ -11,36 +13,36 @@ fun dirvcts(): [2][30]int =
]
fun grayCode(x: int): int = (x >> 1) ^ x
fun grayCode(x: i32): i32 = (x >> 1) ^ x
----------------------------------------
--- Sobol Generator
----------------------------------------
fun testBit(n: int, ind: int): bool =
fun testBit(n: i32, ind: i32): bool =
let t = (1 << ind) in (n & t) == t
fun xorInds(n: int) (dir_vs: [num_bits]int): int =
let reldv_vals = zipWith (fn dv i =>
fun xorInds(n: i32) (dir_vs: [num_bits]i32): i32 =
let reldv_vals = zipWith (\ dv i ->
if testBit(grayCode n,i)
then dv else 0)
dir_vs (iota num_bits)
in reduce (^) 0 reldv_vals
fun sobolIndI (dir_vs: [m][num_bits]int, n: int): [m]int =
fun sobolIndI (dir_vs: [m][num_bits]i32, n: i32): [m]i32 =
map (xorInds n) dir_vs
fun sobolIndR(dir_vs: [m][num_bits]int) (n: int ): [m]f32 =
fun sobolIndR(dir_vs: [m][num_bits]i32) (n: i32 ): [m]f32 =
let divisor = 2.0 ** f32(num_bits)
let arri = sobolIndI( dir_vs, n )
in map (fn (x: int): f32 => f32(x) / divisor) arri
in map (\ (x: i32): f32 -> f32(x) / divisor) arri
fun main(n: int): f32 =
fun main(n: i32): f32 =
let rand_nums = map (sobolIndR (dirvcts())) (iota n)
let dists = map (fn xy =>
let (x,y) = (xy[0],xy[1]) in sqrt32(x*x + y*y))
let dists = map (\xy ->
let (x,y) = (xy[0],xy[1]) in f32.sqrt(x*x + y*y))
rand_nums
let bs = map (fn d => if d <= 1.0f32 then 1 else 0) dists
let bs = map (\d -> if d <= 1.0f32 then 1 else 0) dists
let inside = reduce (+) 0 bs
in 4.0f32*f32(inside)/f32(n)

View file

@ -0,0 +1,20 @@
function mcpi(n) {
var x, y, m = 0;
for (var i = 0; i < n; i += 1) {
x = Math.random();
y = Math.random();
if (x * x + y * y < 1) {
m += 1;
}
}
return 4 * m / n;
}
console.log(mcpi(1000));
console.log(mcpi(10000));
console.log(mcpi(100000));
console.log(mcpi(1000000));
console.log(mcpi(10000000));

View file

@ -0,0 +1,30 @@
(() => {
'use strict';
// monteCarloPi :: Int -> Float
const monteCarloPi = n =>
4 * range(1, n)
.reduce(a => {
const [x, y] = [rnd(), rnd()];
return x * x + y * y < 1 ? a + 1 : a;
}, 0) / n;
// GENERIC FUNCTIONS
// range :: Int -> Int -> [Int]
const range = (m, n) =>
Array.from({
length: Math.floor(n - m) + 1
}, (_, i) => m + i);
// rnd :: () -> Float
const rnd = Math.random;
// TEST with from 1000 samples to 10E8 samples
return range(3, 8)
.map(x => monteCarloPi(Math.pow(10, x)));
// e.g. -> [3.14, 3.1404, 3.13304, 3.142408, 3.1420304, 3.14156788]
})();

View file

@ -0,0 +1 @@
[3.14, 3.1404, 3.13304, 3.142408, 3.1420304, 3.14156788]

View file

@ -1,18 +0,0 @@
function mcpi(n){
var x,y,m=0;
for(var i = 0; i < n; i += 1) {
x = Math.random();
y = Math.random();
if (x*x + y*y < 1) { m += 1; }
}
return 4*m/n;
}
console.log(mcpi(1000));
console.log(mcpi(10000));
console.log(mcpi(100000));
console.log(mcpi(1000000));
console.log(mcpi(10000000));

View file

@ -0,0 +1,23 @@
// version 1.1.0
fun mcPi(n: Int): Double {
var inside = 0
(1..n).forEach {
val x = Math.random()
val y = Math.random()
if (x * x + y * y <= 1.0) inside++
}
return 4.0 * inside / n
}
fun main(args: Array<String>) {
println("Iterations -> Approx Pi -> Error%")
println("---------- ---------- ------")
var n = 1_000
while (n <= 100_000_000) {
val pi = mcPi(n)
val err = Math.abs(Math.PI - pi) / Math.PI * 100.0
println(String.format("%9d -> %10.8f -> %6.4f", n, pi, err))
n *= 10
}
}

View file

@ -2,8 +2,8 @@ sub pi {
my $nthrows = shift;
my $inside = 0;
foreach (1 .. $nthrows) {
my $x = rand * 2 - 1,
$y = rand * 2 - 1;
my $x = rand() * 2 - 1;
my $y = rand() * 2 - 1;
if (sqrt($x*$x + $y*$y) < 1) {
$inside++;
}
@ -11,4 +11,4 @@ sub pi {
return 4 * $inside / $nthrows;
}
printf "%9d: %07f\n", $_, pi($_) foreach 10**4, 10**6;
printf "%9d: %07f\n", $_, pi($_) for 10**4, 10**6;

View file

@ -0,0 +1,11 @@
integer N = 100
for i=1 to 6 do
integer inside = 0
for i=1 to N do
integer x = rand(N),
y = rand(N)
inside += (x*x+y*y<N*N)
end for
?{N,4*inside/N}
N *= 10
end for

View file

@ -1,30 +1,28 @@
/*REXX program computes and displays the value of pi÷4 using the Monte Carlo algorithm*/
pi=3.141592653589793238462643383279502884197169399375105820974944592307816406 /*true pi.*/
say ' 1 2 3 4 5 6 7 '
say 'scale: 1·234567890123456789012345678901234567890123456789012345678901234567890123'
/*true pi*/ pi=3.141592653589793238462643383279502884197169399375105820974944592307816406
say ' 1 2 3 4 5 6 7 '
say 'scale: 1·234567890123456789012345678901234567890123456789012345678901234567890123'
say /* [↑] a two-line scale for showing pi*/
say 'true pi='pi"+" /*we might as well brag about true pi.*/
say 'true pi= ' pi"+" /*we might as well brag about true pi.*/
numeric digits length(pi) - 1 /*this program uses these decimal digs.*/
parse arg times chunk . /*does user want a specific number? */
if times=='' | times=="," then times=1000000000 /*one billion should do it, hopefully. */
if chunk=='' | chunk=="." then chunk= 10000 /*perform Monte Carlo in 10k chunks.*/
limit=10000-1 /*REXX random generates only integers. */
if times=='' | times=="," then times=5e12 /*five trillion should do it, hopefully*/
if chunk=='' | chunk=="." then chunk=100000 /*perform Monte Carlo in 100k chunks.*/
limit=10000 - 1 /*REXX random generates only integers. */
limitSq=limit**2 /*··· so, instead of one, use limit**2.*/
accur=0 /*accuracy of Monte Carlo pi (so far). */
!=0; @reps='repetitions: Monte Carlo pi is' /*pi decimal digit accuracy (so far).*/
accuracy=0 /*accuracy of Monte Carlo pi (so far).*/
!=0; @reps= 'repetitions: Monte Carlo pi is' /*pi decimal digit accuracy (so far).*/
say /*a blank line, just for the eyeballs.*/
do j=1 for times%chunk
do chunk /*do Monte Carlo, one chunk at-a-time.*/
if random(0,limit)**2 + random(0,limit)**2 <=limitSq then !=!+1
end /*chunk*/
reps=chunk*j /*calculate the number of repetitions. */
do j=1 for times % chunk
do chunk /*do Monte Carlo, one chunk at-a-time.*/
if random(, limit)**2 + random(, limit)**2 <= limitSq then !=! + 1
end /*chunk*/
reps=chunk * j /*calculate the number of repetitions. */
_=compare(4*! / reps, pi) /*compare apples and ··· crabapples. */
if _<=accur then iterate /*if not better accuracy, keep trukin'.*/
say right(commas(reps),20) @reps 'accurate to' _-1 "places." /*-1 for dec. pt.*/
accur=_ /*use this accuracy for next baseline. */
if _<=accuracy then iterate /*Not better accuracy? Keep truckin'. */
say right(comma(reps), 20) @reps 'accurate to' _-1 "places." /*─1 ≡ dec. point*/
accuracy=_ /*use this accuracy for next baseline. */
end /*j*/
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
commas: procedure; parse arg _; n=_'.9'; #=123456789; b=verify(n,#,"M")
e=verify(n, #'0', , verify(n, #"0.", 'M') ) - 4
do j=e to b by -3; _=insert(',',_,j); end /*j*/; return _
comma: procedure; arg _; do k=length(_)-3 to 1 by -3; _=insert(',',_,k); end; return _

View file

@ -0,0 +1,23 @@
import <Utilities/Random.sl>;
import <Utilities/Conversion.sl>;
main(args(2)) := monteCarlo(stringToInt(args[1]), stringToInt(args[2]));
monteCarlo(n, seed) :=
let
totalHits := monteCarloHelper(n, seedRandom(seed), 0);
in
(totalHits / intToFloat(n))*4.0;
monteCarloHelper(n, generator, result) :=
let
xRand := getRandom(generator);
x := xRand.Value/(generator.RandomMax + 1.0);
yRand := getRandom(xRand.Generator);
y := yRand.Value/(generator.RandomMax + 1.0);
newResult := result + 1 when x^2 + y^2 < 1.0 else
result;
in
result when n < 0 else
monteCarloHelper(n - 1, yRand.Generator, newResult);

View file

@ -0,0 +1,25 @@
import <Utilities/Random.sl>;
import <Utilities/Conversion.sl>;
main(args(2)) := monteCarlo(stringToInt(args[1]), stringToInt(args[2]));
chunks := 100;
monteCarlo3(n, seed) :=
let
newSeeds := getRandomSequence(seedRandom(seed), chunks).Value;
totalHits := monteCarloHelper(n / chunks, seedRandom(newSeeds), 0);
in
(sum(totalHits) / intToFloat((n / chunks)*chunks))*4.0;
monteCarloHelper(n, generator, result) :=
let
xRand := getRandom(generator);
x := xRand.Value/(generator.RandomMax + 1.0);
yRand := getRandom(xRand.Generator);
y := yRand.Value/(generator.RandomMax + 1.0);
newResult := result + 1 when x^2 + y^2 < 1.0 else
result;
in
result when n < 0 else
monteCarloHelper(n - 1, yRand.Generator, newResult);

View file

@ -0,0 +1,9 @@
func monteCarloPi(nthrows) {
4 * (^nthrows -> count_by {
hypot(1.rand(2) - 1, 1.rand(2) - 1) < 1
}) / nthrows
}
for n in [1e2, 1e3, 1e4, 1e5, 1e6] {
printf("%9d: %07f\n", n, monteCarloPi(n))
}

View file

@ -0,0 +1,17 @@
program define mcdisk
clear all
quietly set obs `1'
gen x=2*runiform()
gen y=2*runiform()
quietly count if (x-1)^2+(y-1)^2<1
display 4*r(N)/_N
end
. mcdisk 10000
3.1424
. mcdisk 1000000
3.141904
. mcdisk 100000000
3.1416253

View file

@ -0,0 +1,8 @@
fcn monty(n){
inCircle:=0;
do(n){
x:=(0.0).random(1); y:=(0.0).random(1);
if(x*x + y*y < 1.0) inCircle+=1;
}
4.0*inCircle/n
}

View file

@ -0,0 +1,7 @@
fcn monty(n){
4.0 * (1).pump(n,Void,fcn(r){
x:=(0.0).random(1); y:=(0.0).random(1);
if(x*x + y*y < 1.0) r.inc();
r
}.fp(Ref(0)) ).value/n;
}