NetLogo database resultlist loading problem - netlogo

I am trying to get some integer values from database (almost 30.000 rows) and it gives error "error while observer running READ-FROM-STRING in procedure GET-IMAGEDB Expected a constant." I considered it may happen because of requiring waiting time to not set a null value to variable of NetLogo and added "print" lines to delay the process. It worked for small sized datasets for instance 30.000 rows. However, when the dataset size increased to 250.000 rows, now I am getting same error again. I am not sure about reason of the error. I have also tried to get all rows from the dataset with single query and set it to NetLogo list, but still gives same error and extremely slow. I have attached the code. Thank you for any help.
let total ( (width + 1) * (height + 1) )
let counter 0
while [ counter < total ]
[ set query "select x, y, r, g, b, background from colorinfo where pixelId = \""
set query (word query counter "\"" )
let resultList (mysql:executeQuery db query)
let stringList item 0 resultList
print (word "wait 1")
let x read-from-string item 0 stringList
print (word "wait 2")
let y read-from-string item 1 stringList
let r read-from-string item 2 stringList
let g read-from-string item 3 stringList
let b read-from-string item 4 stringList
let background read-from-string item 5 stringList
ask patch (x + width + 2) ( y) [ set pcolor (list r g b) ]
print counter
set counter (counter + 1)
set stringList [ ]
set resultList [ ]
]

Related

Cannot find item in list based on index in NetLogo

im using a sorted list in netlogos but when i run my code i get an error message that it can't find element 3 because the lenght of the list is 3, that sounds really strange and counter intuative to me. what goes wrong
globals [
allehøjder
min_højde
nedre_højde
median_højde
øvre_højde
max_højde
]
breed [personer en_person]
personer-own [højde skostørrelse]
to setup ; runs when the button "setup" is pressed
clear-all
;kom alle højder ind i højde
;sorter højde listen
;find 5 kvartil værdien ud fra højder[]
create-personer 3
[
set color white
set højde (150 + ( random ( 190 - 150 )))
set skostørrelse (38 + (random ( 47 - 38 )) )
setxy random-xcor random-ycor
set size 10
]
set allehøjder [højde] of personer
set alleskostørrelser [skostørrelse] of personer
show sort allehøjder
show sort alleskostørrelser
;sætter de 5 kvartilværdier for højde
; sætter min
set min_højde item 1 (sort allehøjder)
;sætter max
**bold** set max_højde item 3 (sort allehøjder)
; sætter median
ifelse 3 mod 2 = 0
;lige antal
[
set median_højde item ((3 + 1 / 2) ) (sort allehøjder)
]
;ulige antal
[
set median_højde ((item ((3 + 1) / 2) (sort allehøjder) + item (((3 + 1) / 2) + 1) (sort allehøjder)) / 2)
]
reset-ticks
end
regards morten
The indexing of lists' items starts from 0, hence the third element will have index 2.
The NetLogo Programming Guide and the NetLogo Dictionary linked above should have you covered with this type of problems.

Is there a simple way to code for a sequence of multiples of ticks in netlogo?

How do I have a model decrease a variable by some increment every x ticks, without simply coding a long list? It seems like there should be a way to use multiples of ticks, e.g decrease the variable every 20n ticks, where n = 1, 2, 3,..., but I couldn't think of how that would work, so I just created a list.
For example, in the code below, I am decreasing the variable octopamine-level by 1 unit every 20 ticks past first-leader-tick.
if (ticks - first-leader-tick = 20) or (ticks - first-leader-tick = 40) or (ticks - first-leader-tick = 60) or (ticks - first-leader-tick = 80) or (ticks - first-leader-tick = 100) or (ticks - first-leader-tick = 120) or (ticks - first-leader-tick = 140) or (ticks - first-leader-tick = 160) or (ticks - first-leader-tick = 180)
[set octopamine-level octopamine-level - 1]
However, I am planning on using a much larger variable, which would require a ridiculously long list, so a cleaner method would be very helpful.
Thanks!
Simple approach #1
You can use a reminder for the next time that the value needs to be updated:
globals [
next-update
octopamine-level
]
to setup
clear-all
reset-ticks
set octopamine-level 10
type "initial level of octopamine: " print octopamine-level
set next-update "none" ; This is needed because, otherwise, the first iteration (i.e. where
; 'ticks = 0') would always satisfy the 'if (ticks = next-update)'
; condition. Doing 'set next-update - 1' would work too, depending on
; which approach you find more relevant and/or elegant.
end
to go
; With this first block of commands I'm just randomly choosing the
; initial tick for starting the reduction.
if (octopamine-level = 10) AND (random 100 < 1) [
set octopamine-level octopamine-level - 1
set next-update ticks + 20
type "ticks = " type ticks type ", octopamine = " type octopamine-level print ", reduction started"
]
if (ticks = next-update) [
set octopamine-level octopamine-level - 1
set next-update ticks + 20
type "ticks = " type ticks type ", octopamine = " print octopamine-level
]
if (octopamine-level = 0) [stop]
tick
end
Simple approach #2
If you also want to have the information more readily accessible about how long will it take until the next update / how long has passed since the last update, you can create a counter:
globals [
counter
counter-on? ; See comment to in 'to setup'.
octopamine-level
]
to setup
clear-all
reset-ticks
set octopamine-level 10
type "initial level of octopamine: " print octopamine-level
set counter "none"
set counter-on? FALSE ; This, together with the condition in which it is used, is needed
; because we cannot simply 'set counter "none"', as that will give
; a runtime error when executing 'set counter counter - 1' (and using
; 'if (is-number? counter) [set counter counter - 1]' doesn't look
; very nice to me).
; Note that you could get rid of all the 'counter-on?' thing and just
; do 'set counter -1' upon setup. This would work, but would also
; execute 'set counter counter - 1' at every tick, bringing 'counter'
; to always more negative numbers before the reduction actually starts -
; which I personally don't really like.
end
to go
; With this first block of commands I'm just randomly choosing the
; initial tick for starting the reduction.
if (octopamine-level = 10) AND (random 100 < 1) [
set counter-on? TRUE
set counter 20
set octopamine-level octopamine-level - 1
type "ticks = " type ticks type ", octopamine = " type octopamine-level print ", reduction started"
]
if (counter = 0) [
set octopamine-level octopamine-level - 1
set counter 20
type "ticks = " type ticks type ", octopamine = " print octopamine-level
]
if (octopamine-level = 0) [stop]
if (counter-on?) [
set counter counter - 1
]
tick
end
Another positive side of this approach is that it makes it simple to pause and resume the counter anytime you want if you ever need to, simply by using set counter-on? FALSE and set counter-on? TRUE.
Less simple approach
To take an approach that looks more similar to your line of thought (but more convoluted than the previous options), this kind of need can also be addressed by using remainders, and in NetLogo you can use remainder indeed (check here).
You can use the following routine to perform a command every 20 ticks.
if (remainder ticks 20 = remainder first-leader-tick 20) [
set octopamine-level octopamine-level - 1
]
Overall, performing the type of adjustments that I discussed for the other approaches earlier, it would look something like:
globals [
first-leader-tick
reduction-on?
octopamine-level
]
to setup
clear-all
reset-ticks
set octopamine-level 10
type "initial level of octopamine: " print octopamine-level
set reduction-on? FALSE
end
to go
; With this first block of commands I'm just randomly choosing the
; initial tick for starting the reduction.
if (octopamine-level = 10) AND (random 100 < 1) [
set reduction-on? TRUE
set first-leader-tick ticks
set octopamine-level octopamine-level - 1
type "ticks = " type ticks type ", octopamine = " type octopamine-level print ", reduction started"
]
if (reduction-on?) AND (ticks > first-leader-tick) AND (remainder ticks 20 = remainder first-leader-tick 20) [
set octopamine-level octopamine-level - 1
type "ticks = " type ticks type ", octopamine = " print octopamine-level
]
if (octopamine-level = 0) [stop]
tick
end
The (reduction-on?) condition is needed because otherwise tick 0 will always pass the test (in fact it is true that remainder 20 20 = remainder 0 20).
The (ticks > first-leader-tick) condition is needed because (remainder ticks 20 = remainder first-leader-tick 20) is true also when the reduction starts (i.e. when ticks = first-leader-tick), which would bring to execute twice set octopamine-level octopamine-level - 1 on the tick when the reduction starts (once in the first if-block and once in the second if-block).
Alternatively, if you want you can get rid of the (ticks > first-leader-tick) condition by either:
removing the set octopamine-level octopamine-level - 1 line from the first if-block;
bringing the second if-block (the one where remainders are evaluated) before the first if-block (the one where the reduction is initiated).
Very simply, you can use the MOD operator to do this.
MOD does a division, then returns the remainder.
This has the great side effect of always returning a number between 0 and one less than the divisor.
Even more simply: ticks MOD 20 always gives a number between 0 and 19. 100 mod 20 is 0. 119 mod 20 is 19. 120 mod 20 is zero again. See? Neat, right?
So you could do
If (ticks - first-leader-tick) mod 20 = 0
[
;; do the thing you do every 20 ticks.
]
Note that this will make it do the thing the first time, too. So adjust your logic accordingly.

NetLogo addition of nominal values giving unusual results

When a variable is being incremented by very small value (say 0.01), it is not giving proper (precise) results as expected.
Looking for suggestions(if any) to deal with the same.
globals[p]
to go
set p 0
while[p <= 1]
[
print p
set p p + 0.01
]
end
First read this:
http://floating-point-gui.de/
Then to subdivide an interval into n pieces, do this:
to-report subdivide [#xmin #xmax #n]
let ps n-values (#n + 1) [? / #n]
report map [#xmin + ? * (#xmax - #xmin)] ps
end

How make a list of cumulative sum in netlogo

How can i make a list of cumulative sum of a other list?
i tried it that way:
;;all temperatrue-values around the turtle saved in list
set temperature_values (list [(output-heat + 1)^ Freedom] of neighbors)
;;build cumulative value of temperatures and put each value in list
let tempsum 0
set tempsum_list []
foreach temperature_values
[set tempsum (tempsum + ? )
set tempsum_list fput tempsum tempsum_list
]
but it doesn't work. can anyone fix this problem? it says that "+ excepted a input but gets a list instead".
your code for a cumulative sum works (except that I think you need lput rather than fput. You can see it with this:
to test
let ll [1 2 3 4]
let tempsum 0
let tempsum_list []
foreach ll
[ set tempsum (tempsum + ? )
set tempsum_list lput tempsum tempsum_list
]
print tempsum_list
end
Did the error highlight the line set temperature_values (list [(output-heat + 1)^ Freedom] of neighbors)? Try putting a space after between ) and ^. NetLogo is picky about space around mathematical operators.
As Jen suggested, you can use foreach. Another nice approach is reduce:
to-report partial-sums [#lst]
set #lst (fput [0] #lst) ;;prepare for reduce
report butfirst reduce [lput (?2 + last ?1) ?1] #lst
end
Similar to Alan's solution (Just an update for the recent version of NetLogo that replaces ? with -> for anonymous procedures.)
to-report partial-sums [lst]
report butfirst reduce [[result-so-far next-item] -> lput (next-item + last
result-so-far) result-so-far] fput [0] lst
end
This is like Alan's solution, just abstracted a bit further. (Perhaps too far, depending on your taste! I like JenB's solution as well.)
Let's first define a thing like reduce, but that keeps all the intermediate results:
to-report scan [fn xs]
report reduce [lput (runresult fn ?2 last ?1) ?1]
(fput (list first xs) butfirst xs)
end
Now we can use it to compute partial sums:
observer> show scan task + [1 2 3 4 5]
observer: [1 3 6 10 15]
but we are also free to swap in a different operation:
observer> show scan task * [1 2 3 4 5]
observer: [1 2 6 24 120]

Nested foreach in NetLogo

I am trying to calculate the Gini coefficient of a set of numbers. The Gini coefficient is half the mean absolute difference. That is, for every possible pair of numbers in the list, I need to take their absolute difference and add these differences together (and some other stuff). This is my code
to-report calc-Gini [list-Values]
let sumdiff 0
foreach list-Values
[ foreach list-Values
[ set sumdiff sumdiff + abs ( ?1 - ?2 )
]
]
report 0.5 * sumdiff / (mean list-Values * (length list-Values) ^ 2)
end
When I test it (eg show calc-Gini (list 1 2 3)) I get an error "task expected 2 inputs, but only got 1" on the second foreach.
I think the problem is that NetLogo wants to run through the foreach loops simultaneously. So if the list length is N, then it creates only N pairs (that is, first item in list1 and first item in list2, then the second item in each list etc) which is where the requirement for equal length lists comes from. But I need it to work with the N^2 pairs obtained by crossing the lists.
How can I make the nested foreach do what I want and/or is some other primitive more appropriate?
NetLogo doesn't have a mechanism for binding ?1 and ?2 to an outer and an inner task. When it sees ?1 and ?2 in your code, it expects that both inputs will come from the inner task. And since the inner foreach only provides one input, NetLogo complains.
You can get around that problem by simply assigning the input of the outer foreach to a local variable:
to-report calc-Gini [list-Values]
let sumdiff 0
foreach list-Values
[ let v ?
foreach list-Values
[ set sumdiff sumdiff + abs ( v - ? )
]
]
report 0.5 * sumdiff / (mean list-Values * (length list-Values) ^ 2)
end
That being said, here is an alternative implementation:
to-report calc-gini [ xs ]
report 0.5 * sum map [ sum-diff ? xs ] xs / (mean xs * (length xs) ^ 2)
end
to-report sum-diff [ x xs ]
report sum map [ abs (x - ?) ] xs
end
I can't solve your nested foreach approach, but this might be an alternative way to do your calculation:
If you use ordered data, you can use this equation for the Gini coefficient (given a vector $y$ with $y_i$, $i=1,...,n$)
$$ G(y) = \frac{1}{n} (n + 1 - 2 * \frac{ \sum_{i=1}^{n} (n + 1 - i) y_{i} }{ \sum_{i=1}^{n} y_i} $$
and the following reporter should deliver the result in NetLogo:
to-report calc-Gini [list-Values]
let values sort list-Values ; making sure values are in a non-decreasing order
let n length values
let i 1
let numerator []
foreach values
[ set numerator lput ( (n + 1 - i) * ? ) numerator
set i i + 1
]
report 1 / n * ( n + 1 - 2 * (sum(numerator) / sum(values)) )
end