IF THEN ELSE nested statement system dynamics command in NetLogo - if-statement

I have variables in system dynamic in NetLogo and I am trying a nested if else as follows
Md * (( ifelse n_porg = 0 [ 0 ] [ ifelse ( ( SDIa * Total_norg ) / n_porg ) > 1
[ 1 ] [ ( SDIa * Total_norg ) / n_porg ] ] ) / delay )
I am getting an error "Expected reporter" please help

ifelse is a command; you can't drop a command into the middle of a reporter expression, because a command doesn't report a value.
Instead of ifelse, use ifelse-value, which is a reporter.
You may find you need to add parentheses, e.g. ifelse (n_porg = 0) ...

Related

NetLogo: Use variable not literal to index lists or arrays?

I am trying to port this pseudocode into NetLogo, and finding it difficult because NetLogo requires a literal to be used as a list index, rather than allowing a variable containing the index value (such as index in the code below) to be used. I tried the array extension, and it likewise doesn't allow a variable to be used for an array index.
Basically, my goal is to
identify elements that differ in the lists of two agents
randomly select one of the elements that will change for both agents.
Any ideas of how to do this in NetLogo?
; Have an agent interact with some another culture if they
; are similar enough that the agent accepts the influence
; and if the event passes some degree of randomness. In
; ’ jump ’ mode we take the exact culture value of the other
; culture , in ’ shift ’ mode we shift closer to that culture.
function interactWith Culture ( agent , other_culture ) {
similarity = calculateSimilarity ( agent. culture , other_culture )
chance = uniform Random ( min = 0 , max = 1)
if ( similarity > minimum_similarity and chance < similarity ) {
index = findDifferingElement (agent. culture , other_culture )
if ( interaction_method == ’ jump ’) {
agent. culture[ index ] = other_culture [ index ]
} else {
difference = agent. culture[ index ] - other_culture [ index ]
agent. culture[ index ] = agent. culture[ index ] -
difference * shift_degree
}
}
}

Netlogo: replacing matrix elements by conditioning on other rows/columns

I am working in Netlogo on a series of models making heavy use matrices. Briefly, the models include a number of state-variables for different breeds, where the state-variables are often stock-like items. As a simple example, consider the model:
extensions [ matrix ]
globals
[
]
turtles-own
[
n-items
stock-list
]
to setup
clear-all
reset-ticks
create-turtles 2
ask turtles
[
setxy random-xcor random-ycor
set n-items 10
let n-vars 3
set stock-list matrix:make-constant n-items n-vars [0] ; empty matrix
let stock-item n-values n-items [i -> i]
let stock-cost n-values n-items [ random-normal 10 2 ]
let stock-age n-values n-items [ random 50 ]
matrix:set-column stock-list 0 stock-item
matrix:set-column stock-list 1 stock-cost
matrix:set-column stock-list 2 stock-age
]
end
Here, each turtle's matrix stock-list is initialised as an empty matrix and then its columns filled in depending on the variables stock-item (id for stock), stock-cost and stock-age.
Imagine a go procedure that increments the stock age by one each time-step:
to go
ask turtles
[
let current-age matrix:get-column stock-list 1
let new-age map [x -> x + 1] current-age
matrix:set-column stock-list 2 new-age
]
tick
end
What I would like to do is an operation on stock-cost only if the age is greater than some value, e.g. 10
;; pseudo-code
for( i = 1 to I = number of items )
{
if ( stock-age[i] > 10 )
{
stock-cost[i] - 1
}
}
I know how to change the list of stock-cost conditional on its own values, using the map primitive, e.g.:
to decrease-stock-value
ask turtles
[
let current-cost matrix:get-column stock-list 1
set current-cost map [[?] -> ifelse-value (? > 10) [? - 1][?]] current-cost
matrix:set-column stock-list 1 current-cost
]
But my efforts to generalise this to using values in a different list to condition upon have failed.
Thanks for your help! Also, any insight onto whether this is a good approach to modelling state variables such as stocks would be useful.
I think I sorted it out using:
to decrease-stock-value
ask turtles
[
let current-cost matrix:get-column stock-list 1
let current-age matrix:get-column stock-list 2
let new-cost ( map [ [ a b ] ->
ifelse-value ( a > 10 ) [ b - 1 ] [ b ] ]
current-age current-cost
)
matrix:set-column stock-list 1 new-cost
]
end

Netlogo list updated in time

I'm writing up a code in Netlogo that basically should do the following:
Amongst directed links, interact and seek out their cooperative behavior (coop_b).
Store coop_b in a list variable together with the time of the interaction (reputation_now)
Every interaction, add the reputation_now to a bigger list, reputation_h (reputation history)
Now, add a time-weight to the reputation, so that the more recently had interactions weigh more in the total reputation. I do this by dividing the encounter time of an interaction by the current time tick, then multiplying that with the coop_b to retrieve a weighted reputation for each interaction. This is stored in the list reputation_h_w (historic reputations weighted). The thing is, this list should be updated every time the members interact, so that earlier additions to the list are now updated to the new time tick. My hunch is this is where my code goes in the mist (problems depicted below the code section).
My code:
to horizontal_interact
ask members [
;set random example variable for coop_b
set coop_b random-float 5 ; coop-b stands for cooperation behavior
if ticks > 0 [
ask my-out-links [ ;there are directed links between all members
set reputation_now (list [coop_b] of end2 ticks) ;list of coop_b and encounter time
set reputation_h lput reputation_now reputation_h ; history of reputations, a list of all reputation_now recorded
foreach reputation_h [ x ->
let cooperative_behavior item 0 x
let encounter_time item 1 x
let reputation_now_w (list cooperative_behavior encounter_time (encounter_time / ticks ))
]
]
]
]
end
If I test the content of reputation_h and reputation_h_w with 2 members, I get:
reputation_h is the coop_b variable of the member and the tick of encounter
links> show reputation_h
(link 1 0):
[[4.0900840358972825 1]
[0.8885953841506328 2]
[0.47017368072392984 3]]
(link 0 1): [[3.6805257472366164 1]
[3.6805257472366164 2]
[3.4201458793705326 3]]
reputation_h_w (containing the member's coop_b variable, the encounter time and the encounter time divided by the ticks):
links> show reputation_h_w
(link 0 1): [[3.6805257472366164 1 1]
[3.6805257472366164 1 0.5]
[3.6805257472366164 2 1]
[3.6805257472366164 1 0.3333333333333333]
[3.6805257472366164 2 0.6666666666666666]
[3.4201458793705326 3 1]]
(link 1 0): [[4.0900840358972825 1 1]
[4.0900840358972825 1 0.5]
[0.8885953841506328 2 1]
[4.0900840358972825 1 0.3333333333333333]
[0.8885953841506328 2 0.6666666666666666]
[0.47017368072392984 3 1]]
The problem is that reputation_h_w doesn't make sense to me - firstly there's six inputs instead of three, and secondly, the encounter time (item 1) and the encounter time/ticks (item 2) is off.
What am I doing wrong here?
Not sure where you update reputation_h_w in your code, but I'm guessing that you are not resetting it to a blank list before running your foreach loop again. So, it's lput-ing the values at the end of the list, which is not blank anymore.
Example setup:
breed [ as a ]
as-own [ coop_b ]
links-own [ reputation_now reputation_history reputation_history_w]
to setup
ca
create-as 2 [
set coop_b who + 1
setxy random-pxcor random-pycor
]
while [ any? as with [ not any? my-in-links ] ] [
ask one-of as with [ not any? my-out-links ] [
create-link-to one-of other as with [ not any? my-in-links ] [
set reputation_now []
set reputation_history []
]
]
]
reset-ticks
end
Note that here I will set reputation_history [] right before the foreach chunk runs:
to interact
if ticks > 0 [
ask links [
set reputation_now ( list [coop_b] of end2 ticks )
set reputation_history lput reputation_now reputation_history
; reset reputation history to a blank list, as you are
; recalculating the weighted value at each tick
set reputation_history_w []
foreach reputation_history [ x ->
let behavior item 0 x
let encounter_time item 1 x
let fraction encounter_time / ticks
set reputation_history_w lput (
list behavior encounter_time fraction ) reputation_history_w
]
show ( word "Current reputation: " reputation_now )
show ( word "Reputation history: " reputation_history )
show ( word "Weighted history rep list: " reputation_history_w )
]
]
tick
end
As far as why your ticks are off, I'd guess it's because you are calling tick after you run your horizontal_interact procedure. With the example above, my output looks like:
(link 0 1): "Current reputation: [2 2]"
(link 0 1): "Reputation history: [[2 1] [2 2]]"
(link 0 1): "Weighted history rep list: [[2 1 0.5] [2 2 1]]"
(link 1 0): "Current reputation: [1 2]"
(link 1 0): "Reputation history: [[1 1] [1 2]]"
(link 1 0): "Weighted history rep list: [[1 1 0.5] [1 2 1]]"
even though the ticks read 3. If you run it with tick at the start of the procedure, that might sort out your expected output.

A list containing NOBODY as one of its entities

I have a sub-routing in my code where each patch is asked to pick its closest & farthest turtle based on certain conditions. I keep getting this error after a couple of ticks
OF expected input to be a turtle agentset or turtle but got NOBODY instead.
error while patch 0 30 running OF
called by procedure UPDATE-SUPPORT
called by procedure GO
called by Button 'Go'
There are two other routines where a turtle dies or is born depending on a few other metrics that are measured. I am not able to debug the code but what i have figured so far is that it happens after a turtle dies or is born.
Below is the code based on which the closest & farthest turtles are assigned at each tick.
to update-support
ask patches [
let old-total sum [my-old-size] of parties
set f-party []
set h-party []
set party-list (sort parties)
set voteshare-list n-values length(party-list) [ (([my-old-size] of party ? ) + 1 ) / ( old-total + 1 ) ]
set party-citizen-dist n-values length(party-list) [ ( distance party ? ) ^ 2 ]
set f-list n-values length(party-list) [ ( ( 1 / ( item ? voteshare-list ) ) * ( item ? party-citizen-dist ) ) ]
set f-index position (min f-list) f-list
set h-list n-values length(party-list) [ ( ( item ? voteshare-list ) * ( item ? party-citizen-dist ) ) ]
set h-index position (max h-list) h-list
set f ((-1) * (min f-list))
set h max h-list
set f-party lput item f-index party-list f-party
set h-party lput item h-index party-list h-party
set closest-party first f-party
set farthest-party first h-party
]
After a turtle dies, when I inspected the patch which was throwing the error, i found the word nobody as an element in the list. The error is highlighted to be in the Party ? section while creating the voteshare-list in the above code
When I inspected the patch throwing the error, Party-list which is the list with all the current parties sorted was showing this:
Party-list: [(party 0) nobody (party 2)]
and my f-party list just had [(nobody)]
Has anyone faced such a situation.?
Below is the death & birth routine:
to party-death
ask parties [if (fitness < survival-threshold and count parties > 2)
[ die
] update-support
]
to party-birth
ifelse (endogenous-birth? = true)
[ ask one-of patches with [distancexy 0 0 < 30]
[ if (random-float 1 < (kpi * 1000)) [sprout-parties 1 [initialize-party] ]]
[ create-parties 1 [set heading random-float 360 jump random-float 30 initialize-party] ]
update-support
end

How does one achieve a square spiral like the the Ulam spiral in Netlogo?

I spent the morning trying to find an easy function (x,y) -> n that would number the patches like this
I was not successful. Do any of Y'all have any experience or suggestions?
Here is my take on it:
patches-own [ n ]
to setup
clear-all
resize-world -4 4 -4 4 ; so it looks better, but use any size you like...
create-turtles 1 [
set heading 180
foreach n-values count patches [ ? + 1 ] [
set n ?
if [ n = 0 ] of patch-left-and-ahead 90 1 [ left 90 ]
fd 1
]
die
]
ask patches [ set plabel n ]
end
Funny you should ask I also spent the morning doing the same thing. There is a function that uses the floor function but I remembered that this is netlogo
so I made a turtle do it for me.
with this procedure
to spin
let k 1
set t t + 1
repeat 2
[
lt 90
repeat t [fd 1 ask patch-here [set n k set k k + 1]]
]
end
and this code in the start up.
crt 1 [
set heading 0
repeat 41 [spin]
die
]
and of course
patches-own [n]
to call them in n order use
foreach sort-on [n] patches ask ? [ "the stuff you want them to do" ]