Monte Carlo methods: Difference between revisions
m
→{{header|Wren}}: Minor tidy
m (→{{header|REXX}}: elided one too many hyphens.) |
m (→{{header|Wren}}: Minor tidy) |
||
(94 intermediate revisions by 41 users not shown) | |||
Line 1:
{{task|Probability and statistics}}
A '''Monte Carlo Simulation''' is a way of approximating the value of a function
where calculating the actual value is difficult or impossible. <br>
Line 5 ⟶ 6:
and then makes a sort of "best guess."
A simple Monte Carlo Simulation can be used to calculate the value for
If you had a circle and a square where the length of a side of the square
was the same as the diameter of the circle, the ratio of the area of the circle
to the area of the square would be
So, if you put this circle inside the square and select many random points
inside the square, the number of points inside the circle
divided by the number of points inside the square and the circle
would be approximately
;Task:
Write a function to run a simulation like this, with a variable number of random points to select.
Also, show the results of a few different sample sizes.
For software where the number
we give
3.141592653589793238462643383280
<br><br>
=={{header|11l}}==
<syntaxhighlight lang="11l">F monte_carlo_pi(n)
V inside = 0
L 1..n
V x = random:()
V y = random:()
I x * x + y * y <= 1
inside++
R 4.0 * inside / n
print(monte_carlo_pi(1000000))</syntaxhighlight>
{{out}}
<pre>
3.13775
</pre>
=={{header|360 Assembly}}==
<syntaxhighlight lang="360asm">* 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</syntaxhighlight>
{{out}}
<pre>
10**4 10000 samples give Pi=3.129200
10**5 100000 samples give Pi=3.145000
10**6 1000000 samples give Pi=3.141180
10**7 10000000 samples give Pi=3.141677
</pre>
=={{header|Action!}}==
{{libheader|Action! Tool Kit}}
{{libheader|Action! Real Math}}
<syntaxhighlight lang="action!">INCLUDE "H6:REALMATH.ACT"
DEFINE PTR="CARD"
DEFINE REAL_SIZE="6"
BYTE ARRAY realArray(1536)
PTR FUNC RealArrayPointer(BYTE i)
PTR p
p=realArray+i*REAL_SIZE
RETURN (p)
PROC InitRealArray()
REAL r2,r255,ri,div
REAL POINTER pow
INT i
IntToReal(2,r2)
IntToReal(255,r255)
FOR i=0 TO 255
DO
IntToReal(i,ri)
RealDiv(ri,r255,div)
pow=RealArrayPointer(i)
Power(div,r2,pow)
OD
RETURN
PROC CalcPi(INT n REAL POINTER pi)
BYTE x,y
INT i,counter
REAL tmp1,tmp2,tmp3,r1,r4
REAL POINTER pow
counter=0
IntToReal(1,r1)
IntToReal(4,r4)
FOR i=1 TO n
DO
x=Rand(0)
pow=RealArrayPointer(x)
RealAssign(pow,tmp1)
y=Rand(0)
pow=RealArrayPointer(y)
RealAssign(pow,tmp2)
RealAdd(tmp1,tmp2,tmp3)
IF RealGreaterOrEqual(tmp3,r1)=0 THEN
counter==+1
FI
OD
IntToReal(counter,tmp1)
RealMult(r4,tmp1,tmp2)
IntToReal(n,tmp3)
RealDiv(tmp2,tmp3,pi)
RETURN
PROC Test(INT n)
REAL pi
PrintF("%I samples -> ",n)
CalcPi(n,pi)
PrintRE(pi)
RETURN
PROC Main()
Put(125) PutE() ;clear the screen
PrintE("Initialization of data...")
InitRealArray()
Test(10)
Test(100)
Test(1000)
Test(10000)
RETURN</syntaxhighlight>
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Monte_Carlo_methods.png Screenshot from Atari 8-bit computer]
<pre>
Initialization of data...
10 samples -> 3.2
100 samples -> 3.28
1000 samples -> 3.212
10000 samples -> 3.1156
</pre>
=={{header|Ada}}==
<
with Ada.Numerics.Float_Random; use Ada.Numerics.Float_Random;
Line 46 ⟶ 253:
Put_Line (" 10_000_000:" & Float'Image (Pi ( 10_000_000)));
Put_Line ("100_000_000:" & Float'Image (Pi (100_000_000)));
end Test_Monte_Carlo;</
The implementation uses built-in uniformly distributed on [0,1] random numbers.
Note that the accuracy of the result depends on the quality of the pseudo random generator: its circle length and correlation to the function being simulated.
Line 64 ⟶ 271:
{{works with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release 1.8.8d.fc9.i386}}
<
BEGIN
INT inside := 0;
Line 79 ⟶ 286:
print ((" 1 000 000:",pi ( 1 000 000),new line));
print ((" 10 000 000:",pi ( 10 000 000),new line));
print (("100 000 000:",pi (100 000 000),new line))</
{{out}}
<pre>
Line 89 ⟶ 296:
</pre>
=={{
<syntaxhighlight lang="rebol">Pi: function [throws][
inside: new 0.0
do.times: throws [
if 1 > hypot random 0 1.0 random 0 1.0 -> inc 'inside
]
return 4 * inside / throws
]
loop [100 1000 10000 100000 1000000] 'n ->
print [pad to :string n 8 "=>" Pi n]</syntaxhighlight>
{{out}}
<pre> 100 => 3.4
1000 => 3.112
10000 => 3.1392
100000 => 3.14368
1000000 => 3.14106</pre>
=={{header|AutoHotkey}}==
{{AutoHotkey case}}
Source: [http://www.autohotkey.com/forum/topic44657.html AutoHotkey forum] by Laszlo
<
MsgBox % MontePi(10000) ; 3.154400
MsgBox % MontePi(100000) ; 3.142040
Line 105 ⟶ 333:
Return 4*p/n
}
</syntaxhighlight>
=={{header|AWK}}==
<syntaxhighlight lang="awk">
# --- with command line argument "throws" ---
Line 120 ⟶ 348:
Pi = 3.14333
</syntaxhighlight>
=={{header|BASIC}}==
{{works with|QuickBasic|4.5}}
{{trans|Java}}
<
CLS
PRINT getPi(10000)
Line 146 ⟶ 374:
NEXT i
getPi = 4! * inCircle / throws
END FUNCTION</
{{out}}
<pre>
Line 155 ⟶ 383:
</pre>
==={{header|
{{works with|basic256|1.1.4.0}}
<syntaxhighlight lang="basic">
# Monte Carlo Simulator
# Determine value of pi
# 21010513
tosses = 1000
in_c = 0
i = 0
for i = 1 to tosses
x = rand
y = rand
x2 = x * x
y2 = y * y
xy = x2 + y2
d_xy = sqr(xy)
if d_xy <= 1 then
in_c += 1
endif
next i
print float(4*in_c/tosses)</syntaxhighlight>
{{out}}
<pre>
Throws Result
1000 3.208
10000 3.142
20000 3.1388
40000 3.1452
</pre>
====Other solution:====
<syntaxhighlight lang="freebasic">print " Number of throws Ratio (Pi) Error"
for pow = 2 to 8
n = 10 ^ pow
pi_ = getPi(n)
error_ = 3.141592653589793238462643383280 - pi_
print rjust(string(int(n)), 17); " "; ljust(string(pi_), 13); " "; ljust(string(error_), 13)
next
end
function getPi(n)
incircle = 0.0
for throws = 0 to n
incircle = incircle + (rand()^2 + rand()^2 < 1)
next
return 4.0 * incircle / throws
end function</syntaxhighlight>
{{out}}
<pre> Number of throws Ratio (Pi) Error
100 2.970297 0.17129562389
1000 3.14085914086 0.00073351273
10000 3.13208679132 0.00950586227
100000 3.14428855711 -0.00269590352
1000000 3.14041685958 0.00117579401
10000000 3.14094968591 0.000643
100000000 3.14153 0.00006264501</pre>
==={{header|BBC BASIC}}===
<syntaxhighlight lang="bbcbasic"> PRINT FNmontecarlo(1000)
PRINT FNmontecarlo(10000)
PRINT FNmontecarlo(100000)
Line 168 ⟶ 458:
IF RND(1)^2 + RND(1)^2 < 1 n% += 1
NEXT
= 4 * n% / t%</
{{out}}
<pre>
Line 177 ⟶ 467:
3.1412816
</pre>
==={{header|FreeBASIC}}===
<syntaxhighlight lang="freebasic">' version 23-10-2016
' compile with: fbc -s console
Randomize Timer 'seed the random function
Dim As Double x, y, pi, error_
Dim As UInteger m = 10, n, n_start, n_stop = m, p
Print
Print " Mumber of throws Ratio (Pi) Error"
Print
Do
For n = n_start To n_stop -1
x = Rnd
y = Rnd
If (x * x + y * y) <= 1 Then p = p +1
Next
Print Using " ############, "; m ;
pi = p * 4 / m
error_ = 3.141592653589793238462643383280 - pi
Print RTrim(Str(pi),"0");Tab(35); Using "##.#############"; error_
m = m * 10
n_start = n_stop
n_stop = m
Loop Until m > 1000000000 ' 1,000,000,000
' empty keyboard buffer
While Inkey <> "" : Wend
Print : Print "hit any key to end program"
Sleep
End</syntaxhighlight>
{{out}}
<pre> Mumber of throws Ratio (Pi) Error
10 3.2 -0.0584073464102
100 3.16 -0.0184073464102
1,000 3.048 0.0935926535898
10,000 3.1272 0.0143926535898
100,000 3.13672 0.0048726535898
1,000,000 3.14148 0.0001126535898
10,000,000 3.1417668 -0.0001741464102
100,000,000 3.14141 0.0001826535898
1,000,000,000 3.14169192 -0.0000992664102</pre>
==={{header|Liberty BASIC}}===
<syntaxhighlight lang="lb">
for pow = 2 to 6
n = 10^pow
print n, getPi(n)
next
end
function getPi(n)
incircle = 0
for throws=0 to n
scan
incircle = incircle + (rnd(1)^2+rnd(1)^2 < 1)
next
getPi = 4*incircle/throws
end function
</syntaxhighlight>
{{out}}
<pre>
100 2.89108911
1000 3.12887113
10000 3.13928607
100000 3.13864861
1000000 3.13945686
</pre>
==={{header|Locomotive Basic}}===
<syntaxhighlight lang="locobasic">10 mode 1:randomize time:defint a-z
20 input "How many samples";n
30 u=n/100+1
40 r=100
50 for i=1 to n
60 if i mod u=0 then locate 1,3:print using "##% done"; i/n*100
70 x=rnd*2*r-r
80 y=rnd*2*r-r
90 if sqr(x*x+y*y)<r then m=m+1
100 next
110 pi2!=4*m/n
120 locate 1,3
130 print m;"points in circle"
140 print "Computed value of pi:"pi2!
150 print "Difference to real value of pi: ";
160 print using "+#.##%"; (pi2!-pi)/pi*100</syntaxhighlight>
[[File:Monte Carlo, 200 points, Locomotive BASIC.png]]
[[File:Monte Carlo, 5000 points, Locomotive BASIC.png]]
==={{header|Run BASIC}}===
{{trans|Liberty BASIC}}
<syntaxhighlight lang="freebasic">for pow = 2 to 6
n = 10 ^ pow
print n; chr$(9); getPi(n)
next
end
function getPi(n)
incircle = 0
for throws = 0 to n
incircle = incircle + (rnd(1)^2 + rnd(1)^2 < 1)
next
getPi = 4 * incircle / throws
end function</syntaxhighlight>
{{out}}
<pre>100 3.12
1000 3.108
10000 3.1652
100000 3.14248
1000000 3.1435</pre>
==={{header|True BASIC}}===
{{trans|BASIC}}
<syntaxhighlight lang="qbasic">FUNCTION getpi(throws)
LET incircle = 0
FOR i = 1 to throws
!a square with a side of length 2 centered at 0 has
!x and y range of -1 to 1
LET randx = (rnd*2)-1 !range -1 to 1
LET randy = (rnd*2)-1 !range -1 to 1
!distance from (0,0) = sqrt((x-0)^2+(y-0)^2)
LET dist = sqr(randx^2+randy^2)
IF dist < 1 then !circle with diameter of 2 has radius of 1
LET incircle = incircle+1
END IF
NEXT i
LET getpi = 4*incircle/throws
END FUNCTION
CLEAR
PRINT getpi(10000)
PRINT getpi(100000)
PRINT getpi(1000000)
PRINT getpi(10000000)
END</syntaxhighlight>
{{out}}
<pre>3.1304
3.14324
3.141716
3.1416452</pre>
==={{header|PureBasic}}===
<syntaxhighlight lang="purebasic">OpenConsole()
Procedure.d MonteCarloPi(throws.d)
inCircle.d = 0
For i = 1 To throws.d
randX.d = (Random(2147483647)/2147483647)*2-1
randY.d = (Random(2147483647)/2147483647)*2-1
dist.d = Sqr(randX.d*randX.d + randY.d*randY.d)
If dist.d < 1
inCircle = inCircle + 1
EndIf
Next i
pi.d = (4 * inCircle / throws.d)
ProcedureReturn pi.d
EndProcedure
PrintN ("'built-in' #Pi = " + StrD(#PI,20))
PrintN ("MonteCarloPi(10000) = " + StrD(MonteCarloPi(10000),20))
PrintN ("MonteCarloPi(100000) = " + StrD(MonteCarloPi(100000),20))
PrintN ("MonteCarloPi(1000000) = " + StrD(MonteCarloPi(1000000),20))
PrintN ("MonteCarloPi(10000000) = " + StrD(MonteCarloPi(10000000),20))
PrintN("Press any key"): Repeat: Until Inkey() <> ""
</syntaxhighlight>
{{out}}
<pre>'built-in' #PI = 3.14159265358979310000
MonteCarloPi(10000) = 3.17119999999999980000
MonteCarloPi(100000) = 3.14395999999999990000
MonteCarloPi(1000000) = 3.14349599999999980000
MonteCarloPi(10000000) = 3.14127720000000020000
Press any key</pre>
=={{header|C}}==
<
#include <stdlib.h>
#include <math.h>
Line 214 ⟶ 689:
printf("Pi is %f\n", pi(3e-4)); /* set to 1e-4 for some fun */
return 0;
}</
=={{header|C sharp|C#}}==
<
class Program {
Line 265 ⟶ 715:
}
}
}</
{{out}}
Line 275 ⟶ 725:
100,000,000:3.1413976
</pre>
=={{header|C++}}==
<syntaxhighlight lang="cpp">
#include<iostream>
#include<math.h>
#include<stdlib.h>
#include<time.h>
using namespace std;
int main(){
int jmax=1000; // maximum value of HIT number. (Length of output file)
int imax=1000; // maximum value of random numbers for producing HITs.
double x,y; // Coordinates
int hit; // storage variable of number of HITs
srand(time(0));
for (int j=0;j<jmax;j++){
hit=0;
x=0; y=0;
for(int i=0;i<imax;i++){
x=double(rand())/double(RAND_MAX);
y=double(rand())/double(RAND_MAX);
if(y<=sqrt(1-pow(x,2))) hit+=1; } //Choosing HITs according to analytic formula of circle
cout<<""<<4*double(hit)/double(imax)<<endl; } // Print out Pi number
}
</syntaxhighlight>
=={{header|Clojure}}==
<
(loop [x (rand) y (rand) in 0 total 1]
(if (< total iterations)
Line 283 ⟶ 758:
(double (* (/ in total) 4)))))
(doseq [x (take 5 (iterate #(* 10 %) 10))] (println (str (format "% 8d" x) ": " (calc-pi x))))</
{{out}}
Line 292 ⟶ 767:
100000: 3.14104
1000000: 3.141064
</pre>
<syntaxhighlight lang="lisp">(defn experiment
[]
(if (<= (+ (Math/pow (rand) 2) (Math/pow (rand) 2)) 1) 1 0))
(defn pi-estimate
[n]
(* 4 (float (/ (reduce + (take n (repeatedly experiment))) n))))
(pi-estimate 10000)
</syntaxhighlight>
{{out}}
<pre>
3.1347999572753906
</pre>
=={{header|Common Lisp}}==
<
(/ (loop repeat n count (<= (abs (complex (random 1.0) (random 1.0))) 1.0)) n 0.25))
(dolist (n (loop repeat 5 for n = 1000 then (* n 10) collect n))
(format t "~%~8d -> ~f" n (approximate-pi n)))</
{{out}}
Line 308 ⟶ 799:
1000000 -> 3.142072
10000000 -> 3.1420677
</pre>
=={{header|Crystal}}==
{{trans|Ruby}}
<syntaxhighlight lang="ruby">def approx_pi(throws)
times_inside = throws.times.count {Math.hypot(rand, rand) <= 1.0}
4.0 * times_inside / throws
end
[1000, 10_000, 100_000, 1_000_000, 10_000_000].each do |n|
puts "%8d samples: PI = %s" % [n, approx_pi(n)]
end</syntaxhighlight>
{{out}}
<pre> 1000 samples: PI = 3.1
10000 samples: PI = 3.1428
100000 samples: PI = 3.1454
1000000 samples: PI = 3.141012
10000000 samples: PI = 3.141148
</pre>
=={{header|D}}==
<
double pi(in uint nthrows) /*nothrow*/ @safe /*@nogc*/ {
Line 324 ⟶ 833:
foreach (immutable p; 1 .. 8)
writefln("%10s: %07f", 10 ^^ p, pi(10 ^^ p));
}</
{{out}}
<pre> 10: 3.200000
Line 345 ⟶ 854:
===More Functional Style===
<
import std.stdio, std.random, std.math, std.algorithm, std.range;
Line 353 ⟶ 862:
foreach (immutable p; 1 .. 8)
writefln("%10s: %07f", 10 ^^ p, pi(10 ^^ p));
}</
{{out}}
<pre> 10: 3.200000
Line 362 ⟶ 871:
1000000: 3.142836
10000000: 3.141550</pre>
=={{header|Dart}}==
From example at [https://www.dartlang.org/ Dart Official Website]
<syntaxhighlight lang="dart">
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;
}
</syntaxhighlight>
{{out}}
The script give in reality an output formatted in HTML
<pre>π ≅ 3.14139</pre>
=={{header|Delphi}}==
{{works with|Delphi|6.0}}
{{libheader|SysUtils,StdCtrls}}
<syntaxhighlight lang="Delphi">
function MonteCarloPi(N: cardinal): double;
{Approximate Pi by seeing if points fall inside circle}
var I,InsideCnt: integer;
var X,Y: double;
begin
InsideCnt:=0;
for I:=1 to N do
begin
{Random X,Y = 0..1}
X:=Random;
Y:=Random;
{See if it falls in Unit Circle}
if X*X + Y*Y <= 1 then Inc(InsideCnt);
end;
{Because X and Y are squared, they only fall with 1/4 of the circle}
Result:=4 * InsideCnt / N;
end;
procedure ShowOneSimulation(Memo: TMemo; N: cardinal);
var MyPi: double;
begin
MyPi:=MonteCarloPi(N);
Memo.Lines.Add(Format('Samples: %15.0n Pi= %2.15f',[N+0.0,MyPi]));
end;
procedure ShowMonteCarloPi(Memo: TMemo);
begin
ShowOneSimulation(Memo,1000);
ShowOneSimulation(Memo,10000);
ShowOneSimulation(Memo,100000);
ShowOneSimulation(Memo,1000000);
ShowOneSimulation(Memo,10000000);
ShowOneSimulation(Memo,100000000);
end;
</syntaxhighlight>
{{out}}
<pre>
Samples: 1,000 Pi= 3.156000000000000
Samples: 10,000 Pi= 3.152000000000000
Samples: 100,000 Pi= 3.142920000000000
Samples: 1,000,000 Pi= 3.140864000000000
Samples: 10,000,000 Pi= 3.141990800000000
Samples: 100,000,000 Pi= 3.141426720000000
</pre>
=={{header|E}}==
Line 367 ⟶ 993:
This computes a single quadrant of the described square and circle; the effect should be the same since the other three are symmetric.
<
var inside := 0
for _ ? (entropy.nextFloat() ** 2 + entropy.nextFloat() ** 2 < 1) in 1..n {
Line 373 ⟶ 999:
}
return inside * 4 / n
}</
Some sample runs:
Line 394 ⟶ 1,020:
? pi(100000)
# value: 3.13848
=={{header|EasyLang}}==
<syntaxhighlight lang="text">
func mc n .
for i = 1 to n
x = randomf
y = randomf
if x * x + y * y < 1
hit += 1
.
.
return 4.0 * hit / n
.
numfmt 4 0
print mc 10000
print mc 100000
print mc 1000000
print mc 10000000
</syntaxhighlight>
Output:
3.1292
3.1464
3.1407
3.1413
=={{header|EDSAC order code}}==
Because real numbers on EDSAC were restricted to the interval [-1,1), this solution estimates pi/10 instead of pi. With 100,000 trials the program would have taken about 3.5 hours on the original EDSAC.
<syntaxhighlight lang="edsac">
[Monte Carlo solution for Rosetta Code.]
[EDSAC program, Initial Orders 2.]
[Arrange the storage]
T45K P56F [H parameter: library s/r P1 to print real number]
T46K P78F [N parameter: library s/r P7 to print integer]
T47K P210F [M parameter: main routine]
T48K P114F [& (delta) parameter: library s/r C6 (division)]
T49K P150F [L parameter: library subroutine R4 to read data]
T51K P172F [G parameter: generator for pseudo-random numbers]
[Library subroutine M3, runs at load time and is then overwritten.
Prints header; here the header sets teleprinter to figures.]
PFGKIFAFRDLFUFOFE@A6FG@E8FEZPF
*!!!!TRIALS!!EST!PI#X10@&..
PK [after header, blank tape and PK (WWG, 1951, page 91)]
[================ Main routine ====================]
E25K TM GK
[Variables]
[0] PF PF [target count: print result when count = target]
[2] PF PF [count of points]
[4] PF PF [count of hits (point inside circle)]
[6] PF PF [x-coordinate - 1/2]
[Constants]
T8#Z PF T10#Z PF [clear sandwich bits in 35-bit constants]
T8Z [resume normal loading]
[8] PD PF [35-bit constant 1]
[10] L1229F Y819F [35-bit constant 2/5 (near enough)]
[12] IF [1/2]
[13] RF [1/4]
[14] #F [figures shift]
[15] MF [dot (decimal point) in figures mode]
[16] @F [carriage return]
[17] &F [line feed]
[18] !F [space]
[Enter with acc = 0]
[19] A19@ GL [read seed for LCG into 0D]
AD T4D [pass seed to LCG in 4D]
[23] A23@ GG [initialize LCG]
T2#@ T4#@ [zero trials and hits]
[Outer loop: round target counts]
[27] TF [clear acc]
[28] A28@ GL [read next target count into 0D]
SD [acc := -target]
E85@ [exit if target = 0]
T#@ [store negated target]
[Inner loop : round points in the square]
[33] TF T4D [pass LCG range = 0 to return random real in [0,1)]
[35] A35@ G1G [call LCG, 0D := random x]
AD S12@ T6#@ [store x - 1/2 over next call]
T4D
[41] A41@ G1G [call LCG, 0D := random y]
AD S12@ TD [store y - 1/2]
H6#@ V6#@ [acc := (x - 1/2)^2]
HD VD [acc := acc := (x - 1/2)^2 + (y - 1/2)^2]
S13@ [test for point inside circle, i.e. acc < 1/4]
E56@ [skip if not]
TF A4#@ A8#@ T4#@ [inc number of hits]
[56] TF A2#@ A8#@ U2#@ [inc number of trials]
A#@ [add negated target]
G33@ [if not reached target, loop back]
A2#@ TD [pass number of trials to print s/r]
[64] A64@ GN [print number of trials]
A4#@ TD A2#@ T4D [pass hits and trials to division s/r]
[70] A70@ G& [0D := hits/trials, estimated value of pi/4]
HD V10#@ TD [times 2/5; pass estimated pi/10 to print s/r]
O18@ O18@ O8@ O15@ [print ' 0.']
[79] A79@ GH P5F [print estimated pi/10 to 5 decimals]
O16@ O17@ [print CR, LF]
E27@ [loop back for new target]
[85] O14@ [exit: print dummy character to flush printer buffer]
ZF [halt program]
[==================== Generator for pseudo-random numbers ===========]
[Linear congruential generator, same algorithm as Delphi 7 LCG.
38 locations]
E25K TG
GK G10@ G15@ T2#Z PF T2Z I514D P257F T4#Z PF T4Z PD PF T6#Z PF T6Z PF RF A6#@ S4#@ T6#@ E25F E8Z PF T8Z PF PF A3F T14@ A4D T8#@ ZF A3F T37@ H2#@ V8#@ L512F L512F L1024F A4#@ T8#@ H6#@ C8#@ T8#@ S4D G32@ TD A8#@ E35@ H4D TD V8#@ L1F TD ZF
[==================== LIBRARY SUBROUTINES ============================]
[D6: Division, accurate, fast.
36 locations, workspace 6D and 8D.
0D := 0D/4D, where 4D <> 0, -1.]
E25K T& GK
GKA3FT34@S4DE13@T4DSDTDE2@T4DADLDTDA4DLDE8@RDU4DLDA35@
T6DE25@U8DN8DA6DT6DH6DS6DN4DA4DYFG21@SDVDTDEFW1526D
[R4: Input of one signed integer at runtime.
22 storage locations; working positions 4, 5, and 6.]
E25K TL
GKA3FT21@T4DH6@E11@P5DJFT6FVDL4FA4DTDI4FA4FS5@G7@S5@G20@SDTDT6FEF
[P1: Prints non-negative fraction in 0D, without '0.']
E25K TH
GKA18@U17@S20@T5@H19@PFT5@VDUFOFFFSFL4FTDA5@A2FG6@EFU3FJFM1F
[P7, prints long strictly positive integer;
10 characters, right justified, padded left with spaces.
Even address; 35 storage locations; working position 4D.]
E25K TN
GKA3FT26@H28#@NDYFLDT4DS27@TFH8@S8@T1FV4DAFG31@SFLDUFOFFFSF
L4FT4DA1FA27@G11@XFT28#ZPFT27ZP1024FP610D@524D!FO30@SFL8FE22@
[===================================================================]
[The following, without the comments and white space, might have
been input from a separate tape.]
E25K TM GK
E19Z [define entry point]
PF [acc = 0 on entry]
[Integers supplied by user: (1) seed for LCG; (2) list of numbers of trials
for which to print result; increasing order, terminated by 0.
To be read by library subroutine R4; sign comes after value.]
987654321+100+1000+10000+100000+0+
</syntaxhighlight>
{{out}}
<pre>
TRIALS EST PI/10
100 0.32400
1000 0.31319
10000 0.31371
100000 0.31410
</pre>
=={{header|Elixir}}==
<
def pi(n) do
count = Enum.count(1..n, fn _ ->
x = :
y = :
:math.sqrt(x*x + y*y) <= 1
end)
Line 410 ⟶ 1,187:
Enum.each([1000, 10000, 100000, 1000000, 10000000], fn n ->
:io.format "~8w samples: PI = ~f~n", [n, MonteCarlo.pi(n)]
end)</
{{out}}
Line 419 ⟶ 1,196:
1000000 samples: PI = 3.142904
10000000 samples: PI = 3.141124
</pre>
=={{header|Erlang}}==
===With inline test===
<syntaxhighlight lang="erlang">
-module(monte).
-export([main/1]).
monte(N)->
monte(N,0,0).
monte(0,InCircle,NumPoints) ->
4 * InCircle / NumPoints;
monte(N,InCircle,NumPoints)->
Xcoord = rand:uniform(),
Ycoord = rand:uniform(),
monte(N-1,
if Xcoord*Xcoord + Ycoord*Ycoord < 1 -> InCircle + 1; true -> InCircle end,
NumPoints + 1).
main(N) -> io:format("PI: ~w~n", [ monte(N) ]).
</syntaxhighlight>
{{out}}
<pre>
8> [monte:main(X) || X <- [10000,100000,100000,10000000] ].
PI: 3.136
PI: 3.1464
PI: 3.1412
PI: 3.1416704
[ok,ok,ok,ok]
</pre>
===With test in a function===
<syntaxhighlight lang="erlang">
-module(monte2).
-export([main/1]).
monte(N)->
monte(N,0,0).
monte(0,InCircle,NumPoints) ->
4 * InCircle / NumPoints;
monte(N,InCircle,NumPoints)->
X = rand:uniform(),
Y = rand:uniform(),
monte(N-1, within(X,Y,InCircle), NumPoints + 1).
within(X,Y,IN)->
if X*X + Y*Y < 1 -> IN + 1;
true -> IN
end.
main(N) -> io:format("PI: ~w~n", [ monte(N) ]).
</syntaxhighlight>
{{out}}
<pre>Xcoord
6> [monte2:main(X) || X <- [10000000,1000000,100000,10000] ].
PI: 3.1424172
PI: 3.140544
PI: 3.14296
PI: 3.1252
[ok,ok,ok,ok]
</pre>
=={{header|ERRE}}==
<syntaxhighlight lang="erre">
PROGRAM RANDOM_PI
Line 446 ⟶ 1,289:
MONTECARLO(1000000->RES) PRINT(RES)
MONTECARLO(10000000->RES) PRINT(RES)
END PROGRAM</
{{out}}
<pre>
Line 457 ⟶ 1,300:
=={{header|Euler Math Toolbox}}==
<syntaxhighlight lang="euler math toolbox">
>function map MonteCarloPI (n,plot=false) ...
$ X:=random(1,n);
Line 472 ⟶ 1,315:
3.14159265359
>MonteCarloPI(10000,true):
</syntaxhighlight>
[[File:Test.png]]
=={{header|F Sharp}}==
There is some support and test expressions.
<syntaxhighlight lang="fsharp">
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
</syntaxhighlight>
{{out}}
<pre>
3.164
3.122
3.1436
</pre>
=={{header|Factor}}==
Since Factor lets the user choose the range of the random generator, we use 2^32.
<
: limit ( -- n ) 2 32 ^ ; inline
: in-circle ( x y -- ? ) limit [ sq ] tri@ [ + ] [ <= ] bi* ;
: rand ( -- r ) limit random ;
: pi ( n -- pi ) [ [ drop rand rand in-circle ] count ] keep / 4 * >float ;</
Example use:
<
3.1412</
=={{header|Fantom}}==
<
class MontyCarlo
{
Line 517 ⟶ 1,391:
}
}
</syntaxhighlight>
{{out}}
Line 550 ⟶ 1,424:
=={{header|Fortran}}==
{{works with|Fortran|90 and later}}
<
IMPLICIT NONE
Line 584 ⟶ 1,458:
END DO
END PROGRAM MONTE_CARLO</
{{out}}
Line 594 ⟶ 1,468:
100000000 3.14147
</pre>
{{works with|Fortran|2008 and later}}
<syntaxhighlight lang="fortran">
program mc
integer :: n,i
real(8) :: pi
n=10000
do i=1,5
print*,n,pi(n)
n = n * 10
end do
end program
function pi(n)
integer :: n
real(8) :: x(2,n),pi
call random_number(x)
pi = 4.d0 * dble( count( hypot(x(1,:),x(2,:)) <= 1.d0 ) ) / n
end function
</syntaxhighlight>
=={{header|Futhark}}==
Since Futhark is a pure language, random numbers are implemented using Sobol sequences.
<syntaxhighlight lang="futhark">
import "futlib/math"
default(f32)
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
],
[
536870912, 805306368, 671088640, 1006632960, 570425344, 855638016, 713031680, 1069547520, 538968064, 808452096, 673710080, 1010565120, 572653568, 858980352, 715816960, 1073725440, 536879104, 805318656, 671098880, 1006648320, 570434048, 855651072, 713042560, 1069563840, 538976288, 808464432, 673720360, 1010580540, 572662306, 858993459
]
]
fun grayCode(x: i32): i32 = (x >> 1) ^ x
----------------------------------------
--- Sobol Generator
----------------------------------------
fun testBit(n: i32, ind: i32): bool =
let t = (1 << ind) in (n & t) == t
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]i32, n: i32): [m]i32 =
map (xorInds n) dir_vs
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 (\ (x: i32): f32 -> f32(x) / divisor) arri
fun main(n: i32): f32 =
let rand_nums = map (sobolIndR (dirvcts())) (iota n)
let dists = map (\xy ->
let (x,y) = (xy[0],xy[1]) in f32.sqrt(x*x + y*y))
rand_nums
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)
</syntaxhighlight>
=={{header|Go}}==
'''Using standard library math/rand:'''
<syntaxhighlight lang="go">package main
import (
Line 628 ⟶ 1,577:
fmt.Println(getPi(10000000))
fmt.Println(getPi(100000000))
}</
{{out}}
<pre>
Line 637 ⟶ 1,586:
3.14149596
</pre>
'''Using x/exp/rand:'''
For very careful Monte Carlo studies, you might consider the subrepository rand library. The random number generator there has some advantages such as better known statistical properties and better use of memory.
<syntaxhighlight lang="go">package main
import (
"fmt"
"math"
"time"
"golang.org/x/exp/rand"
)
func getPi(numThrows int) float64 {
inCircle := 0
for i := 0; i < numThrows; i++ {
//a square with a side of length 2 centered at 0 has
//x and y range of -1 to 1
randX := rand.Float64()*2 - 1 //range -1 to 1
randY := rand.Float64()*2 - 1 //range -1 to 1
//distance from (0,0) = sqrt((x-0)^2+(y-0)^2)
dist := math.Hypot(randX, randY)
if dist < 1 { //circle with diameter of 2 has radius of 1
inCircle++
}
}
return 4 * float64(inCircle) / float64(numThrows)
}
func main() {
rand.Seed(uint64(time.Now().UnixNano()))
fmt.Println(getPi(10000))
fmt.Println(getPi(100000))
fmt.Println(getPi(1000000))
fmt.Println(getPi(10000000))
fmt.Println(getPi(100000000))
}</syntaxhighlight>
=={{header|Haskell}}==
<syntaxhighlight lang="haskell">import Control.Monad
import System.Random
results <- replicateM throws one_trial
return (4 * fromIntegral (sum results) / fromIntegral throws)
where
one_trial = do
rand_y <- randomRIO (-1, 1)
let dist :: Double
dist =
return (if dist < 1 then 1 else 0)</syntaxhighlight>
{{Out}}
<pre>Example:
Prelude System.Random Control.Monad> get_pi 10000
3.1352
Line 658 ⟶ 1,645:
3.15184
Prelude System.Random Control.Monad> get_pi 1000000
3.145024</pre>
Or, using foldM, and dropping sqrt:
<syntaxhighlight lang="haskell">import Control.Monad (foldM, (>=>))
import System.Random (randomRIO)
import Data.Functor ((<&>))
------- APPROXIMATION TO PI BY A MONTE CARLO METHOD ------
monteCarloPi :: Int -> IO Double
monteCarloPi n =
(/ fromIntegral n) . (4 *) . fromIntegral
<$> foldM go 0 [1 .. n]
where
rnd = randomRIO (0, 1) :: IO Double
go a _ = rnd >>= ((<&>) rnd . f a)
f a x y
| 1 > x ** 2 + y ** 2 = succ a
| otherwise = a
--------------------------- TEST -------------------------
main :: IO ()
main =
mapM_
(monteCarloPi >=> print)
[1000, 10000, 100000, 1000000]</syntaxhighlight>
{{Out}}
For example:
<pre>3.244
3.1116
3.14116
3.141396</pre>
=={{header|HicEst}}==
<
inside = 0
DO i = 1, samples
Line 672 ⟶ 1,691:
WRITE(ClipBoard) Pi(1E5) ! 3.14204
WRITE(ClipBoard) Pi(1E6) ! 3.141672
WRITE(ClipBoard) Pi(1E7) ! 3.1412856</
=={{header|Icon}} and {{header|Unicon}}==
<
every t := 10 ^ ( 5 to 9 ) do
printf("Rounds=%d Pi ~ %r\n",t,getPi(t))
Line 688 ⟶ 1,707:
incircle +:= 1
return 4 * incircle / rounds
end</
{{libheader|Icon Programming Library}}
Line 702 ⟶ 1,721:
=={{header|J}}==
'''Explicit Solution:'''
<
4* y%~ +/ 1>: %: +/ *: <: +: (2,y) ?@$ 0
)</
'''Tacit Solution:'''
<
'''Examples:'''
<
3.1426
piMC 10^i.7
4 2.8 3.24 3.168 3.1432 3.14256 3.14014</
'''Alternative Tacit Solution:'''
<syntaxhighlight lang="j">pimct=. (4 * +/ % #)@:(1 >: |)@:(? j. ?)@:($&0)"0
(,. pimct) 10 ^ 3 + i.6
1000 3.168
10000 3.122
100000 3.13596
1e6 3.1428
1e7 3.14158
1e8 3.14154</syntaxhighlight>
=={{header|Java}}==
<
public static void main(String[] args) {
System.out.println(getPi(10000));
Line 741 ⟶ 1,771:
return 4.0 * inCircle / numThrows;
}
}</
{{out}}
3.1396
Line 749 ⟶ 1,779:
3.14168604
{{works with|Java|8+}}
<
import java.util.stream.IntStream;
Line 792 ⟶ 1,822:
return (4.0 * inCircle) / numThrows;
}
}</
{{out}}
3.1556
Line 801 ⟶ 1,831:
=={{header|JavaScript}}==
===ES5===
<syntaxhighlight lang="javascript">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;
}
Line 818 ⟶ 1,851:
console.log(mcpi(100000));
console.log(mcpi(1000000));
console.log(mcpi(10000000));</
<pre>3.168
3.1396
Line 826 ⟶ 1,859:
</pre>
===ES6===
<syntaxhighlight lang="javascript">(() => {
"use strict";
// --- APPROXIMATION OF PI BY A MONTE CARLO METHOD ---
// monteCarloPi :: Int -> Float
const [x, y] = [rnd(), rnd()];
return (x ** 2) + (y ** 2) < 1 ? (
1 + a
) : a;
}, 0) / n;
// --------------------- GENERIC ---------------------
// enumFromTo :: Int -> Int -> [Int]
const enumFromTo = m =>
n => Array.from({
length: 1 + n - m
}, (_, i) => m + i);
// rnd :: () -> Float
const rnd = Math.random;
// ---------------------- TEST -----------------------
// From 1000 samples to 10E7 samples
return enumFromTo(3)(7).forEach(x => {
const nSamples = 10 ** x;
console.log(
`${nSamples} samples: ${monteCarloPi(nSamples)}`
);
});
})();</syntaxhighlight>
{{Out}} For example:
<pre>1000 samples: 3.064
10000 samples: 3.1416
100000 samples: 3.14756
1000000 samples: 3.142536
10000000 samples: 3.142808</pre>
=={{header|jq}}==
'''Adapted from [[#Wren|Wren]]'''
{{works with|jq}}
'''Works with gojq, the Go implementation of jq'''
jq does not have a built-in PRNG so we will use /dev/urandom
as a source of entropy by invoking jq as follows:
<syntaxhighlight lang="sh"># In case gojq is used, trim leading 0s:
function prng {
cat /dev/urandom | tr -cd '0-9' | fold -w 10 | sed 's/^0*\(.*\)*\(.\)*$/\1\2/'
}
prng | jq -nMr -f program.jq</syntaxhighlight>
'''program.jq'''
<syntaxhighlight lang="jq">def lpad($len): tostring | ($len - length) as $l | (" " * $l)[:$l] + .;
def percent: "\(100000 * . | round / 1000)%";
def pi: 4* (1|atan);
def rfloat: input/1E10;
def mcPi:
. as $n
| reduce range(0; $n) as $i (0;
rfloat as $x
| rfloat as $y
| if ($x*$x + $y*$y <= 1) then . + 1 else . end)
| 4 * . / $n ;
"Iterations -> Approx Pi -> Error",
"---------- ---------- ------",
( pi as $pi
| range(1; 7)
| pow(10;.) as $p
| ($p | mcPi) as $mcpi
| ((($pi - $mcpi)|length) / $pi) as $error
| "\($p|lpad(10)) \($mcpi|lpad(10)) \($error|percent|lpad(6))" )</syntaxhighlight>
{{out}}
<pre>
Iterations -> Approx Pi -> Error
---------- ---------- ------
10
1000
10000
100000
1000000
</pre>
=={{header|Jsish}}==
From Javascript ES5 entry, with PRNG seeded during unit testing for reproducibility.
<syntaxhighlight lang="javascript">/* Monte Carlo methods, in Jsish */
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;
}
if (Interp.conf('unitTest')) {
Math.srand(0);
; mcpi(1000);
; mcpi(10000);
; mcpi(100000);
; mcpi(1000000);
}
/*
=!EXPECTSTART!=
mcpi(1000) ==> 3.108
mcpi(10000) ==> 3.1236
mcpi(100000) ==> 3.13732
mcpi(1000000) ==> 3.142124
=!EXPECTEND!=
*/</syntaxhighlight>
{{out}}
<pre>prompt$ jsish -u monteCarlos.jsi
[PASS] monteCarlos.jsi</pre>
=={{header|Julia}}==
<syntaxhighlight lang="julia">using Printf
function monteπ(n)
s = count(rand() ^ 2 + rand() ^ 2 < 1 for _ in 1:n)
return 4s / n
end
for n in 10 .^ (3:8)
p = monteπ(n)
println("$(lpad(n, 9)): π ≈ $(lpad(p, 10)), pct.err = ", @sprintf("%2.5f%%", 100 * abs(p - π) / π))
end</syntaxhighlight>
{{out}}
<pre> 1000: π ≈ 3.224, pct.err = 0.02623%
10000: π ≈ 3.1336, pct.err = 0.254%
100000: π ≈ 3.13468, pct.err = 0.220%
1000000: π ≈ 3.14156, pct.err = 0.001%
10000000: π ≈ 3.1412348, pct.err = 0.011%
100000000: π ≈ 3.14123216, pct.err = 0.011%</pre>
=={{header|K}}==
<
sim 10000
Line 856 ⟶ 2,024:
sim'10^!8
4 2.8 3.4 3.072 3.1212 3.14104 3.14366 3.1413</
=={{header|
<syntaxhighlight lang="scala">// version 1.1.0
fun mcPi(n: Int): Double {
var inside = 0
(1..n).forEach {
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
}
}</syntaxhighlight>
Sample output:
{{out}}
<pre>
Iterations -> Approx Pi -> Error%
---------- ---------- ------
100000 -> 3.14468000 -> 0.0983
1000000 -> 3.13982000 -> 0.0564
10000000 -> 3.14182040 -> 0.0072
100000000 -> 3.14160244 -> 0.0003
</pre>
=={{header|Logo}}==
<
to square :n
output :n * :n
Line 927 ⟶ 2,081:
show sim 100000 10000 ; 3.145
show sim 1000000 10000 ; 3.140828
</syntaxhighlight>
=={{header|LSL}}==
To test it yourself; rez a box on the ground, and add the following as a New Script.
(Be prepared to wait... LSL can be slow, but the Servers are typically running thousands of scripts in parallel so what do you expect?)
<
integer iMAX_SAMPLE_POWER = 6;
default {
Line 953 ⟶ 2,107:
llOwnerSay("Done.");
}
}</
{{out}}
<pre>Estimating Pi (3.141593)
Line 966 ⟶ 2,120:
=={{header|Lua}}==
<
math.randomseed( os.time() )
Line 982 ⟶ 2,136:
print( MonteCarlo( 100000 ) )
print( MonteCarlo( 1000000 ) )
print( MonteCarlo( 10000000 ) )</
{{out}}
<pre>3.1436
Line 989 ⟶ 2,143:
3.1420188</pre>
=={{header|Mathematica}}/{{header|Wolfram Language}}==
We define a function with variable sample size:
<syntaxhighlight lang="mathematica">MonteCarloPi[samplesize_Integer] := N[4Mean[If[# > 1, 0, 1] & /@ Norm /@ RandomReal[1, {samplesize, 2}]]]</syntaxhighlight>
Example (samplesize=10,100,1000,....10000000):
<syntaxhighlight lang="mathematica">{#, MonteCarloPi[#]} & /@ (10^Range[1, 7]) // Grid</syntaxhighlight>
gives back:
<pre>10 3.2
100 3.16
1000 3.152
Line 1,006 ⟶ 2,155:
100000 3.14872
1000000 3.1408
10000000 3.14134</pre>
<syntaxhighlight lang="mathematica">monteCarloPi = 4. Mean[UnitStep[1 - Total[RandomReal[1, {2, #}]^2]]] &;
monteCarloPi /@ (10^Range@6)</syntaxhighlight>
A less elegant way to solve the problem, is to imagine a (well-trained) monkey, throwing a number of darts at a dartboard.
The darts land randomly on the board, at different x and y coordinates. We want to know how many darts land inside the circle. We then guess Pi by dividing the total number of darts inside the circle by the total number of darts thrown (assuming they all hit the square board), and multiplying the whole lot by 4.
We create a function ''MonkeyDartsPi'', which can take a variable number of throws as input:
<syntaxhighlight lang="wolfram language">MonkeyDartsPi[numberOfThrows_] := (
xyCoordinates = RandomReal[{0, 1}, {numberOfThrows, 2}];
InsideCircle = Length[Select[Total[xyCoordinates^2, {2}],#<=1&]] ;
4*N[InsideCircle / Length[xyCoordinates],1+Log10[numberOfThrows]])</syntaxhighlight>
We do several runs with a larger number of throws each time, increasing by powers of 10.
<syntaxhighlight lang="wolfram language">Grid[Table[{n, MonkeyDartsPi[n]}, {n, 10^Range[7]} ], Alignment -> Left]</syntaxhighlight>
We see that as the number of throws increases, we get closer to the value of Pi:
<pre>10 2.8
100 3.20
1000 3.176
10000 3.1356
100000 3.13700
1000000 3.142624
10000000 3.1416328</pre>
=={{header|MATLAB}}==
Line 1,020 ⟶ 2,188:
Minimally Vectorized:
<
%The square has a sides of length 2, which means the circle has radius
Line 1,036 ⟶ 2,204:
end
</syntaxhighlight>
Completely Vectorized:
<
piEstimate = 4*sum( sum(rand(numDarts,2).^2,2) <= 1 )/numDarts;
end</
{{out}}
<
ans =
3.141512000000000</
=={{header|Maxima}}==
<
approx_pi(n):= block(
[x: random_continuous_uniform(0, 1, n),
Line 1,061 ⟶ 2,230:
4*cin/n);
float(approx_pi(100));</
=={{header|MAXScript}}==
Line 1,082 ⟶ 2,251:
=={{header|МК-61/52}}==
<syntaxhighlight lang="text">П0 П1 0 П4 СЧ x^2 ^ СЧ x^2 +
1 - x<0 15 КИП4 L0 04 ИП4 4 *
ИП1 / С/П</
''Example:'' for n = ''
=={{header|Nim}}==
<
randomize()
proc pi(nthrows: float): float =
var inside = 0.0
for i in 1..int64(nthrows):
if hypot(
for n in [10e4, 10e6, 10e7, 10e8]:
echo pi(n)</
{{out}}
<pre>3.15336
Line 1,108 ⟶ 2,278:
=={{header|OCaml}}==
<
let rec helper i count =
if i = throws then count
Line 1,119 ⟶ 2,289:
else
helper (i+1) count
in float (4 * helper 0 0) /. float throws</
Example:
# get_pi 10000;;
Line 1,134 ⟶ 2,304:
=={{header|Octave}}==
<
in_circle = 0;
for samp = 1:samples
Line 1,149 ⟶ 2,319:
disp(montepi(l));
l *= 10;
endwhile</
Since it runs slow, I've stopped it at the second iteration, obtaining:
Line 1,157 ⟶ 2,327:
=== Much faster implementation ===
<
function result = montepi(n)
result = sum(rand(1,n).^2+rand(1,n).^2<1)/n*4;
endfunction
</syntaxhighlight>
=={{header|PARI/GP}}==
<
A hundred million tests (about a minute) yielded 3.14149000, slightly more precise (and round!) than would have been expected. A million gave 3.14162000 and a thousand 3.14800000.
=={{header|Pascal}}==
{{libheader|Math}}
<
uses
Line 1,198 ⟶ 2,368:
writeln (10**i, ' samples give ', MC_Pi(i):7:5, ' as pi.');
end.
</syntaxhighlight>
{{out}}
<pre>:> ./MonteCarlo
Line 1,209 ⟶ 2,379:
=={{header|Perl}}==
<syntaxhighlight lang="perl">sub pi {
my $nthrows = shift;
my $inside = 0;
foreach (1 .. $nthrows) {
my $x = rand() * 2 - 1
if (sqrt($x*$x + $y*$y) < 1) {
$inside++;
Line 1,223 ⟶ 2,392:
}
printf "%9d: %07f\n", $_, pi($_)
{{out}}
<pre>
10000: 3.132000
1000000: 3.141596
</pre>
=={{header|
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">N</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">100</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">6</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">inside</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">N</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">x</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">rand</span><span style="color: #0000FF;">(</span><span style="color: #000000;">N</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">y</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">rand</span><span style="color: #0000FF;">(</span><span style="color: #000000;">N</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">inside</span> <span style="color: #0000FF;">+=</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">x</span><span style="color: #0000FF;">*</span><span style="color: #000000;">x</span><span style="color: #0000FF;">+</span><span style="color: #000000;">y</span><span style="color: #0000FF;">*</span><span style="color: #000000;">y</span><span style="color: #0000FF;"><</span><span style="color: #000000;">N</span><span style="color: #0000FF;">*</span><span style="color: #000000;">N</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #7060A8;">pp</span><span style="color: #0000FF;">({</span><span style="color: #000000;">N</span><span style="color: #0000FF;">,</span><span style="color: #000000;">4</span><span style="color: #0000FF;">*</span><span style="color: #000000;">inside</span><span style="color: #0000FF;">/</span><span style="color: #000000;">N</span><span style="color: #0000FF;">})</span>
<span style="color: #000000;">N</span> <span style="color: #0000FF;">*=</span> <span style="color: #000000;">10</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
{100,3.2}
{1000
{10000
{100000,3.13996}
{1000000,3.141856}
{10000000,3.1415728}
</pre>
=={{header|PHP}}==
<syntaxhighlight lang="php"><?
$loop = 1000000; # loop to 1,000,000
$count = 0;
Line 1,259 ⟶ 2,434:
}
echo "loop=".number_format($loop).", count=".number_format($count).", pi=".($count/$loop*4);
?></
{{out}}
<pre>loop=1,000,000, count=785,462, pi=3.141848</pre>
=={{header|Picat}}==
Some general Monte Carlo simulators. <code>N</code> is the number of runs, <code>F</code> is the simulation function.
===Using while loop===
<syntaxhighlight lang="text">
sim1(N, F) = C =>
C = 0,
I = 0,
while (I <= N)
C := C + apply(F),
I := I + 1
end.</syntaxhighlight>
===List comprehension===
This is simpler, but slightly slower than using <code>while</code> loop.
<syntaxhighlight lang="picat">sim2(N, F) = sum([apply(F) : _I in 1..N]).</syntaxhighlight>
===Recursion===
<syntaxhighlight lang="picat">sim_rec(N,F) = S =>
sim_rec(N,N,F,0,S).
sim_rec(0,_N,_F,S,S).
sim_rec(C,N,F,S0,S) :-
S1 = S0 + apply(F),
sim_rec(C-1,N,F,S1,S).</syntaxhighlight>
===Test===
Of the three different MC simulators, <code>sim_rec/2</code> (using recursion) is slightly faster than the other two (<code>sim1/2</code> and <code>sim2/2</code>) which have about the same speed.
<syntaxhighlight lang="picat">go =>
foreach(N in 0..7)
sim_pi(10**N)
end,
nl.
% The specific pi simulation
sim_pi(N) =>
Inside = sim(N,pi_f),
MyPi = 4.0*Inside/N,
Pi = math.pi,
println([n=N, myPi=MyPi, diff=Pi-MyPi]).
% The simulation function:
% returns 1 if success, 0 otherwise
pi_f() = cond(frand()**2 + frand()**2 <= 1, 1, 0).</syntaxhighlight>
{{out}}
<pre>[n = 1,myPi = 4.0,diff = -0.858407346410207]
[n = 10,myPi = 3.2,diff = -0.058407346410207]
[n = 100,myPi = 3.12,diff = 0.021592653589793]
[n = 1000,myPi = 3.152,diff = -0.010407346410207]
[n = 10000,myPi = 3.1672,diff = -0.025607346410207]
[n = 100000,myPi = 3.13888,diff = 0.002712653589793]
[n = 1000000,myPi = 3.14192,diff = -0.000327346410207]
[n = 10000000,myPi = 3.1408988,diff = 0.000693853589793]</pre>
=={{header|PicoLisp}}==
<
(let (Dim (** 10 Scl) Dim2 (* Dim Dim) Pi 0)
(do (* 4 Dim)
Line 1,273 ⟶ 2,501:
(for N 6
(prinl (carloPi N)) )</
{{out}}
<pre>3.4
Line 1,284 ⟶ 2,512:
=={{header|PowerShell}}==
{{works with|PowerShell|2}}
<
$InCircle = 0
for ($i = 0; $i -lt $Iterations; $i++) {
Line 1,300 ⟶ 2,528:
| Add-Member -PassThru NoteProperty Pi $Pi `
| Add-Member -PassThru NoteProperty "% Difference" $Diff
}</
This returns a custom object with appropriate properties which automatically enables a nice tabular display:
<pre>PS Home:\> 10,100,1e3,1e4,1e5,1e6 | ForEach-Object { Get-Pi $_ }
Line 1,312 ⟶ 2,540:
100000 3,14712 0,1759409006731298209938938800
1000000 3,141364 0,0072782698142600895432451100</pre>
=={{header|Python}}==
Line 1,353 ⟶ 2,547:
One use of the "sum" function is to count how many times something is true (because True = 1, False = 0):
<
>>> throws = 1000
>>> 4.0 * sum(math.hypot(*[random.random()*2-1
Line 1,368 ⟶ 2,562:
for q in [0,1]]) < 1
for p in xrange(throws)) / float(throws)
3.1415666400000002</
===As a program using a function===
<
from random import random
from math import hypot
Line 1,389 ⟶ 2,583:
for n in [10**4, 10**6, 10**7, 10**8]:
print "%9d: %07f" % (n, pi(n))
</syntaxhighlight>
===Faster implementation using Numpy===
<
import numpy as np
n = input('Number of samples: ')
print np.sum(np.random.rand(n)**2+np.random.rand(n)**2<1)/float(n)*4
</syntaxhighlight>
=={{header|Quackery}}==
{{trans|Forth}}
<syntaxhighlight lang="quackery"> [ $ "bigrat.qky" loadfile ] now!
[ [ 64 bit ] constant
dup random dup *
over random dup * +
swap dup * < ] is hit ( --> b )
[ 0 swap times
[ hit if 1+ ] ] is sims ( n --> n )
[ dup echo say " trials "
dup sims 4 *
swap 20 point$ echo$ cr ] is trials ( n --> )
' [ 10 100 1000 10000 100000 1000000 ] witheach trials</syntaxhighlight>
{{out}}
<pre>10 trials 2.8
100 trials 3.2
1000 trials 3.172
10000 trials 3.1484
100000 trials 3.1476
1000000 trials 3.142256</pre>
=={{header|R}}==
<
monteCarloPi <- function(samples) {
x <- runif(samples, -1, 1) # for big samples, you need a lot of memory!
Line 1,426 ⟶ 2,649:
print(monteCarloPi(1e4))
print(monteCarloPi(1e5))
print(monteCarlo2Pi(1e7))</
=={{header|Racket}}==
<
(define (in-unit-circle? x y) (<= (sqrt (+ (sqr x) (sqr y))) 1))
Line 1,460 ⟶ 2,683:
;; to see how it looks as a decimal we can exact->inexact it
(let ((mc (monte-carlo 10000000 1000000 random-point-in-2x2-square in-unit-circle? passed:samples->pi)))
(printf "exact = ~a~%inexact = ~a~%(pi - guess) = ~a~%" mc (exact->inexact mc) (- pi mc)))</
{{out}}
<pre>1000000 samples of 10000000: 785763 passed -> 785763/250000
Line 1,477 ⟶ 2,700:
A little more Racket-like is the use of an iterator (in this case '''for/fold'''),
which is clearer than an inner function:
<
(define (in-unit-circle? x y) (<= (sqrt (+ (sqr x) (sqr y))) 1))
;; Good idea made in another task that:
Line 1,504 ⟶ 2,727:
;; to see how it looks as a decimal we can exact->inexact it
(let ((mc (monte-carlo/2 10000000 1000000 random-point-in-unit-square in-unit-circle? passed:samples->pi)))
(printf "exact = ~a~%inexact = ~a~%(pi - guess) = ~a~%" mc (exact->inexact mc) (- pi mc)))</
[Similar output]
=={{header|Raku}}==
(formerly Perl 6)
{{works with|rakudo|2015-09-24}}
We'll consider the upper-right quarter of the unitary disk centered at the origin. Its area is <math>\pi \over 4</math>.
<syntaxhighlight lang="raku" line>my @random_distances = ([+] rand**2 xx 2) xx *;
sub approximate_pi(Int $n) {
4 * @random_distances[^$n].grep(* < 1) / $n
}
say "Monte-Carlo π approximation:";
say "$_ iterations: ", approximate_pi $_
for 100, 1_000, 10_000;
</syntaxhighlight>
{{out}}
<pre>Monte-Carlo π approximation:
100 iterations: 2.88
1000 iterations: 3.096
10000 iterations: 3.1168</pre>
We don't really need to write a function, though. A lazy list would do:
<syntaxhighlight lang="raku" line>my @pi = ([\+] 4 * (1 > [+] rand**2 xx 2) xx *) Z/ 1 .. *;
say @pi[10, 1000, 10_000];</syntaxhighlight>
=={{header|REXX}}==
A specific─purpose commatizer function is included to format the number of iterations.
<syntaxhighlight lang="rexx">/*REXX program computes and displays the value of pi÷4 using the Monte Carlo algorithm*/
parse arg times chunk digs r? . /*does user want a specific number? */
if times=='' | times=="," then times= 5e12 /*five trillion should do it, hopefully*/
/* [↓] pi meant to line─up with a SAY.*/
pi= 3.141592653589793238462643383279502884197169399375105820974944592307816406
pi= strip( left(pi, digs + length(.) ) ) /*obtain length of pi to what's wanted.*/
say 'scale: 1·234567890123456789012345678901234567890123456789012345678901234567890123'
say /*
say 'true pi= ' pi"+" /*we might as well brag about true pi.*/
say
limit = 10000 - 1
limitSq = limit **2
accuracy= 0
@reps= 'repetitions: Monte Carlo pi is' /*a handy─dandy short literal for a SAY*/
!= 0
do j=1 for times % chunk
if random(, limit)**2 + random(, limit)**2 <= limitSq then != ! + 1
reps= chunk * j /*calculate the number of repetitions. */
_= compare(4*! / reps, pi) /*compare apples and ··· crabapples. */
if _<=accuracy then iterate /*Not better accuracy? Keep truckin'. */
say right(commas(reps), 20) @reps 'accurate to' _-1 "places." /*─1≡dec. point*/
accuracy= _ /*use this accuracy for next baseline. */
end /*j*/
exit 0 /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
commas: procedure;
{{out|output|text= when using the default input:}}
<pre>
1 2 3 4 5 6 7
scale: 1·234567890123456789012345678901234567890123456789012345678901234567890123
true pi= 3.141592653589793238462643383279502884197169399375105820974944592307816406+
10,390,000 repetitions: Monte Carlo pi is accurate to 9 places.
</pre>
For more example runs using REXX, see the [https://rosettacode.org/wiki/Talk:Monte_Carlo_methods ''discussion''] page.
=={{header|Ring}}==
<
decimals(8)
see "monteCarlo(1000) = " + monteCarlo(1000) + nl
Line 1,569 ⟶ 2,823:
t = (4 * n) / t
return t
</syntaxhighlight>
Output:
<pre>
Line 1,575 ⟶ 2,829:
monteCarlo(10000) = 3.00320000
monteCarlo(100000) = 2.99536000
</pre>
=={{header|RPL}}==
≪ 0
1 3 PICK '''START'''
RAND SQ RAND SQ + 1 < +
'''NEXT'''
SWAP / 4 *
≫ '<span style="color:blue">MCARL</span>' STO
100 <span style="color:blue">MCARL</span>
1000 <span style="color:blue">MCARL</span>
10000 <span style="color:blue">MCARL</span>
100000 <span style="color:blue">MCARL</span>
{{out}}
<pre>
4: 3.2
3: 3.084
2: 3.1684
1: 3.14154
</pre>
=={{header|Ruby}}==
<
times_inside = throws.times.count {Math.hypot(rand, rand) <= 1.0}
4.0 * times_inside / throws
end
[1000, 10_000, 100_000, 1_000_000, 10_000_000].each do |n|
end</
{{out}}
<pre> 1000 samples: PI = 3.2
Line 1,593 ⟶ 2,866:
1000000 samples: PI = 3.145124
10000000 samples: PI = 3.1414788</pre>
=={{header|Rust}}==
<syntaxhighlight lang="rust">extern crate rand;
use rand::Rng;
use std::f64::consts::PI;
// `(f32, f32)` would be faster for some RNGs (including `rand::thread_rng` on 32-bit platforms
// and `rand::weak_rng` as of rand v0.4) as `next_u64` combines two `next_u32`s if not natively
// supported by the RNG. It would less accurate however.
fn is_inside_circle((x, y): (f64, f64)) -> bool {
x * x + y * y <= 1.0
}
fn simulate<R: Rng>(rng: &mut R, samples: usize) -> f64 {
let mut count = 0;
for _ in 0..samples {
if is_inside_circle(rng.gen()) {
count += 1;
}
}
(count as f64) / (samples as f64)
}
fn main() {
let mut rng = rand::weak_rng();
println!("Real pi: {}", PI);
for samples in (3..9).map(|e| 10_usize.pow(e)) {
let estimate = 4.0 * simulate(&mut rng, samples);
let deviation = 100.0 * (1.0 - estimate / PI).abs();
println!("{:9}: {:<11} dev: {:.5}%", samples, estimate, deviation);
}
}</syntaxhighlight>
{{out}}
<pre>Real pi: 3.141592653589793
1000: 3.212 dev: 2.24114%
10000: 3.156 dev: 0.45860%
100000: 3.14112 dev: 0.01505%
1000000: 3.14122 dev: 0.01186%
10000000: 3.1408112 dev: 0.02487%
100000000: 3.14186092 dev: 0.00854%</pre>
=={{header|Scala}}==
<
private val random = new scala.util.Random
Line 1,621 ⟶ 2,937:
}
}
}</
{{out}}
<pre>10000 simulations; pi estimation: 3.1492
Line 1,630 ⟶ 2,946:
=={{header|Seed7}}==
<
include "float.s7i";
Line 1,655 ⟶ 2,971:
writeln(" 10000000: " <& pi( 10000000) digits 5);
writeln("100000000: " <& pi(100000000) digits 5);
end func;</
{{out}}
Line 1,665 ⟶ 2,981:
100000000: 3.14159
</pre>
=={{header|SequenceL}}==
First solution is serial due to the use of random numbers. Will always give the same result for a given n and seed
<syntaxhighlight lang="sequencel">
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);
</syntaxhighlight>
The second solution will run in parallel. It will also always give the same result for a given n and seed. (Note, the function monteCarloHelper is the same in both versions).
<syntaxhighlight lang="sequencel">
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);
</syntaxhighlight>
=={{header|Sidef}}==
<syntaxhighlight lang="ruby">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))
}</syntaxhighlight>
{{out}}
<pre>
100: 3.320000
1000: 3.120000
10000: 3.169600
100000: 3.138920
1000000: 3.142344
</pre>
=={{header|SparForte}}==
As a structured script.
<syntaxhighlight lang="ada">#!/usr/local/bin/spar
pragma annotate( summary, "monte" )
@( description, "A Monte Carlo Simulation is a way of approximating the" )
@( description, "value of a function where calculating the actual value is" )
@( description, "difficult or impossible. It uses random sampling to define" )
@( description, "constraints on the value and then makes a sort of 'best" )
@( description, "guess.'" )
@( description, "" )
@( description, "Write a function to run a simulation like this with a" )
@( description, "variable number of random points to select. Also, show the" )
@( description, "results of a few different sample sizes. For software" )
@( description, "where the number pi is not built-in, we give pi to a couple" )
@( description, "of digits: 3.141592653589793238462643383280 " )
@( see_also, "http://rosettacode.org/wiki/Monte_Carlo_methods" )
@( author, "Ken O. Burtch" );
pragma license( unrestricted );
pragma restriction( no_external_commands );
procedure monte is
function pi_estimate (throws : positive) return float is
inside : natural := 0;
begin
for throw in 1..throws loop
if numerics.random ** 2 + numerics.random ** 2 <= 1.0 then
inside := @ + 1;
end if;
end loop;
return 4.0 * float (inside) / float (throws);
end pi_estimate;
begin
? " 1_000:" & strings.image (pi_estimate ( 1_000))
@ " 10_000:" & strings.image (pi_estimate ( 10_000))
@ " 100_000:" & strings.image (pi_estimate ( 100_000))
@ " 1_000_000:" & strings.image (pi_estimate ( 1_000_000));
end monte;</syntaxhighlight>
=={{header|Stata}}==
<syntaxhighlight lang="stata">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</syntaxhighlight>
=={{header|Swift}}==
{{trans|JavaScript}}
<
func mcpi(sampleSize size:Int) -> Double {
Line 1,692 ⟶ 3,146:
println(mcpi(sampleSize: 1000000))
println(mcpi(sampleSize: 10000000))
println(mcpi(sampleSize: 100000000))</
{{out}}
<pre>
Line 1,705 ⟶ 3,159:
=={{header|Tcl}}==
<
set i 0
set inside 0
Line 1,719 ⟶ 3,173:
foreach runs {1e2 1e4 1e6 1e8} {
puts "$runs => [pi $runs]"
}</
result
<pre>PI is approx 3.141592653589793
Line 1,729 ⟶ 3,183:
=={{header|Ursala}}==
<
#import flo
mcp "n" = times/4. div\float"n" (rep"n" (fleq/.5+ sqrt+ plus+ ~~ sqr+ minus/.5+ rand)?/~& plus/1.) 0.</
Here's a walk through.
* <code>mcp "n" = </code>... defines a function named <code>mcp</code> in terms of a dummy variable <code>"n"</code>, which will be the number of iterations used in the simulation
Line 1,750 ⟶ 3,204:
* The result of the division is quadrupled by <code>times/4.</code>.
test program:
<
pis = mcp* <10,100,1000,10000,100000,1000000></
{{out}}
<pre><
Line 1,761 ⟶ 3,215:
3.144480e+00,
3.141668e+00></pre>
=={{header|Wren}}==
{{trans|Kotlin}}
{{libheader|Wren-fmt}}
<syntaxhighlight lang="wren">import "random" for Random
import "./fmt" for Fmt
var rand = Random.new()
var mcPi = Fn.new { |n|
var inside = 0
for (i in 1..n) {
var x = rand.float()
var y = rand.float()
if (x*x + y*y <= 1) inside = inside + 1
}
return 4 * inside / n
}
System.print("Iterations -> Approx Pi -> Error\%")
System.print("---------- ---------- ------")
var n = 1000
while (n <= 1e8) {
var pi = mcPi.call(n)
var err = (Num.pi - pi).abs / Num.pi * 100.0
Fmt.print("$9d -> $10.8f -> $6.4f", n, pi, err)
n = n * 10
}</syntaxhighlight>
{{out}}
Sample run:
<pre>
Iterations -> Approx Pi -> Error%
---------- ---------- ------
1000 -> 3.21200000 -> 2.2411
10000 -> 3.16720000 -> 0.8151
100000 -> 3.13944000 -> 0.0685
1000000 -> 3.14048000 -> 0.0354
10000000 -> 3.14191240 -> 0.0102
100000000 -> 3.14142320 -> 0.0054
</pre>
=={{header|XPL0}}==
<
code real RlOut=48;
Line 1,783 ⟶ 3,278:
RlOut(0, MontePi( 1_000_000)); CrLf(0);
RlOut(0, MontePi(100_000_000)); CrLf(0);
]</
{{out}}
Line 1,794 ⟶ 3,289:
=={{header|zkl}}==
<
inCircle:=0;
do(n){
Line 1,801 ⟶ 3,296:
}
4.0*inCircle/n
}</
Or, in a more functional style (using a reference for state info):
<
4.0 * (1).pump(n,Void,fcn(r){
x:=(0.0).random(1); y:=(0.0).random(1);
Line 1,809 ⟶ 3,304:
r
}.fp(Ref(0)) ).value/n;
}</
{{out}}
<pre>
|