How to loop through values in NetLogo? - netlogo

I want to change the mean, lambda, of a poisson process every time ticks advance by one.
Let's say lambda is a predetermined list of the following numbers: [1 2 3 4 5].
If I define lambda in this way, is it possible for NetLogo to loop through each position of the list based on the time step? E.g., at the first tick, NetLogo will set lambda to equal to the first item of the list, such that lambda = 1, when tick = 2, lambda = 2, etc.
Here is an example of what I'm trying to do:
to recruit-spores
ask turtles with [color = red] [
hatch-spores random-poisson lambda ; lambda is what I want to change at every tick
[set shape "dot"
set size 0.01
set color orange
setxy random-xcor random-ycor ]
]
end
Is there a way to change the value of lambda by looping through a list in NetLogo? Either through NetLogo's built-in functionality, or through an extension? Is there a way to do this using the R extension?

Straightforward to do it entirely in NetLogo if you want. The reproducible code below shows how you can use first, lput and but-first to take (in this example, print) the first value of the list and then append it to the end of the list:
globals [
lambda-values
]
to setup
set lambda-values [1 2 3 4 5]
end
to go
print first lambda-values
set lambda-values lput (first lambda-values) lambda-values
set lambda-values but-first lambda-values
tick
end
To put this in your example, it would be:
to recruit-spores
let current-lambda first lambda-values
set lambda-values lput current-lambda lambda-values
set lambda-values but-first lambda-values
ask turtles with [color = red] [
hatch-spores random-poisson current-lambda [
set shape "dot"
set size 0.01
set color orange
setxy random-xcor random-ycor
]
]
end
Alternatively, you can use remainder or mod, in combination with the current value of ticks, to find out the position of the item that needs to be extracted from the list (you can extract it using item). This solution might be in some way less preferable than the previous one, as it is ticks-dependant (as opposed to the previous one).
Another approach: implement a counter variable that is incremented each time that you use a value from lambda-values and that indicates the position of the next item you want to extract, and that is reset to 0 when it reaches the end of the list. This latest solution might be the least preferable because it requires you to create a global variable for the counter.

Related

How to find the turtle with the most neighbors in netlogo

i am struggling with a way to find the turtle with the most neigbors in a radius of 3 and change its color. At the moment i tried something with a while loop that increases an the id of the turtles and tests if the number of neighbors is higher than the last one. But It's causing anf infinite loop and travels only between the id 0 and 1.
I can't seem to find where the error comes from, Here's the code i wrote:
to election
while [var1 < 9][
ask turtle var1 [
set voisin count turtles in-radius 3
if voisin > maxi [
set maxi voisin
set idmax var1
]
show voisin
show idmax
set var1 var1 + 1
set color pink
]
]
ask turtle idmax[
set color green
]
end
You can do this with a single statement,
ask max-one-of turtles [count other turtles in-radius 3] [set color green]
max-one-of finds the turtle with the maximum value of the expression in brackets. (If there are multiple turtles with that maximum value, then a random one of those with the maximum value is chosen.) In the brackets, each turtle evaluates the number of other turtles in radius 3. The other is not strictly necessary. Without it, every turtle will count itself, adding one to the count.

SIR model error - can't find bug, need help in locating potential source of deviation?

This question will be an interesting one. I was trying to replicate the results of a paper which concerned disease transmission in a system of freely moving agents (sounds like the perfect job for NetLogo). I coded up a simple SIR model in NetLogo pretty easily according to the details given in the paper, made sure my model parameters matched those listed, and let the simulation run. Everything ran perfectly until I checked how the experimental results matched with the predicted values (according to the results of the paper). They were off, and by a pretty sizeable margin. Thinking there was an error somewhere in the code, I triple checked everything, only to find nothing. I then made sure the ordering of events was correct (as the order of movement, infection, and recovery matters), and these also matched the paper. I mulled over the problem for quite some time until finally I opened R, coded up the exact same program in RStudio, and let it run, only to find that the results matched the prediction perfectly! The R code does the same thing I expect the NetLogo code to be doing, so I think that something is going on behind the scenes in NetLogo or I've a misunderstanding somewhere that is the source of the deviation... Note that since the result in the paper is a mean-field approximation, you would have to run the program a few times in order for it to approach the theoretical result.
I'm not sure where I'm going wrong, as my R code confirms the predicted values are correct, so I conclude that something somewhere in my NetLogo code is incorrect. I'm not too familiar with NetLogo, and I would really appreciate it if someone could help me find where in the following code the deviation may be occurring. The experimental average tends to be lower than the predicted one, suggesting that infection occurs faster than it should, but of all the changes I looked at, none of them solved this problem (e.g. infections do not occur one at a time per infectious turtle). Any suggestions/help would be very much appreciated.
A slimmed-down version of my code is presented below. This should run in a regular interface with the standard setup/go buttons. Results are stored in lists that can be plotted, and anyone curious can see the deviation as the simulation progresses via the Plot object. Thank you in advance.
;; Simple SIR model
globals [
;; variables for storing predictions
predS
predE
predI
predR
oldPredS
oldPredE
oldPredI
oldPredR
;; list to store experimental values
Slist
;; list to store predicted values
predSList
;; model variables
length-of-patch ;; length of habitat (a square of area length-of-patch^2)
infection-radius ;; the distance from an infectious individual a susceptible agent has to be within
;; in order to risk getting infected
total-pop ;; total population in the model
force-of-infection ;; probability of infection if within infection-radius distance
I0 ;; initial infected
recovery-rate ;; probability of recovery
]
turtles-own [
infected-status ;; 0 susceptible, 1 infected, 2 recovered
]
to setup
ca ;; clear
;; define the variables
set length-of-patch 31.62278 ;; the square root of 1000 (so the density is 1)
set infection-radius 1
set total-pop 1000
set force-of-infection 0.1
set I0 10
set recovery-rate 0.05
;; setup simulation
setup-patches
setup-agents
reset-ticks
;; initialize lists as empty
set Slist []
set predSList []
end
to go
;; update experimental values (density of susceptible individuals)
set Slist lput ((count turtles with [infected-status = 0]) / (length-of-patch ^ 2)) Slist
if (ticks = 0) ;; if ticks == 0, make sure initial value is the same as experimental
[
;; update predicted values with densities of agents
set predS ((count turtles with [infected-status = 0]) / (length-of-patch ^ 2))
set predI ((count turtles with [infected-status = 1]) / (length-of-patch ^ 2))
set predR 0
;; placeholder variables for iterative process
set oldPredS predS
set oldPredI predI
set oldPredR predR
;; store predicted S population in corresponding list
set predSList lput (predS) predSList
]
if (ticks > 0) ;; if ticks > 0, then update predicted values according to paper results
[
;; update predicted values
set predI (oldPredI + oldPredS * (1 - (1 - force-of-infection * oldPredI) ^ (pi * (infection-radius ^ 2))) - recovery-rate * oldPredI)
set predR (oldPredR + recovery-rate * oldPredI)
set predS ((total-pop / (length-of-patch ^ 2)) - predI - predR)
;; placeholder variables
set oldPredS predS
set oldPredI predI
set oldPredR predR
;; store values in corresponding list
set predSList lput (oldPredS) predSList
]
;; perform movement, infection, and recovery, in that order
move-agents
infect-agents
recover-agents
if (count turtles with [infected-status = 1] = 0) [
;; if no one else is infected, stop
stop
]
tick
end
to setup-patches
;; resize the world to make it fit comfortably in the interface
resize-world 0 length-of-patch 0 length-of-patch
set-patch-size 400 / (length-of-patch)
end
to setup-agents
;; create susceptible agents
crt (total-pop - I0) [
set infected-status 0
setxy random-pxcor random-pycor
set color 55 ;; green
set size 2
]
;; create I0 infected agents
crt I0 [
set infected-status 1
setxy random-pxcor random-pycor
set color 15 ;; red
set size 2
]
end
to move-agents ;; move all the agents
ask turtles [
setxy random-pxcor random-pycor
]
end
to infect-agents
;; iterate over infected turtles
ask turtles with [infected-status = 1] [
;; check neighborhood around infected turtle for susceptible turtles...
let numNeighbors count (turtles with [infected-status = 0] in-radius infection-radius)
if (numNeighbors > 0) [ ;; there are susceptibles around, so we perform infection
ask (turtles with [infected-status = 0] in-radius infection-radius) [
let %draw (random-float 1)
if (%draw <= force-of-infection) [ ;; probability of infection
;; infect one of the neighbors
set infected-status 1
set color 15 ;; red
]
]
] ;; end of if numneighbors > 0
]
end
to recover-agents
ask turtles with [infected-status = 1] [
let %draw (random-float 1)
if (%draw <= recovery-rate) [ ;; an agent recovered
set infected-status 2
set color 105
]
]
end
One problem I can see is that you have: setxy random-pxcor random-pycor but you want: setxy random-xcor random-ycor
Basically you are putting all your turtles at the centre of the patch, so they are on top of each other, instead of distributing them randomly across the space. That positioning changes the distribution of possible distances between turtles.
I also changed the number of turtles to 1024 1089 and the size to sqrt 1024 (instead of 1000) to make the density match properly.
Both of those reduced the mismatch but it's unclear whether they fix the problem since I didn't do large numbers of runs.
UPDATE
Even more dimension matching is required. Changing the code so there are 1089 agents, setting length to 33 for the pred calculations, and resizing world with max of 32 appears to move the curves closer. This recognises that patch coordinates 0 to 32 actually describe a size with length 33 because NetLogo coordinates would start at -0.5 and run to 32.5 as mentioned by #Jasper

In NetLogo how can I extract the x and y coordinates of a subset of turtles every nth tick?

I have a very simple model of 50 turtles moving away from a central point. I would like to be able to extract the spatial coordinates (xcor, ycor) of a subset of them every nth tick in behaviour space. Hope you can help!
The modulo operator mod is probably the simplest way to do this. It outputs the remainder from a division operation, so you can just use a logical flag such that the coordinates are only extracted when ticks divided by n is equal to 0. For example:
to setup
ca
crt 10
reset-ticks
end
to go
; set up lists for example output
let tlist []
let xlist []
let ylist []
ask turtles [
rt random 60 - 30
fd 1
]
tick
; If ticks is not zero, and the remainder of
; the number of ticks / 3 is zero, extract
; some info about the turtles and print it.
if ticks > 0 and ticks mod 3 = 0 [
ask turtles with [ xcor > 0 ] [
set tlist lput self tlist
set xlist lput xcor xlist
set ylist lput ycor ylist
]
print tlist
print xlist
print ylist
]
end
Run this several times and you'll see that on tick 3 (and 6, 9, 12, etc), the lists are printed out. Note that where you have your tick increment will affect when this output is actually extracted- in the example above, tick happens at the end of the go procedure but before the if statement is evaluated.

NetLogo: Changing one breed's variable depending on other breed's variable in an ego-centric network environment

Dear Stackoverflow users,
I am a newbie to NetLogo and the community here, so I hope I can express myself adequately. If you need more information in order to understand my question, please, let me know. As I am not completely sure, where my problem lies, my title might even be misleading.
Here is what I am trying to do: I want an ego-centric network model, in which 1 ego (a Latino immigrant in the US) starts with a given value (between 1 and 6) for
identification with Latino culture and
identification with US/White culture.
The ego (breed #1) has 8 alters (breed #2). The alters consist of Latinos and Whites (ratio to be determined by slider in the interface: number-Latinos). The alters are randomly connected between themselves (amount of undirected links to be determined by another slider in the interface: number-of-alter-links). Each alter has a value for degree d (which is the number of links within the same ethnicity).
At each tick, ego is supposed to interact randomly with one of the alters. If the alter is Latino, then ego's initial value for Latino identification should increase by 0.1 + d * 0.1. If the alter is White, ego's initial value for US identification should increase by 0.1 + d * 0.1. The maximum value that can be reached for the identification variables is 6.
Here comes the code:
breed [egos ego]
breed [alters alter]
egos-own[identification-US identification-Latino]
alters-own[degree]
to setup
clear-all
setup-alters
setup-egos
reset-ticks
end
to setup-alters
create-alters 8
[layout-circle alters 8
if who < number-Latinos [set color orange] ; Latinos are orange
if who >= number-Latinos [set color yellow] ; Whites are yellow
]
while [count links < number-of-alter-links][
let node1 random 8
let node2 random 8
if (node1 != node2)[
ask alter node1 [create-link-with alter node2]
]
]
ask alters [ ; set degree within same ethnicity
ifelse color = yellow
[set degree (count link-neighbors with [color = yellow])]
[set degree (count link-neighbors with [color = orange])]
]
end
to setup-egos
create-egos 1 [
set identification-US initial-US-identification-ego
set identification-Latino initial-Latino-identification-ego]
end
to go
if ticks >= 50 [stop]
interact
change-identification
tick
end
to interact
ask egos [create-link-with one-of alters [set color green]]
end
to change-identification
ask links with [color = green] [let d [degree] of end1
ask egos [
ifelse link-neighbors = yellow
[ifelse (identification-US < 6)
[set identification-US identification-US + 0.1 + d * 0.1]
[set identification-US 6]
]
[ifelse (identification-Latino < 6)
[set identification-Latino identification-Latino + 0.1 + d * 0.1]
[set identification-Latino 6]
]
]
]
ask egos [ask my-links [die]]
end
This is my problem: When I am running the simulation, only the value for Latino identification changes, but not the one for US identification. This is even true, when there are no Latinos in the network. I am not sure where the problem lies. Is it in the nested ifelse command? I have tried to work my way around the nested ifelse and made several if commands, but the problem remains. Does it have to do with how I defined the two ethnicities with colors? Also, when I ask in the command center something about a particular turtle (e.g., turtle 3), I get the answer 9 times (total number of turtles). Maybe the problem is how I ask the link-neighbor(s) for its color?
Thanks for your attention! Any idea, suggestion or possible solution is highly appreciated.
This will always be false: link-neighbors = yellow.
Btw, if you post an entire model like this, you need to replace the interface globals with code-based declaration and initialization of the variables.

How to pick random agents from an agentset to create a new agenset?

I have an agent-set of all the turtles. I want to randomly pick 5 turtles from this agent-set and assign a value of 1 to them. The other 5, ones that were not selected should take the value of 0.
I tried using the random function but it's not working.
turtles-own [attr]
to set-attr
ask turtles [set attr 0]
let my-agentset n-of 5 turtles
ask my-agentset [set attr 1]
end