LDP/LDP/guide/docbook/abs-guide/brownian.sh

124 lines
3.5 KiB
Bash
Raw Normal View History

2007-11-08 15:53:07 +00:00
#!/bin/bash
# brownian.sh
# Author: Mendel Cooper
# Reldate: 10/26/07
# License: GPL3
# ----------------------------------------------------------------
# This script models Brownian motion:
#+ the random wanderings of tiny particles in a fluid,
2008-03-13 13:24:45 +00:00
#+ as they are buffeted by random currents and collisions.
#+ This is colloquially known as the "Drunkard's Walk."
2007-11-08 15:53:07 +00:00
2008-03-13 13:24:45 +00:00
# It can also be considered as a stripped-down simulation of a
2007-11-08 15:53:07 +00:00
#+ Galton Board, a slanted board with a pattern of pegs,
#+ down which rolls a succession of marbles, one at a time.
#+ At the bottom is a row of slots or catch basins in which
2008-03-13 13:24:45 +00:00
#+ the marbles come to rest at the end of their journey.
2007-11-08 15:53:07 +00:00
# Think of it as a kind of bare-bones Pachinko game.
# As you see by running the script,
#+ most of the marbles cluster around the center slot.
2008-03-13 13:24:45 +00:00
#+ This is consistent with the expected binomial distribution.
# As a Galton Board simulation, the script
2007-11-08 15:53:07 +00:00
#+ disregards such parameters as
#+ board tilt-angle, rolling friction of the marbles,
#+ angles of impact, and elasticity of the pegs.
2008-05-09 18:58:34 +00:00
# To what extent does this affect the accuracy of the simulation?
2007-11-08 15:53:07 +00:00
# ----------------------------------------------------------------
2008-05-09 18:58:34 +00:00
PASSES=500 # Number of particle interactions / marbles.
ROWS=10 # Number of "collisions" (or horiz. peg rows).
RANGE=3 # 0 - 2 output range from $RANDOM.
POS=0 # Left/right position.
RANDOM=$$ # Seeds the random number generator from PID
#+ of script.
2007-11-08 15:53:07 +00:00
declare -a Slots # Array holding cumulative results of passes.
2008-03-13 13:24:45 +00:00
NUMSLOTS=21 # Number of slots at bottom of board.
2007-11-08 15:53:07 +00:00
2008-05-09 18:58:34 +00:00
Initialize_Slots () { # Zero out all elements of the array.
2007-11-08 15:53:07 +00:00
for i in $( seq $NUMSLOTS )
do
Slots[$i]=0
done
echo # Blank line at beginning of run.
}
Show_Slots () {
2011-08-29 23:59:19 +00:00
echo; echo
2007-11-08 15:53:07 +00:00
echo -n " "
for i in $( seq $NUMSLOTS ) # Pretty-print array elements.
do
2008-05-09 18:58:34 +00:00
printf "%3d" ${Slots[$i]} # Allot three spaces per result.
2007-11-08 15:53:07 +00:00
done
echo # Row of slots:
echo " |__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|"
2011-08-29 23:59:19 +00:00
echo " ||"
2007-11-08 15:53:07 +00:00
echo # Note that if the count within any particular slot exceeds 99,
#+ it messes up the display.
# Running only(!) 500 passes usually avoids this.
}
Move () { # Move one unit right / left, or stay put.
2008-03-13 13:24:45 +00:00
Move=$RANDOM # How random is $RANDOM? Well, let's see ...
2007-11-08 15:53:07 +00:00
let "Move %= RANGE" # Normalize into range of 0 - 2.
case "$Move" in
0 ) ;; # Do nothing, i.e., stay in place.
1 ) ((POS--));; # Left.
2 ) ((POS++));; # Right.
2008-03-13 13:24:45 +00:00
* ) echo -n "Error ";; # Anomaly! (Should never occur.)
2007-11-08 15:53:07 +00:00
esac
}
Play () { # Single pass (inner loop).
i=0
2008-07-20 23:16:47 +00:00
while [ "$i" -lt "$ROWS" ] # One event per row.
2007-11-08 15:53:07 +00:00
do
Move
((i++));
done
SHIFT=11 # Why 11, and not 10?
let "POS += $SHIFT" # Shift "zero position" to center.
(( Slots[$POS]++ )) # DEBUG: echo $POS
2011-08-29 23:59:19 +00:00
# echo -n "$POS "
2007-11-08 15:53:07 +00:00
}
Run () { # Outer loop.
p=0
2008-03-13 13:24:45 +00:00
while [ "$p" -lt "$PASSES" ]
2007-11-08 15:53:07 +00:00
do
Play
(( p++ ))
POS=0 # Reset to zero. Why?
done
}
# --------------
# main ()
Initialize_Slots
Run
Show_Slots
# --------------
exit $?
# Exercises:
# ---------
# 1) Show the results in a vertical bar graph, or as an alternative,
#+ a scattergram.
# 2) Alter the script to use /dev/urandom instead of $RANDOM.
2008-03-13 13:24:45 +00:00
# Will this make the results more random?
2011-08-29 23:59:19 +00:00
# 3) Provide some sort of "animation" or graphic output
# for each marble played.