Sort nested list - netlogo

I found this code to sort nested list.
to-report test
let z [[2 3] [1 9] [3 1] ]
report sort-by [(first ?1) < (first ?2)] z
end
What is first ?1 and first ?2 in this formula. It says that they are not defined as variables.

Are you perhaps using NetLogo v6.0? Your code works in v5.3.1, but v6.0 uses anonymous reporters. It would look like:
to-report test
let z [[2 3] [1 9] [3 1] ]
report sort-by [[list1 list2] -> first list1 < first list2] z
end
Charles

Related

Working with index positions on a list in Netlogo

I'm struggling with the following problem using these variables:
set variablex .5
set threshhold-list [0 .3 .6]
set variable-list [0 0 1]
I have three agenttypes 0,1,2 that correspond to the index position of threshhold-list and variable-list. So Agent 0 has threshold 0 and variable 0, Agent 1 has threshold .3 and variable 0, and Agent 2 has threshold .6 and variable 1.
What I'd like to do is check if any agent has a threshold greater than zero and less than variablex. If so, update that agent's variable on the variable list to variablex. That is, for the variables above I'd like to run logic that produces a new variable-list like this one:
variable-list [0 .5 1]
But if variablex was .7, it would produce [0 .7 .7].
I've got some code I've been hacking away at but I feel like it's way more complicated than the problem and so I'm wondering if someone could point me in the right direction. Thanks so much!
There are a few different ways to approach the problem, but if I was in your situation, I would first write a small reporter that gives me the value that should be stored at each index:
to-report new-value [ i ]
let t item i threshhold-list
report ifelse-value (t > 0 and t < variablex)
[ variablex ] ; the variable's new value should be variable x
[ item i variable-list ] ; the variable's value should not change
end
Once you have that, you can use either foreach or map to change your variable list:
to update-variables-with-foreach
foreach range length variable-list [ i ->
set variable-list replace-item i variable-list new-value i
]
end
to update-variables-with-map
set variable-list map new-value range length variable-list
end
Here is a somewhat verbose test to check that both versions would give you the expected results:
globals [
variablex
threshhold-list
variable-list
]
to test
clear-all
set threshhold-list [0 .3 .6]
set variablex .5
set variable-list [0 0 1]
update-variables-with-foreach
print variable-list
set variablex .5
set variable-list [0 0 1]
update-variables-with-map
print variable-list
set variablex .7
set variable-list [0 0 1]
update-variables-with-foreach
print variable-list
set variablex .7
set variable-list [0 0 1]
update-variables-with-map
print variable-list
end
That being said, as much as I think it is fun to play with lists, I think you are approaching your problem in a very unnetlogoish way.
NetLogo's world is a world of turtles and patches and links, not a world of arrays and indices and numbers.
You could do something along the lines of:
globals [
variable-x
]
turtles-own [
threshhold
variable
]
to setup
clear-all
set variable-x .5
(foreach [0 .3 .6] [0 0 1] [ [t v] ->
create-turtles 1 [
set threshhold t
set variable v
]
])
ask turtles [ update-variable ]
ask turtles [ show variable ]
end
to update-variable ; turtle procedure
if threshhold > 0 and threshhold < variable-x [
set variable variable-x
]
end
I don't know what you're ultimately trying to achieve, but if I could offer general advice, it would be to try to embrace to NetLogo mindset. Every time you're tempted to use an index of some kind in your code, take a step back and think again: there is probably a better (as in "more netlogoish") way to do it.

Mean of Nested Lists

I'm trying to calculate the mean of nested lists. I have tried using the map function, but the default gives the mean in the opposite dimension that I am interested in. See the below example:
set a [[1 1][2 2][3 3]] ; create a nested list
set b map mean a ; b equals [1 2 3]
This answer gives [1 2 3] for b. However I am interested in the answer [2 2] by taking the mean in the "other" dimension. I would imagine there is a way to do this with map but haven't figured it out.
to go
print column-means [
[ 1 1 ]
[ 2 2 ]
[ 3 3 ]
]
end
to-report column-means [ matrix ]
if length (remove-duplicates map length matrix) > 1 [
error "All rows must be the same length"
]
report n-values length first matrix [ mean extract ? matrix ]
end
to-report extract [ i row ]
report map [ item i ? ] row
end
A possible solution is the following
set a [[1 2 3] [1 2 3]]
set b map mean a
this will give you [2 2] for b.

Random sized array and exactly three ones in it

Good morning,
I need to create a list of [0,1], which length is defined by the user (global variable). There is an easy solution for this:
set listInd (list n-values numOfInd [random 2])
But I need to make sure, that the list has exactly three ones in it and they are placed on random positions. Is there a way to do this?
Regards.
You can create 3 random numbers (indices) and then create a list with 1 on the positions defined by this index list:
to-report rand-list[n k]
let ind-list n-of k n-values n [?]
report n-values n [ifelse-value (member? ? ind-list) [1][0]]
end
Usage:
show rand-list 10 3
; result:
; [0 1 0 0 0 0 1 0 0 1]
An alternative to bergant's solution would be to gather the desired amount of ones and zeros, then mix them together randomly:
to-report rand-list [n k]
let zeros n-values (n - k) [0]
let ones n-values k [1]
report shuffle sentence zeros ones
end

How to write piecewise function in netlogo for agent simulation?

I'm doing Multi agent simulation using Netlogo, but in Netlogo, there is no suitable math expression for defining a piecewise function.
Anyone knows how to solve this ?
Many thanks!
to-report unitstep [#x]
report ifelse-value (#x < 0) [0] [1]
end
Edit:
If you want steps at multiple points, you could do this:
to-report n-steps [#x]
let steps [1 2 3]
let n 0
foreach steps [
set n (n + unitstep (#x - ?))
]
report n
end
I think it is best to write it functionally as a to-report
this snippet may help
to-report thing [X]
ifelse x < 10 and x > 5 [report 3][report x ^ 2]
end

“Expecting a constant value” error when constructing a NetLogo list

I am currently working to create a pictorial representation of the Levy C-Curve in NetLogo using an IFS construction scheme. I have found two functions which describe how to iteratively map the locations of two turtles and should result in the desired curve after thousands of iterations. Here is my code so far:
;;;;;; some useful complex operations
; to take re(z) of a complex number a + bi inputed as the list of coordinates [a b]
to-report re [z]
report first z
end
; to take im(z)
to-report im [z]
report last z
end
; to multiply two complex numbers
to-report complex_mul [z1 z2]
report list (re z1 * re z2 - im z1 * im z2)
(re z1 * im z2 + im z1 * re z2)
end
; to add complex numbers
to-report complex_add [z1 z2]
report list (re z1 + re z2)
(im z1 + im z2)
end
; to dilate complex numbers by a scalar fraction
to-report complex/real [z1 real]
report list (re z1 / real)
(im z1 / real)
end
; to initialize
to setup
ca
setup-turtles
reset-ticks
end
; create 2 turtles located at the initial set of points {0, 1}
to setup-turtles
crt 2
ask turtle 0 [ setxy 0 0]
ask turtle 1 [ setxy 1 0]
ask turtles [ pd]
end
; to create the first function to transform the turtle's location
to-report nextz_1 [z]
report complex/real (complex_mul [1 -1] z) 2
end
; to create the second function to transform the turtle's location
to-report nextz_2 [z]
report complex_add [1 0]
(complex/real (complex_mul [1 1]
(complex_add z [-1 0]))
2)
end
; finally we are creating the Levy Curve
to levy
ask turtles [ run one-of (list task setxy re (nextz_1 [xcor ycor]) im (nextz_1 [xcor ycor])
task setxy re (nextz_2 [xcor ycor]) im (nextz_2 [xcor ycor])
)
]
end
However, I'm receiving an error message in my "levy" code block where I call re (nextz_1 [xcor ycor]) etc., saying that NetLogo is expecting a constant value in place of xcor and ycor.
How would I fix this issue?
At http://ccl.northwestern.edu/netlogo/docs/faq.html#listexpectedconstant the NetLogo FAQ says:
If a list contains only constants, you can write it down just by putting square brackets around it, like [1 2 3].
If you want your list to contain items that may vary at runtime, the list cannot be written down directly. Instead, you build it using the list primitive.
You actually got this right in some other places in your code, but in the levy procedure, you need to replace e.g. [xcor ycor] with list xcor ycor.
To NetLogo, [xcor ycor] looks like a reporter block, not like a list.