Herfindahl index code in Netlogo - netlogo

I have trouble with programming the Herfindahl index in Netlogo. I want Netlogo to calculate it. I have trouble telling the program the following formula:
https://en.wikipedia.org/wiki/Herfindahl_index#Formula
I want Netlogo to report it and plot it. Help please :-s.

Here is a complete working example. For your purposes, you just need the calc-HI procedure (and remember to call it in your go procedure) but I have given you a separate model so you can test it yourself. The way to test it is to run setup, then run go then show HI in the command centre. By inspecting the individual turtles, you can see their variable values and use a calculator to check the match for HI value.
globals [ HI ]
turtles-own [ val ]
to setup
clear-all
create-turtles 3
[ setxy random-xcor random-ycor
set val random 5
]
reset-ticks
end
to go
set HI calc-HI
tick
end
to-report calc-HI
let num count turtles
let total sum [ val ] of turtles
let herf sum [ ( val / total ) ^ 2 ] of turtles
report herf
end
For plotting, all you need to do is plot HI in the plot widget.

Assuming you have a list of market-shares using percentages. Map each market-share to the square and sum them up:
;;e.g. let market-shares (list .5 .5)
to-report calculate-herfindahl [market-shares]
report (sum (map [? * ?] market-shares))
end
If you want to calculate the shares based on actual shares. Map each share to a percentage, then apply the above formula:
;;e.g. let market-shares (list 30 40)
to-report calculate-herfindahl [market-shares]
let market-size sum market-shares
report (sum (map [(? / market-size) ^ 2] market-shares))
end

Related

How to loop through values in 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.

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

How to plot distributions of two different breeds

I setup two different breeds with the breed command:
breed [breeds1 breed1]
breed [breeds2 breed2]
and in go, I ask to a random turtle to execute an action command, like this:
to go
ask one-of turtles [
action
]
end
where action is defined as
to action
ifelse (breed = breeds1)
[
set q random-float 1
set c q
set potential_1 (1 + d) * (1 - c)^(d)
]
[
set c random-float 1
set potential_2 (1 + (1 / d))*(1 - c)^(1 / d)
]
end
For breeds1, q has value in [0,1] and c takes its value.
For breeds2, q has value equal to 0 and c takes random values in [0,1].
Both breeds have d=3 (fixed value).
c,q, and both potentials are global variables.
What I need to do is to plot the two potentials/distributions.
I used plotxy to plot the distributions in the plot code box:
[![enter image description here][1]][1]
What I would like are the following two distributions in the same plot. Plot 1 shows the distribution for breeds1, plot 2 for breeds2.
If I consider potential_1 and potential_2 as turtles-own (the first one for breeds1, the second one for breeds2) I receive the message that I can't use potential_1 in an observer context, because potential_1 s turtle-only. Same for potential_2.
If I consider q and c as turtles-own as following:
breeds1-own
[ q
c
potential_1
]
breeds2-own
[
q
c
potential_2
]
I receive the following error:
You can't use c in an observer context, because c is turtle-only
So my question is: how could I plot the two distributions?
I hope you can help me.
Okay, I can't answer your question using your code as I can't work out the logic of the ask one-of. So, what I have done instead is created a complete model that does the plotting in the hope that will help you work out what's wrong with your code.
Try this:
globals [d]
turtles-own
[ potential
group
c
]
to setup
clear-all
set d 3
create-turtles 100
[ set group one-of ["type1" "type2"]
action
]
reset-ticks
end
to action
ifelse (group = "type1")
[ let q random-float 1
set c q
set potential (1 + d) * (1 - c)^(d)
]
[ set c random-float 1
set potential (1 + (1 / d))*(1 - c)^(1 / d)
]
end
Then you will need the following as the pens in your plot. You will also need to change the plot settings for each pen to 'point' rather than 'line'.
ask turtles with [group = "type1"] [plotxy c potential]
ask turtles with [group = "type2"] [plotxy c potential]
What I have done is create 100 turtles in two groups, with the values of the variables 'c' and 'potential' calculated for each group using your code. But it's all done in a single pass - each turtle does its calculation and then control moves to the next turtle as they are created. Then I have each pen in the plot just plot the values from one group.
The error message you were getting "You can't use c in an observer context, because c is turtle-only" means that you tried to use the variable c without letting NetLogo know which turtle's value of 'c' you wanted to use.

Netlogo: sum within a neighborood

I need some help. My issue is the following
I want to solve the following formula
sum (Zi - Zj)^2 where Zi is a constant for an individual i and Zj is the value for a generic individual j that is within a neighborood with radius = 1 of the individual i.
Therefore, I want a sum of the square of the distance between a constant value and the value of Z for each individual within that radius.
Sorry for the absence of my code, but I have no idea about how to approach this issue
I will write an example
Zi = 1
The neighborhood of the individual i is composed of 2 agents, let say a and b where Za = 3 and Zb = 5
I want the following result
(1-3)^2 + (1-5)^2 = 20
Thanks
I think you want to do the sum of squared differences between a constant and a list of numbers, where the list of numbers is the value of Z for several turtles. If this is correct, then the following is a complete model that does what you want.
turtles-own [ varZ ]
to setup
clear-all
create-turtles 40
[ setxy random-xcor random-ycor
set varZ random 10
set color blue
]
testme
end
to testme
ask one-of turtles
[ set color red
let friends other turtles in-radius 4
ask friends [ set color yellow ]
type "my varZ is: " print varZ
type "sum of squared differences is: " print sum-sq-diff varZ [varZ] of friends
]
end
to-report sum-sq-diff [#constant #listvals]
report reduce + (map [ thisval -> (thisval - #constant) ^ 2 ] #listvals)
end
The procedure sum-sq-diff takes two inputs: a constant and a list of values. It calculates the squared sum of differences between the constant and each value in the list. The map does the square of differences and creates a list of those values, then the reduce sums across the list. You can test is by simply typing sum-sq-diff 1 [ 2 3 4 ] in the command centre and you will get back 14 (which is (2-1)^2 + (3-1)^2 + (4-1)^2).
The rest of the code is an example of how to use this procedure in the context I think you want, pulling out the turtles within some radius and using their variable values as the list.

Q: How to calculate 'hub integration' / how many of your link-neighbors are also my link-neighbors?

In the model I am building I need to make turtles calculate the 'hub integration' of their link-neighbors. By 'hub integration'(HI) I mean the following: HI = number-of-shared-neighbors/n-of-your-neighbors.
HI is a value that the 'turtle x' assigns to every other turtle that shares a link with her (we will call every linked turtles as 'turtle y'). The value of HI is thus the fraction of the number of nodes that are linked to both turtles x and y, with the number of nodes linked to turtle y.
I am using as references the Netlogo dictionary and the book 'An Introduction to Agent-Based Modeling' from Wilensky and Rand. Still, without the help of this community it would be really hard for me, if not impossible, to learn more advanced procedures.
EDIT 3 ---
I am greatly thankful for all the help received. I finally have a running procedure.
For the record, my final code of the 'hub integration procedure' is the following:
to find-hi
ask turtles [
foreach sort link-neighbors [
ask ? [
if count [my-links] of self > 1 and count [my-links] of myself > 1 [
let hi ( calc-HI self myself )
run-procedure ] ] ] ]
end
to-report calc-HI [ XX YY ]
let sizeX count [my-links] of XX
let sizeY count [my-links] of YY
let sizeXY count (turtle-set [link-neighbors] of XX [link-neighbors] of YY)
report (sizeX + sizeY - sizeXY) / sizeY
end
I think you want to count the number of neighbours, not list them all out.
One approach to count the number in common is to count the neighbours of X, count the neighbours of Y and count the agents who are either neighbours of X or Y. A turtle who is a neighbour of both X and Y will still only appear once in the agentset constructed, so the size of the intersection is the sum of the individual counts then subtract the size of the union.
This code expects you to nominate two turtles and reports the HI of turtle YY from the perspective of turtle XX (note that there is no checking that the two turtles have a link between them). I am not sure I have understood the calculation that you want, but you can amend as required.
to-report calc-HI [ XX YY ]
let sizeX count [my-links] of XX
let sizeY count [my-links] of YY
let sizeXY count (turtle-set [link-neighbors] of XX [link-neighbors] of YY)
report (sizeX + sizeY - sizeXY) / sizeY
end
You're using print in your reporter, try using report instead.
E.G.:
to-report who-of-neighbors
report [who] of link-neighbors
end
More info on to-report right here.