How to add a row to a matrix in NetLogo? - netlogo

I have a 2*2 matrix called orders:
0 0
0 0
created by:
set orders matrix:from-row-list [[0 0] [0 0]]
and I would like to change it to be a 3*2 matrix:
0 0
0 0
10 50
How to do this please? (I guess you have to create a new matrix also called orders to overwrite the existing orders, but I couldn't figure out the syntax.)

The easiest way would probably be to first convert your matrix to a list, than add the new row to the list, and convert it back to a matrix. Not very elegant, but the report function below should do the trick:
extensions [ matrix ]
to-report matrix-add-row [matrix row-added]
let temp-list matrix:to-row-list matrix ;; converts the matrix to a list
set temp-list lput row-added temp-list ;; the new row is added to the list
report matrix:from-row-list temp-list ;; converts the list back to a matrix
end
to test
let orders matrix:from-row-list [[0 0] [0 0]]
show orders
show matrix-add-row orders [ 10 50 ]
end
This would return you:
observer> test
observer: {{matrix: [ [ 0 0 ][ 0 0 ] ]}}
observer: {{matrix: [ [ 0 0 ][ 0 0 ][ 10 50 ] ]}}
Of course, you have to make sure that the dimensions of the matrix and the row added match.

Just in case this helps someone else, what I did in the end was use a new agent breed 'orders' in place of the matrix, with each orders turtle essentially being what would have been a row in the matrix. I told the orders to sit on the same patch as the turtle that owned it, which was easy as the turtles in that model don't move. The advantage is that I had access to a wide range of processing possibilities that I didn't have with the matrix. Of course if you do this and the order of the rows matters, you need to include some way of managing this (something like orders-own [index] would do).

Related

Sort list by one item and identify record that meets a condition in Netlogo

I have a list of sublists, something like the following
[[0 “coal” 500 1430] [0 “gas” 300 1300] [1 “coal” 600 1500] [1 “gas” 700 1400]]
I would like to do four things:
1. Sort the main list by item 3 of sublists
2. Cumulatively sum item 2 of sublists until a certain value is reached.
3. Identify item 3 of the last list added.
4. Then I’d like to identify items 0 and 1 of lists that were added to the loop in point 2 and ask those turtles to do something.
I've been exploring tables, lists, etc but struggling with this complex bit of code. Can people suggest how they would code this?
Thanks in advance for the help!
The following seems to answer the case, I think...though there may be more elegant ways
to go
create-turtles 2
let l [[0 "coal" 500 1430] [0 "gas" 300 1300] [1 "coal" 600 1500] [1 "gas" 700 1400]]
;sort the list by item 2
let sorted sort-by bigger l
show sorted
;accumulate item 3 until limit reached
let k 0
let n 0
let limit 2800
let turtleNos []
let fuels []
while [k < limit]
[
set k k + item 3 ( item n sorted )
;accumulate item 0 and 1
set turtleNos lput item 0 ( item n sorted ) turtleNos
set fuels lput item 1 ( item n sorted ) fuels
set n n + 1
]
show k
;show item 3 for the last item added to k
show item 3 (item ( n - 1 ) sorted)
;accumulated lists - note non-unique
show turtleNos
show fuels
(foreach turtleNos fuels
[ [x y] -> ask turtle x [show y] ])
end
to-report bigger [l1 l2]
report item 2 l1 > item 2 l2
end

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

Netlogo - Sandpile Model - update count - runtime Error

At each tick i am asking each patch to update its count dependent on that of its 8 neighbours. If more than 4 neighbours have a count more than or equal to 1 then they update by 1. If more than 4 neighbours have a count less than or equal to 1 then the patch count should be set to 0.
When i run the code i get the following error:
"The >= operator can only be used on two numbers, two strings, or two agents of the same type, but not on a TRUE/FALSE and a number.error while patch 27 -22 running >= called by procedure SPREAD-ERRORS called by procedure GO"
to spread-errors ;; Errors spread prior to addition of random error
;; This is dependent upon majority of neighbors with errors
ask patches [
ifelse count neighbors with [n >= 1] > 4
[update-n 1]
[set n n = 0]
]
end
You mean set n 0, not set n n = 0.
But why is set n n = 0 actually valid NetLogo syntax, and how did it end up leading to the error message you get?
Well, n = 0 is a boolean expression whose value is either true or false. Then you're taking that value and storing it in n. The effect is as if you had written:
ifelse n = 0 [ set n true ] [ set n false ]
after this command runs, n holds a boolean. Then the next time n >= 1 runs, you get the error message above, since n is no longer a number and can't be compared with 1.