Update all new Tasks

This commit is contained in:
Ingy döt Net 2015-02-20 09:02:09 -05:00
parent 00a190b0a6
commit 91df62d461
5697 changed files with 93386 additions and 804 deletions

View file

@ -0,0 +1,28 @@
{{Percolation Simulation}}
Let <math>v</math> be a vector of <math>n</math> values of either <tt>1</tt> or <tt>0</tt> where the probability of any
value being <tt>1</tt> is <math>p</math>, (and <tt>0</tt> is therefore <math>1-p</math>).
Define a run of <tt>1</tt>'s as being a group of consecutive <tt>1</tt>'s in the vector bounded
either by the limits of the vector or by a <tt>0</tt>. Let the number of runs in a
vector of length <math>n</math> be <math>R_n</math>.
The following vector has <math>R_{10} = 3</math>
<pre>
[1 1 0 0 0 1 0 1 1 1]
^^^ ^ ^^^^^
</pre>
Percolation theory states that
:<math>K(p) = \lim_{n\to\infty} R_n / n = p(1 - p)</math>
;Task
Any calculation of <math>R_n / n</math> for finite <math>n</math> is subject to randomness so should be
computed as the average of <math>t</math> runs, where <math>t \ge 100</math>.
For values of <math>p</math> of 0.1, 0.3, 0.5, 0.7, and 0.9, show the effect of varying <math>n</math>
on the accuracy of simulated <math>K(p)</math>.
Show your output here
;See also
* [http://mathworld.wolfram.com/s-Run.html s-Run] on Wolfram mathworld.

View file

@ -0,0 +1,2 @@
---
note: Percolation Simulations

View file

@ -0,0 +1,56 @@
#include <algorithm>
#include <random>
#include <vector>
#include <iostream>
#include <numeric>
#include <iomanip>
using VecIt = std::vector<int>::const_iterator ;
//creates vector of length n, based on probability p for 1
std::vector<int> createVector( int n, double p ) {
std::vector<int> result( n ) ;
std::random_device rd ;
std::mt19937 gen( rd( ) ) ;
std::uniform_real_distribution<> dis( 0 , 1 ) ;
for ( int i = 0 ; i < n ; i++ ) {
double number = dis( gen ) ;
if ( number <= p )
result[ i ] = 1 ;
else
result[ i ] = 0 ;
}
return result ;
}
//find number of 1 runs in the vector
int find_Runs( const std::vector<int> & numberVector ) {
int runs = 0 ;
VecIt found = numberVector.begin( ) ;
while ( ( found = std::find( found , numberVector.end( ) , 1 ) )
!= numberVector.end( ) ) {
runs++ ;
while ( found != numberVector.end( ) && ( *found == 1 ) )
std::advance( found , 1 ) ;
if ( found == numberVector.end( ) )
break ;
}
return runs ;
}
int main( ) {
std::cout << "t = 100\n" ;
std::vector<double> p_values { 0.1 , 0.3 , 0.5 , 0.7 , 0.9 } ;
for ( double p : p_values ) {
std::cout << "p = " << p << " , K(p) = " << p * ( 1 - p ) << std::endl ;
for ( int n = 10 ; n < 100000 ; n *= 10 ) {
std::vector<double> runsFound ;
for ( int i = 0 ; i < 100 ; i++ ) {
std::vector<int> ones_and_zeroes = createVector( n , p ) ;
runsFound.push_back( find_Runs( ones_and_zeroes ) / static_cast<double>( n ) ) ;
}
double average = std::accumulate( runsFound.begin( ) , runsFound.end( ) , 0.0 ) / runsFound.size( ) ;
std::cout << " R(" << std::setw( 6 ) << std::right << n << ", p) = " << average << std::endl ;
}
}
return 0 ;
}

View file

@ -0,0 +1,36 @@
#include <stdio.h>
#include <stdlib.h>
// just generate 0s and 1s without storing them
double run_test(double p, int len, int runs)
{
int r, x, y, i, cnt = 0, thresh = p * RAND_MAX;
for (r = 0; r < runs; r++)
for (x = 0, i = len; i--; x = y)
cnt += x < (y = rand() < thresh);
return (double)cnt / runs / len;
}
int main(void)
{
double p, p1p, K;
int ip, n;
puts( "running 1000 tests each:\n"
" p\t n\tK\tp(1-p)\t diff\n"
"-----------------------------------------------");
for (ip = 1; ip < 10; ip += 2) {
p = ip / 10., p1p = p * (1 - p);
for (n = 100; n <= 100000; n *= 10) {
K = run_test(p, n, 1000);
printf("%.1f\t%6d\t%.4f\t%.4f\t%+.4f (%+.2f%%)\n",
p, n, K, p1p, K - p1p, (K - p1p) / p1p * 100);
}
putchar('\n');
}
return 0;
}

View file

@ -0,0 +1,23 @@
import std.stdio, std.range, std.algorithm, std.random, std.math;
enum n = 100, p = 0.5, t = 500;
double meanRunDensity(in size_t n, in double prob) {
return n.iota.map!(_ => uniform01 < prob)
.array.uniq.sum / double(n);
}
void main() {
foreach (immutable p; iota(0.1, 1.0, 0.2)) {
immutable limit = p * (1 - p);
writeln;
foreach (immutable n2; iota(10, 16, 2)) {
immutable n = 2 ^^ n2;
immutable sim = t.iota.map!(_ => meanRunDensity(n, p))
.sum / t;
writefln("t=%3d, p=%4.2f, n=%5d, p(1-p)=%5.5f, " ~
"sim=%5.5f, delta=%3.1f%%", t, p, n, limit, sim,
limit ? abs(sim - limit) / limit * 100 : sim*100);
}
}
}

View file

@ -0,0 +1,59 @@
! loosely translated from python. We do not need to generate and store the entire vector at once.
! compilation: gfortran -Wall -std=f2008 -o thisfile thisfile.f08
program percolation_mean_run_density
implicit none
integer :: i, p10, n2, n, t
real :: p, limit, sim, delta
data n,p,t/100,0.5,500/
write(6,'(a3,a5,4a7)')'t','p','n','p(1-p)','sim','delta%'
do p10=1,10,2
p = p10/10.0
limit = p*(1-p)
write(6,'()')
do n2=10,15,2
n = 2**n2
sim = 0
do i=1,t
sim = sim + mean_run_density(n,p)
end do
sim = sim/t
if (limit /= 0) then
delta = abs(sim-limit)/limit
else
delta = sim
end if
delta = delta * 100
write(6,'(i3,f5.2,i7,2f7.3,f5.1)')t,p,n,limit,sim,delta
end do
end do
contains
integer function runs(n, p)
integer, intent(in) :: n
real, intent(in) :: p
real :: harvest
logical :: q
integer :: count, i
count = 0
q = .false.
do i=1,n
call random_number(harvest)
if (harvest < p) then
q = .true.
else
if (q) count = count+1
q = .false.
end if
end do
runs = count
end function runs
real function mean_run_density(n, p)
integer, intent(in) :: n
real, intent(in) :: p
mean_run_density = real(runs(n,p))/real(n)
end function mean_run_density
end program percolation_mean_run_density

View file

@ -0,0 +1,28 @@
import Control.Monad.Random
import Control.Applicative
import Text.Printf
import Control.Monad
import Data.Bits
data OneRun = OutRun | InRun deriving (Eq, Show)
randomList :: Int -> Double -> Rand StdGen [Int]
randomList n p = take n . map f <$> getRandomRs (0,1)
where f n = if (n > p) then 0 else 1
countRuns xs = fromIntegral . sum $
zipWith (\x y -> x .&. xor y 1) xs (tail xs ++ [0])
calcK :: Int -> Double -> Rand StdGen Double
calcK n p = (/ fromIntegral n) . countRuns <$> randomList n p
printKs :: StdGen -> Double -> IO ()
printKs g p = do
printf "p= %.1f, K(p)= %.3f\n" p (p * (1 - p))
forM_ [1..5] $ \n -> do
let est = evalRand (calcK (10^n) p) g
printf "n=%7d, estimated K(p)= %5.3f\n" (10^n::Int) est
main = do
x <- newStdGen
forM_ [0.1,0.3,0.5,0.7,0.9] $ printKs x

View file

@ -0,0 +1,15 @@
procedure main(A)
t := integer(A[2]) | 500
write(left("p",8)," ",left("n",8)," ",left("p(1-p)",10)," ",left("SimK(p)",10))
every (p := 0.1 | 0.3 | 0.5 | 0.7 | 0.9, n := 1000 | 2000 | 3000) do {
Ka := 0.0
every !t do {
every (v := "", !n) do v ||:= |((?0.1 > p,"0")|"1")
R := 0
v ? while tab(upto('1')) do R +:= (tab(many('1')), 1)
Ka +:= real(R)/n
}
write(left(p,8)," ",left(n,8)," ",left(p*(1-p),10)," ",left(Ka/t, 10))
}
end

View file

@ -0,0 +1,21 @@
NB. translation of python
NB. 'N P T' =: 100 0.5 500 NB. silliness
newv =: (> ?@(#&0))~ NB. generate a random binary vector. Use: N newv P
runs =: {: + [: +/ 1 0&E. NB. add the tail to the sum of 1 0 occurrences Use: runs V
mean_run_density =: [ %~ [: runs newv NB. perform experiment. Use: N mean_run_density P
main =: 3 : 0 NB.Usage: main T
T =. y
smoutput' T P N P(1-P) SIM DELTA%'
for_P. 10 %~ >: +: i. 5 do.
LIMIT =. (* -.) P
smoutput ''
for_N. 2 ^ 10 + +: i. 3 do.
SIM =. T %~ +/ (N mean_run_density P"_)^:(<T) 0
smoutput 4 5j2 6 6j3 6j3 4j1 ": T, P, N, LIMIT, SIM, SIM (100 * [`(|@:(- % ]))@.(0 ~: ])) LIMIT
end.
end.
EMPTY
)

View file

@ -0,0 +1,10 @@
sub R($n, $p) { [+] ((rand < $p) xx $n).squish }
say 't= ', constant t = 100;
for .1, .3 ... .9 -> $p {
say "p= $p, K(p)= {$p*(1-$p)}";
for 10, 100, 1000 -> $n {
printf " R(%6d, p)= %f\n", $n, t R/ [+] R($n, $p)/$n xx t
}
}

View file

@ -0,0 +1,17 @@
sub R {
my ($n, $p) = @_;
my $r = join '',
map { rand() < $p ? 1 : 0 } 1 .. $n;
0+ $r =~ s/1+//g;
}
use constant t => 100;
printf "t= %d\n", t;
for my $p (qw(.1 .3 .5 .7 .9)) {
printf "p= %f, K(p)= %f\n", $p, $p*(1-$p);
for my $n (qw(10 100 1000)) {
my $r; $r += R($n, $p) for 1 .. t; $r /= $n;
printf " R(n, p)= %f\n", $r / t;
}
}

View file

@ -0,0 +1,24 @@
from __future__ import division
from random import random
from math import fsum
n, p, t = 100, 0.5, 500
def newv(n, p):
return [int(random() < p) for i in range(n)]
def runs(v):
return sum((a & ~b) for a, b in zip(v, v[1:] + [0]))
def mean_run_density(n, p):
return runs(newv(n, p)) / n
for p10 in range(1, 10, 2):
p = p10 / 10
limit = p * (1 - p)
print('')
for n2 in range(10, 16, 2):
n = 2**n2
sim = fsum(mean_run_density(n, p) for i in range(t)) / t
print('t=%3i p=%4.2f n=%5i p(1-p)=%5.3f sim=%5.3f delta=%3.1f%%'
% (t, p, n, limit, sim, abs(sim - limit) / limit * 100 if limit else sim * 100))

View file

@ -0,0 +1 @@
Data source: http://rosettacode.org/wiki/Percolation/Mean_run_density

View file

@ -0,0 +1,32 @@
#lang racket
(require racket/fixnum)
(define t (make-parameter 100))
(define (Rn v)
(define (inner-Rn rv idx b-1)
(define b (fxvector-ref v idx))
(define rv+ (if (and (= b 1) (= b-1 0)) (add1 rv) rv))
(if (zero? idx) rv+ (inner-Rn rv+ (sub1 idx) b)))
(inner-Rn 0 (sub1 (fxvector-length v)) 0))
(define ((make-random-bit-vector p) n)
(for/fxvector
#:length n ((i n))
(if (<= (random) p) 1 0)))
(define (Rn/n l->p n) (/ (Rn (l->p n)) n))
(for ((p (in-list '(1/10 3/10 1/2 7/10 9/10))))
(define l->p (make-random-bit-vector p))
(define Kp (* p (- 1 p)))
(printf "p = ~a\tK(p) =\t~a\t~a~%" p Kp (real->decimal-string Kp 4))
(for ((n (in-list '(10 100 1000 10000))))
(define sum-Rn/n (for/sum ((i (in-range (t)))) (Rn/n l->p n)))
(define sum-Rn/n/t (/ sum-Rn/n (t)))
(printf "mean(R_~a/~a) =\t~a\t~a~%"
n n sum-Rn/n/t (real->decimal-string sum-Rn/n/t 4)))
(newline))
(module+ test
(require rackunit)
(check-eq? (Rn (fxvector 1 1 0 0 0 1 0 1 1 1)) 3))

View file

@ -0,0 +1,33 @@
proc randomString {length probability} {
for {set s ""} {[string length $s] < $length} {} {
append s [expr {rand() < $probability}]
}
return $s
}
# By default, [regexp -all] gives the number of times that the RE matches
proc runs {str} {
regexp -all {1+} $str
}
# Compute the mean run density
proc mrd {t p n} {
for {set i 0;set total 0.0} {$i < $t} {incr i} {
set run [randomString $n $p]
set total [expr {$total + double([runs $run])/$n}]
}
return [expr {$total / $t}]
}
# Parameter sweep with nested [foreach]
set runs 500
foreach p {0.10 0.30 0.50 0.70 0.90} {
foreach n {1024 4096 16384} {
set theory [expr {$p * (1 - $p)}]
set sim [mrd $runs $p $n]
set diffpc [expr {abs($theory-$sim)*100/$theory}]
puts [format "t=%d, p=%.2f, n=%5d, p(1-p)=%.3f, sim=%.3f, delta=%.2f%%" \
$runs $p $n $theory $sim $diffpc]
}
puts ""
}