How to create random binary/boolean variable in Netlogo - random

I'd like to assign a random boolean variable to each turtle, but I'm not seeing a function that would simulate a draw from a Bernoulli distribution.
This gets close, but it's awkward:
ifelse random-in-range 0 1 < .5 [set expensive? false]
[ set expensive? true ]
Anyone know a better way?

A few options:
one-of [ true false ]
random 2 = 1
random-float 1 < 0.5 - If you need to modify the probability, to get any Bernoulli distribution you want
If I deal with a lot of probabilistic stuff in a model, I like to add
to-report probability [ p ]
report random-float 1 < p
end
as an easy shorthand.
Also, note that the ifelse is redundant in your code. You can just do set expensive? one-of [ true false ] or whichever is your preferred method.

Related

Turtle distribution

How to create a set of turtles with the rising distribution of their location from the edge of the environment to the middle?
You can use something like this in setup
let center-x (max-pxcor + min-pxcor) / 2
let center-y (max-pycor + min-pycor) / 2
let std-dev 5 ; change this to vary how clumped the turtles are
crt 100
[
set xcor random-normal center-x std-dev
set ycor random-normal center-y std-dev
]
That will work if you have world-wrapping on. If world-wrapping is off, you would have to add some code to check that the values of xcor and ycor from random-normal are within the world (e.g., the turtle's new xcor is between min-pxcor and max-pxcor) -- otherwise, the code will sometimes try to put the new turtle outside the space, which is an error.
You could also use a triangular distribution that varies the density of turtles linearly from a peak at the center of the space to zero at the edge.
let center-x (max-pxcor + min-pxcor) / 2
let center-y (max-pycor + min-pycor) / 2
crt 100
[
set xcor random-triangular min-pxcor center-x max-pxcor
set ycor random-triangular min-pycor center-y max-pycor
]
NetLogo does not have this triangular distribution built-in, so you need to add this procedure to your code:
to-report random-triangular [a-min a-mode a-max]
; Return a random value from a triangular distribution
; Method from https://en.wikipedia.org/wiki/Triangular_distribution#Generating_Triangular-distributed_random_variates
; Obtained 2015-11-27
if (a-min > a-mode) or (a-mode > a-max) or (a-min >= a-max)
[ error (word "Random-triangular received illegal parameters (min, mode, max): " a-min " " a-mode " " a-max) ]
let a-rand random-float 1.0
let F (a-mode - a-min) / (a-max - a-min)
ifelse a-rand < F
[ report a-min + sqrt (a-rand * (a-max - a-min) * (a-mode - a-min)) ]
[ report a-max - sqrt ((1 - a-rand) * (a-max - a-min) * (a-max - a-mode)) ]
end

NetLogo: save or increase calculation time with using local variable "let"?

I would like to save calculation time of turtle movement (question posted here: NetLogo: how to make the calculation of turtle movement easier?). In original move-turtles procedure authors use many "let" - local variables. I suppose that I can easily replace these "let" variables with built-in NetLogo primitives p.ex. here:
; original code with "let" local variables
let np patches in-radius 15 ; define your perceptual range
let bnp max-one-of np [totalattract] ; max of [totalattract] of patches in your neighborhood
let ah [totalattract] of patch-here ; [totalattract] of my patch
let xcorhere [pxcor] of patch-here
let ycorhere [pycor] of patch-here
let abnp [totalattract] of bnp
ifelse abnp - ah > 2 [ ...
can be replaced by this condition?
; make the same condition with NetLogo primitives
ifelse ([totalattract] of max-one-of patches in-radius 15 [totalattract] - [totalattract] of patch-here > 2 [ ...
Please, will utilization of "let" local variables save computational time or will it be more time consuming? How can I easily verify it? Thank you for your time !
(PS: Following comments to my previous question I suppose that primitives variables will be more efficient, I just prefer to be more sure)
The difference is in the number of times each reporter is being calculated. If you say let np patches in-radius 15 then that actually calculates the number of patches within 15 distance and gives that value to the variable named np. Using np in calculations directly substitutes the value that is saved. If you have to use it 10 times in your code, then using the let means it is calculated once and simply read 10 times. Alternatively, if you don't store it in a variable, then you will need patches in-radius 15 at 10 different places in the code and, EACH TIME, NetLogo will need to calculate this value.
Apparently is looks like local variables within [] works faster then primitives NetLogo variables.
Comparing 1) only NL primitives
let flightdistnow sqrt (
; (([pxcor] of max-one-of patches in-radius 15 [totalattract] - [pxcor] of patch-here ) ^ 2) +
; ([pycor] of max-one-of patches in-radius 15 [totalattract] - [pycor] of patch-here ) ^ 2
; )
vs 2) use local variables and then calculate turtle movement
to move-turtles
let np patches in-radius 15 ; define your perceptual range
let bnp max-one-of np [totalattract] ; max of [totalattract] of patches in your neighborhood
let ah [totalattract] of patch-here ; [totalattract] of my patch
let xcorhere [pxcor] of patch-here
let ycorhere [pycor] of patch-here
let abnp [totalattract] of bnp
ifelse abnp - ah > 2 [
move-to bnp ; move if attractiveness of patches-here is lower then patches in-radius
let xbnp [pxcor] of bnp
let ybnp [pycor] of bnp
let flightdistnow sqrt ((xbnp - xcorhere) * (xbnp - xcorhere) + (ybnp - ycorhere) * (ybnp - ycorhere))
set t_dispers (t_dispers + flightdistnow)
set energy (energy - (flightdistnow / efficiency))
set flightdist (flightdist + flightdistnow)
; if ([pxcor] of patch-here = max-pxcor) or ([pycor] of patch-here = max-pycor) or ([pxcor] of patch-here = min-pxcor) or ([pycor] of patch-here = min-pycor)
; [set status "lost"
; set beetle_lost (beetle_lost + 1)]
] ; if attractivity of [totalattract] is higher the the one of my patch
and using stop watch for movement of 5000 turtles my results are:
- 1) 10 seconds
- 2) 5 seconds
so I suppose to use local variables in time consuming calculations.
I will appreciate if you will correct my conclusions if I'm wrong. Thanks !!

NetLogo Sandpile Model - Code Required to Enhance Model

The below code relates to the NetLogo Sandpile Model where at each time step a random grain of sand is added. When the count of grains of sand exceeds a threshold limit it will trigger an avalanche type event.
I now want to enhance this model with further code so that at each tick (prior to the random grain of sand being added) the code now executes the following rules:
(1) Each patch count will increase its count (n + 1) if the majority of its 8 neighbours are n > 1.
(2) Each patch count will decrease its count to (n = 0) if the majority of its 8 neighbours are n < 1.
It will then move to the second step with the random addition of a grain of sand as in the original code below:
xtensions [sound]
globals [
;; By always keeping track of how much sand is on the table, we can compute the
;; average number of grains per patch instantly, without having to count.
total
;; We don't want the average monitor to updating wildly, so we only have it
;; update every tick.
total-on-tick
;; Keep track of avalanche sizes so we can histogram them
sizes
;; Size of the most recent run
last-size
;; Keep track of avalanche lifetimes so we can histogram them
lifetimes
;; Lifetime of the most recent run
last-lifetime
;; The patch the mouse hovers over while exploring
selected-patch
;; These colors define how the patches look normally, after being fired, and in
;; explore mode.
default-color
fired-color
selected-color
threshold-color
]
patches-own [
;; how many grains of sand are on this patch
n
;; A list of stored n so that we can easily pop back to a previous state. See
;; the NETLOGO FEATURES section of the Info tab for a description of how stacks
;; work
n-stack
;; Determines what color to scale when coloring the patch.
base-color
]
;; The input task says what each patch should do at setup time
;; to compute its initial value for n. (See the Tasks section
;; of the Programming Guide for information on tasks.)
to setup [setup-task]
clear-all
set default-color blue
set fired-color red
set selected-color green
set selected-patch nobody
ask patches [
set n runresult setup-task
set n-stack []
set base-color default-color
]
let ignore stabilize false
ask patches [ recolor ]
set total sum [ n ] of patches
;; set this to the empty list so we can add items to it later
set sizes []
set lifetimes []
reset-ticks
end
;; For example, "setup-uniform 2" gives every patch a task which reports 2.
to setup-uniform [initial]
setup task [ initial ]
end
;; Every patch uses a task which reports a random value.
to setup-random
setup task [ random error-count ]
end
;; patch procedure; the colors are like a stoplight
to recolor
set threshold-color threshold + 2
set pcolor scale-color base-color n 0 threshold-color
end
to go
if ticks = time
[ sound:play-note "Trumpet" 60 64 2 stop ]
let drop drop-patch
if drop != nobody [
ask drop [
update-n 1
recolor
]
let results stabilize animate-avalanches?
let avalanche-patches first results
let lifetime last results
;; compute the size of the avalanche and throw it on the end of the sizes list
if any? avalanche-patches [
set sizes lput (count avalanche-patches) sizes
set lifetimes lput lifetime lifetimes
]
;; Display the avalanche and guarantee that the border of the avalanche is updated
ask avalanche-patches [ recolor ask neighbors4 [ recolor ] ]
display
;; Erase the avalanche
ask avalanche-patches [ set base-color default-color recolor ]
;; Updates the average monitor
set total-on-tick total
tick
]
end
to explore
ifelse mouse-inside? [
let p patch mouse-xcor mouse-ycor
set selected-patch p
ask patches [ push-n ]
ask selected-patch [ update-n 1 ]
let results stabilize false
ask patches [ pop-n ]
ask patches [ set base-color default-color recolor ]
let avalanche-patches first results
ask avalanche-patches [ set base-color selected-color recolor ]
display
] [
if selected-patch != nobody [
set selected-patch nobody
ask patches [ set base-color default-color recolor ]
]
]
end
;; Stabilizes the sandpile. Reports which sites fired and how many iterations it took to
;; stabilize.
to-report stabilize [animate?]
let active-patches patches with [ n > threshold ]
;; The number iterations the avalanche has gone for. Use to calculate lifetimes.
let iters 0
;; we want to count how many patches became overloaded at some point
;; during the avalanche, and also flash those patches. so as we go, we'll
;; keep adding more patches to to this initially empty set.
let avalanche-patches no-patches
while [ any? active-patches ] [
let overloaded-patches active-patches with [ n > threshold ]
if any? overloaded-patches [
set iters iters + 1
]
ask overloaded-patches [
set base-color fired-color
;; subtract 'threshold' amount from this patch
update-n -4
if animate? [ recolor ]
;; edge patches have less than four neighbors, so some sand may fall off the edge
let selected-neighbors n-of 4 neighbors
;; World is wrapped horizonatlly and vertically so we can always select 4 random neighbors.
;; However, we only want to select neighbors which are on the table.
;; That is what the next section of code does.
set selected-neighbors selected-neighbors with [
(abs (pxcor - [ pxcor ] of myself) < 2) ;; selects patch < 2 from myself which is one patch away.
and
(abs (pycor - [ pycor ] of myself) < 2)
]
ask selected-neighbors [
update-n 1
if animate? [ recolor ]
]
]
if animate? [ display ]
;; add the current round of overloaded patches to our record of the avalanche
;; the patch-set primitive combines agentsets, removing duplicates
set avalanche-patches (patch-set avalanche-patches overloaded-patches)
;; find the set of patches which *might* be overloaded, so we will check
;; them the next time through the loop
set active-patches patch-set [ neighbors ] of overloaded-patches
]
report (list avalanche-patches iters)
end
;; patch procedure. input might be positive or negative, to add or subtract sand
to update-n [ how-much ]
set n n + how-much
set total total + how-much
end
to-report drop-patch
if drop-location = "center" [ report patch 0 0 ]
if drop-location = "random" [ report one-of patches ]
if drop-location = "mouse-click" and mouse-down? [
every 0.3 [ report patch mouse-xcor mouse-ycor ]
]
report nobody
end
;; Save the patches state
to push-n ;; patch procedure
set n-stack fput n n-stack
end
;; restore the patches state
to pop-n ;; patch procedure
; need to go through update-n to keep total statistic correct
update-n ((first n-stack) - n)
set n-stack but-last n-stack
end

Not calculating "set" correctly - syntax?

I am trying to use set to calculate a value, but it always return 0.5. When I breakdown the equation to individual operators, it works fine, but when I put it all together, all I get is 0.5. I think I have a syntax misunderstand. Any suggestions?
to go
;;see if a new risk is generated [randomly]
if random 2 = 1 ;;50% chance risk be generated on an individual project
[
make-risk
ask one-of projects
[
ask one-of risks [
set risk-encounter ((((RE-influence * ( [duration] of myself ) * 0.5)) / (( [duration] of myself )))) ;;calculate RE. THIS DOES NOT WORK :-( Always sets to 0.5
set temp-RE-score risk-encounter
]
set total-RE total-RE + temp-RE-score ;;update the project's RE score
]
]
ask projects[
set label precision total-RE 1
set size total-RE / 10 ; size according to RE score
]
tick
if ticks >= (max [duration] of projects ) * 2 [stop] ;; stops all the projects once max duration is reached (* 2)
end

How to take power of each element in a matrix in Netlogo?

I would like to take all elements of a matrix to the power of a specific number.
I have a matrix using the matrix extension set up like this:
let A matrix:make-constant 4 4 5
which gives a 4x4 matrix with values of 5 in there
Now I want to take all elements in the matrix to the same power, so say I want to take them to power 2, then I want to end up with a 4x4 matrix with numbers 25.
How can I do this?
You can do this a couple ways. The simplest is probably with matrix:times-element-wise. Unfortunately, this will only work for integer powers greater than or equal to 1:
to-report matrix-power [ mat n ]
repeat n - 1 [
set mat matrix:times-element-wise mat mat
]
report mat
end
You can also convert the matrix to a list of lists, and then use map on that to raise each element to a power. This has the advantage of working with 0, fractional powers, and negative:
to-report matrix-power [ mat n ]
report matrix:from-row-list map [ map [ ? ^ n ] ? ] matrix:to-row-list mat
end
map [ ? ^ n ] some-list raises each element of a list to the power of n. matrix:to-row-list converts the matrix to a list of lists. So, we apply map [ ? ^ n ] each list in the result of matrix:to-row-list. Then, we convert the result back into a matrix with matrix:from-row-list.
You can generalize this to do any element-wise operation:
to-report matrix-map [ function mat ]
report matrix:from-row-list map [ map function ? ] matrix:to-row-list mat
end
Then, we could define the power function as:
to-report matrix-power [ mat n ]
report matrix-map task [ ? ^ n ] mat
end

Resources