Marble drop

Marble drop preview image

1 collaborator

Default-person Paolo Gaudiano (Author)

Tags

(This model has yet to be categorized with any tags)
Visible to everyone | Changeable by everyone
Model was written in NetLogo 6.2.2 • Viewed 61 times • Downloaded 5 times • Run 0 times
Download the 'Marble drop' modelDownload this modelEmbed this model

Do you have questions or comments about this model? Ask them here! (You'll first need to log in.)


WHAT IS IT?

This is a simulation of falling marbles to illustrate certain points about statistics and modeling.

HOW IT WORKS

Marbles fall from the top and bounce over pegs to the left or to the right. At the bottom they are collected into bins. The distribution of marbles across bins can be observed and modified by applying a "bias" to some of the pegs.

When there are no biases, the resulting distribution approximates a Gaussian (or "Bell-shaped" or "Normal" distribution). Groups of pegs can be biased to the left or to the right by varying degrees.

HOW TO USE IT

=== Main Control Buttons ===

  • Click "Init" to reset the entire simulation and draw the pegs and the bins
  • Click "Go" to start/end the simulation.
  • Click "Drop" to start/stop dropping marbles through the hole at the top.

=== Marble Settings ===

  • Click "Clear Marbles" to erase all Marbles.
  • Use the "max-marbles" slider to determine hoe many marbles to drop (good default is 250)
  • Adjust the "drop-rate" slider to determine how quickly marbles drop from the hole.

=== Bias Settings === Use these controls to change some of the pegs to be biased to the left or right. Click anywhere over the pegs to bias some of them, based on the various settings.

  • Use the "Bias-direction" drop-down to select Left, Right or None.
  • Use the "Bias-radius" slider to determine how large of a patch will be biased around the point where you click the mouse.
  • Use the "bias-strength" slider to set the bias. For example, when a marble hits a red peg (Right bias) with the slider set to 100%, the marble will always go to the right. At a 0% bias, the marble has a 50-50 chance of falling to the right. [Technically, the probability of the marble going to the right is 0.5*bias + 0.5.]

=== Distribution Settings ===

  • Click "Clear Distr" to clear the red dots showing the distribution on the bins.
  • Use the "Distribution" drop-down to select one of the following modes: _* None: do not show distribution, or, if a distribution was being shown, do not change it. Once "Init" or "Clear Distr" are pressed, any remaining distribution will be erased. _* Dynamic: For each bin, place a dot corresponding to the highest marble stacked on its left (not ideal but gets the point across). This changes dynamically as the marbles drop to match the current distribution. _* Gaussian: Draw a Gaussian distribution based on the sliders below _* Manual: Use the mouse to draw a distribution by clicking on individual bins. Note that you can also click-and-drag to draw the distribution.

  • Use the "d-mean" "d-amp" and "d-stdev" sliders to set the mean, amplitude and standard deviation of the Gaussian distribution.

=== Additional controls ===

  • The toggle "use-rseed" determines whether at initialization the random number generator uses a seed or not. If you want to replicate a run, turn this ON and select a desired seed.
  • Use the "r-seed" slider to set a random number seed between 0 and 10
  • The "# of marbles" box is a counter showing how many marbles have been dropped.

WHAT THIS IS ABOUT

The main point of this demo is to illustrate the difference between statistical approaches and agent-based or "bottom-up" approaches to modeling.

When there are no biases, it can be shown mathematically that the distribution of falling marbles should approach a Gaussian distribution. In fact, if you run this with about 250 marbles and no biases, you should be able to fit the resulting distribution with a Gaussian with mean 0, amplitude 1 and standard deviation 10.

However, suppose now that someone shows you a distribution which is not Gaussian. Perhaps it is skewed to one side, or even bimodal. A statistical modeling approach would try to find a different mathematical function (perhaps a gamma or beta distribution) and adjust parameters until it minimizes the error between theoretical and empirical distributions. However, this approach doesn't really say anything about WHY the distribution should be the way it is, nor is there any relationship between the mathematical expression for the distribution and the underlying behavior.

In contrast, using a bottom-up modeling approach, we can make speculations about WHY a certain distribution arises. For instance, if you see a distribution where most marbles end up on the right, you can assume that some pegs must be biased to the right. By selecting different pegs you can make adjustments until you get close to the observed distribution.

Conversely, you can make hypotheses about the impact of different biases. For instance, what happens if all the pegs on the right are biased to the right and all the pegs on the left are biased to the left? Is there a difference between biasing the first five rows of pegs versus biasing the bottom five rows of pegs?

Now imagine the pegs representing people expressing opinions about a product. Each "person" decides whether he or she thinks the product is good (right) or bad (left). Each person then expresses that opinion to another person. Now imagine one person is biased in one direction. If that person can also influence many of its friends through word-of-mouth, a big cluster of biased individuals can cause the opinion of the entire population to shift.

Modeling these kinds of effects is nearly impossible with statistical approaches. You might even imagine a more complex situation, in which the bias of individuals is changed gradually over time by watching what other people decided. Bottom-up modeling gives you the ability to test different conditions, and to do so based on direct, intuitive terms, such as "what happens if this group is biased?" or "where is the most effective group to bias?"

By comparison, with a statistical approach you might be able to ask questions like "what if the standard deviation of the distribution increases?" or "what if I use a Gamma distribution instead of a Gaussian?"

In a nutshell, bottom-up modeling gives you the power to explore and understand causality, while statistical approaches at best can tell you about correlations between variables.

BUGS ETC

The "manual" distribution should place dots at the average between the highest marbles on the left and right sides.

It would be nice to let the bias change as a function of several other factros, such as what other patches are doing, or what information the marbles carry.

COPYRIGHT

This work was created by Paolo Gaudiano and is copyright of Icosystem Corporation. This may not be used for commercial purposes without prior consent of Icosystem. For additional information please visit our web site (http://www.icosystem.com) or send mail to info@icosystem.com

Comments and Questions

Please start the discussion about this model! (You'll first need to log in.)

Click to Run Model

globals
[ top-row   ; used by drop-marbles
  field     ; the patches that are not border patches
  border    ; the border patches
  bins      ; the patches that make up the bottom bins
  pegs      ; the patches that are pegs
  Fill      ; Use to start/stop filling
  Field-color ; color of the background (field)
  Marble-color ; color of the marbles
  Peg-color ; normal grid color
  Bin-color ; color for bins
  Right-color ; pegs biased to the right
  Left-color ; pegs biased to the left
  Border-color ; color of the border patches
  Distr-color ; color to mark distribution on bins
  Hole-size ; how big is the hole from which marbles fall?
  Bin-height ; how tall are the bins?
  Pegs-top ; where at the top do the pegs begin?
  Pegs-bottom ; where at the bottom do the pegs end?
  total-error ;
  old-d-amp; Use these variables to see if Gaussian distro changed
  old-d-stdev;
  old-d-mean;
]

breed [ marbles marble ]

patches-own
[ void? ; true means patch is empty, and not an obstacle
  my_error ; used by distribution patches
]

to setup
   ;; (for this model to work with NetLogo's new plotting features,
  ;; __clear-all-and-reset-ticks should be replaced with clear-all at
  ;; the beginning of your setup procedure and reset-ticks at the end
  ;; of the procedure.)
   clear-all
   ask patches [ set void? true ]
   if use-rseed [ random-seed r-seed ]
   set-color-scheme
   set Bin-height 0.4 * max-pycor
   set Pegs-top 0.95 * max-pycor
   set Pegs-bottom max-pycor * -0.5
   reset-screen-regions
   set top-row patches with [ pycor = max-pycor ]
   set Hole-size 2
   set Fill false
   make-hole
   make-pegs
   make-bins
   reset-ticks
   print "Initialization complete"
end 

to go
   ; if using mouse, all else pauses
   ifelse mouse-down?
   [ do-mouse-action ]
   [ ; evaluate the run-time effect switches
     if Fill = true  [ drop-marbles  ]
     ifelse Distribution != "None"
     [ show-dist ]
     [ clear-distr ]
     ; marbles fall
     ; without-interruption
     ask marbles [ fall-down ]
   ]
end 

to set-color-scheme
     set Field-color black
     set Marble-color green
     set Bin-color 35
     set Peg-color 3
     set Border-color sky
     set Right-color 15
     set Left-color 95
     set Distr-color white
end 

to define-field
   set field patches with
   [     abs pxcor < max-pxcor
     and pycor > min-pycor
   ]
end 

to define-border
   set border patches with
   [ abs pxcor = max-pxcor or pycor = min-pycor
   ]
end 

to define-bins
   set bins patches with
   [ pycor <= min-pycor + Bin-height and pxcor mod 3 = 0
     and pycor != min-pycor and abs pxcor != max-pxcor
   ]
end 

to define-pegs
   set pegs patches with
   [ pycor >= Pegs-bottom and pycor <= Pegs-top and  (pycor + 1) mod 2 = 0
     and floor (pxcor + pycor / 2) mod 2 = 0
     and pycor != min-pycor and abs pxcor != max-pxcor
   ]
end 

to-report field-not-defined?
   report not is-patch-set? field
end 

to-report border-not-defined?
   report not is-patch-set? border
end 

to-report bins-not-defined?
   report not is-patch-set? bins
end 

to-report pegs-not-defined?
   report not is-patch-set? pegs
end 

to define-screen-regions
   if field-not-defined?   [ define-field  ]
   if bins-not-defined?    [ define-bins ]
   if border-not-defined?  [ define-border ]
   if pegs-not-defined?     [ define-pegs ]
end 

to reset-screen-regions
   define-screen-regions
   clear-field
   set-border
end 

to clear-field
   ask marbles [ pop ]
   ask field [ clear-grid ]
end 

to set-border
   ask border
   [ set void? false
     set pcolor Border-color
   ]
end 

to set-fill
  ifelse Fill
  [ set Fill false]
  [ set Fill true ]
end 

to drop-marbles
   let open-patches top-row with [ void? = true ]
   if random 100 < drop-rate and count marbles < max-marbles
   [
     if any? open-patches
     [ ask one-of open-patches
       [ make-marble ]
     ]
   ]
end 

to make-marble ; patch procedure
     sprout 1
     [ set breed marbles
       set shape "circle"
       set heading 180
       set void? false
       set color Marble-color
     ]
end 

to fall-down
   let below patch-at 0 -1
   let below-left patch-at -1 -1
   let below-right patch-at 1 -1
   ;let beside patches at-points [ [ -1 0 ] [ 1 0 ] ]
   ; Adding to fix at-points issue
   let beside-left patch-at -1 0
   let beside-right patch-at 1 0
   let beside (patch-set patch-at -1 0 patch-at 1 0)

   ; if open space directly below, fall straight down
   if [void?] of below = true
   [ set void? true
     set ycor ycor - 1
     set void? false
     stop
   ]

   ; check if there is a biased grid point below.
   if [pcolor] of below = Right-color and [void?] of below-right = true
     and random 100 < bias-strength
     [ set void? true
;       set xcor pxcor-of below-right
;       set ycor pycor-of below-right
       setxy [pxcor] of below-right [pycor] of below-right
       set void? false
       stop
     ]

   if [pcolor] of below = Left-color and [void?] of below-left = true
     and random 100 < bias-strength
     [ set void? true
;       set xcor pxcor-of below-left
;       set ycor pycor-of below-left
       setxy [pxcor] of below-left [pycor] of below-left
       set void? false
       stop
     ]

;   This part gets executed if the space below is occupied, either by an unbiased
;   peg, or by another marble, or by a bin wall. In this case see if there is space
;   below to the left or right. If both are available, choose one randomly.
;   [
     set beside beside with [ void? = true and [void?] of patch-at 0 -1 = true ]
     if count beside > 0
      [ set beside one-of beside
        set void? true
        setxy [pxcor] of beside ( pycor - 1 )
        set void? false
        stop
;      ]

   ]
end 

; this procedure can do two things: set some of the pins to have a bias, or draw a distribution on the pegs

to do-mouse-action

   ifelse Distribution != "Manual" or mouse-ycor >= Pegs-bottom
   [
     let biased pegs with [ abs ( mouse-xcor - pxcor ) <= Bias-radius
                          and abs ( mouse-ycor - pycor ) <= Bias-radius ]
     ask biased [
       ifelse Bias-direction = "Left"
       [ set pcolor Left-color ]
       [ ifelse Bias-direction = "Right"
         [ set pcolor Right-color ]
         [ set pcolor Peg-color ]
       ]
     ] ; ask biased
   ]
   [
     let marked bins with [  abs ( pxcor - mouse-xcor ) < 1 ];  and abs ( pycor - mouse-ycor ) < 1 ]
     ask marked [
       ifelse pycor = round mouse-ycor
       [ set pcolor Distr-color ]
       [ set pcolor Bin-color]
     ]
   ]
end 

to clear-marbles
   ;without-interruption
   ask marbles [ pop ]
end 

to clear-bias
   ;without-interruption
   ask pegs
     [ set-color-grid Peg-color ]
end 

to clear-distr
   ;without-interruption
   ask bins with [ pcolor = Distr-color ]
     [ set-color-grid Bin-color ]
end 

to make-hole
   ask field with [ pycor = max-pycor and abs ( pxcor ) > Hole-size ]
   [ set-color-grid Border-color ]
end 

to make-pegs
   ask pegs
   [ set-color-grid Peg-color ]
end 

to make-bins
   ask bins
   [ set-color-grid Bin-color ]
end 

; superimpose the distribution on the bin columns

to show-dist
   set total-error 0
   if ( Distribution = "Gaussian" ) and Gaussian-unchanged [ stop ]
   ask bins
    [
     if Distribution = "Dynamic"
      [ ifelse ( [void?] of patch-at -1 0 = false or [void?] of patch-at 1 0 = false )
               and ( [void?] of patch-at -1 1 = true and [void?] of patch-at 1 1 = true
                     or [pcolor] of patch-at 0 1 = Field-color )
        [ set pcolor Distr-color ]
        [ set pcolor Bin-color ]
        stop
      ]

     if Distribution = "Gaussian"
      [
         ifelse pycor = min-pycor +
          floor ( d-amp * Bin-height * exp ( - ( pxcor - d-mean ) * ( pxcor - d-mean ) / ( d-stdev * d-stdev ) ) )
          [ set pcolor Distr-color
            set my_error 0
            let left-col min-pycor
            let right-col min-pycor
            let not-found true
          ]
          [ set pcolor Bin-color
            set my_error 0
          ]
        stop
      ]
   ]
end 

; This reporter checks whether the sliders for the Gaussian have changed

to-report Gaussian-unchanged
  ifelse ( old-d-amp = d-amp ) and ( old-d-stdev = d-stdev ) and ( old-d-mean = d-mean )
  [ set old-d-amp d-amp
    set old-d-stdev d-stdev
    set old-d-mean d-mean
    report true
  ]
  [ set old-d-amp d-amp
    set old-d-stdev d-stdev
    set old-d-mean d-mean
    report false
  ]
end 

to clear-grid
   set pcolor Field-color
   set void? true
end 

to set-color-grid [ gcolor ]
   set pcolor gcolor
   set void? false
end 

to pop
   hide-turtle
   set void? true
   die
end 

There is only one version of this model, created almost 2 years ago by Paolo Gaudiano.

Attached files

File Type Description Last updated
Marble drop.png preview Preview for 'Marble drop' almost 2 years ago, by Paolo Gaudiano Download

This model does not have any ancestors.

This model does not have any descendants.