I have tried several different ways using different list primitives, but cannot find a way to test an inequality for each item of a list. For example, my list [1 2 -1 -2] could be tested for > 0, and give [1 2 0 0 ]. Can someone please help with this simple task.
There's a couple ways to do this, depending on the result you want. For your example, you can do:
map [ ifelse-value (? > 0) [ ? ] [ 0 ] ] my-list
map creates a new list by applying the given reporter task to each item of the given list. If you haven't used tasks in NetLogo before, ? represents the argument to the task. So, in this case doing:
map [ ifelse-value (? > 0) [ ? ] [ 0 ] ] [1 2 -1 -2]
basically does:
(list ifelse-value (1 > 0) [ 1 ] [ 0 ]
ifelse-value (2 > 0) [ 2 ] [ 0 ]
ifelse-value (-1 > 0) [ -1 ] [ 0 ]
ifelse-value (-2 > 0) [ -2 ] [ 0 ])
ifelse-value is like ifelse, except that it returns the value in the block that runs.
If, you just want to get rid of all items in the list that fail the inequality, you can use filter
filter [ ? < 0 ] my-list
map and filter are very powerful reporters, but they can take a little while to master. But, if you need to do something fancy with lists, chances are you can do it with map, filter, or (in more extreme cases) reduce.
Related
I am trying to represent a multi-scale environment where I have large patches that represent high-value areas in the landscape and smaller patches that have local information. E.g. I want to have snow data at a 1km^2 scale but I also want to have larger patches (9km^2) that summarize large-scale information. Each of my large patches has a variable value that is different from its neighbors but the variable value may be repeated throughout the landscape in other patches. I am looking for the most straightforward way for my turtles to identify the difference between the large-scale patches. I had thought of creating patch-sets but I am not sure how to get around the issue of variable values repeating in different patches. Any help is much appreciated.
EDIT: I have created a raster with equal patch structure as the large-scale raster and assigned "patch-id's" using this, so that there is no longer variable repetition in the world. I am still struggling with getting turtles to identify these larger patches as grouped entities.
You commented on my first answer
My main issue is that I need to run a "find max-one-of
neigboring-large-patches [large-scale-variable]" so I need my turtles
to understand what the neighboring large-patches are and be able to
read them as units, if that makes sense. I can't quite figure out how
to incorporate that into your answer, any thoughts?
Here's how to do that. This code is fast and sloppy but it illustrates the point.
Let the large-regions have x and y values, generated during creation. Basically, these store the column and row numbers of the grid of large regions that covers the viewport.
breed [ large-regions large-region ]
large-regions-own [
terrain
region-color
population
x
y
]
Then, conceptually, the neighbors of a region will have x and y values within +/- 1 of the region's x and y values, so you can identify them that way.
To simplify coding at the expense of space, when I generated the regions I also stored the unique identifier (who) of that region and its x and y values into every patch in that region, in variables lrx and lry.
patches-own [
large-region-who
lrx
lry
]
The heart of finding the neighboring large-region with the max value of population as you requested follows. I coded this for speed in debugging , not for elegance, so it can be greatly cleaned up. The full source code has many print statements that effectively comment each step in solving your requested search.
This looks around (patch 0 0), finds the info on the large region's x and y from that patch, generates an agent-set of large-regions with nearby x and y values, does a max [population] search on that set to extract the region with the highest population. It also colors the asking patch black, the local large-region blue, and the maximum population neighbor red.
It mostly works -- the large regions are offset by one patch from where they should be -- but this illustrates the point. Run setup and go and see for yourself.
Here's the (ugly) code to play with. Interesting problem. You can easily extend this to small regions as well, and have both working at the same time. Enjoy!
globals [
large-region-size
]
breed [ large-regions large-region ]
large-regions-own [
terrain
region-color
population
x
y
]
patches-own [
large-region-who
lrx
lry
]
to setup
clear-all
set large-region-size 5
no-display
make-large-regions
ask patches [ set pcolor white ]
display
ask large-regions [ set hidden? true]
print (word " hilly region count: " count large-regions with [terrain = "hilly"] )
;; print (word " deep snow count: " count small-regions with [snow-cover > 75])
reset-ticks
end
to go
ask patches [ set pcolor white]
; ;; lets examine the large-regions
; print " large region xvals "
; let xvals [ ]
; ask large-regions [ set xvals fput x xvals ]
; set xvals remove-duplicates xvals
; show xvals
; print " "
; print " patch lrx values: "
; set xvals [ ]
; ask patches [ set xvals fput lrx xvals ]
; set xvals remove-duplicates xvals
; show xvals
; print "========================================="
print " let's examine large-regions around the patch at 0 0 "
let x-spot 0
let y-spot 0
print ( word " looking for large-regions with max population bordering the following patch " x-spot " " y-spot)
; ask n-of 1 patches [ set x-spot pxcor set y-spot pycor print (word "selected patch " x-spot ", " y-spot )]
let home-who [ large-region-who] of patch x-spot y-spot
print (word "home-region-who is " home-who)
print " "
;; thinking ahead, we have coded the x and y values of the large region around us directly into the patch variables
let home-x [ lrx ] of patch x-spot y-spot
let home-y [ lry ] of patch x-spot y-spot
print (word "this blue home region has x=" home-x " and y=" home-y )
ask patches with [lrx = home-x and lry = home-y] [ set pcolor blue ]
ask patch x-spot y-spot [ set pcolor black ]
let home-neighbor-set large-regions with [
( x >= ( home-x - 1 )) and ( x <= ( home-x + 1) ) and (y >= ( home-y - 1 ) ) and ( y <= ( home-y + 1 ) ) ]
print "count of home-neighbor-set is "
print count large-regions with [
( x >= ( home-x - 1 )) and ( x <= ( home-x + 1) ) and (y >= ( home-y - 1 ) ) and ( y <= ( home-y + 1) ) ]
print " "
print "here is that set "
show home-neighbor-set
print " "
ask home-neighbor-set [ print (word "Large region with who = " who " has population " population )]
let big-boy max-one-of home-neighbor-set [ population]
show big-boy
print ( word " Neighboring red large-region with largest population is " big-boy " with population " [population] of big-boy )
let bbx 0
let bby 0
let bwho 0
ask big-boy [ set bbx x set bby y set bwho who]
ask patches with [lrx = bbx and lry = bby] [ set pcolor red ]
tick
end
to make-large-regions ;; for testing
let px min-pxcor
let py min-pycor
let region-id -1 ;; missing
let mysize large-region-size
let stopper 0
while [px < max-pxcor] [
while [py < max-pycor] [
if stopper > 300 [ stop ] ;; stops making large regions
set stopper stopper + 1
let xcode round ( ( px + 1) / 5)
let ycode round ( ( py + 1) / 5)
;; make a new region
let decolor one-of [ red blue yellow green ]
create-large-regions 1 [
set terrain one-of ["hilly" "flat" "mountain" "water" "swamp"]
set region-id who
set population random 1000
set x xcode
set y ycode
set region-color decolor
]
;; large region is defined, update the patches in that region
ask patches with [ (abs (pxcor - px) < (mysize / 2) )
and (abs (pycor - py) < (mysize / 2) )] [
set pcolor decolor
set large-region-who region-id
set lrx xcode
set lry ycode
]
set py py + mysize
]
if py > max-pycor [
set py min-pycor
set px px + mysize]
]
end
This may not be the best way, but I think it would work. You could let regions own several variables, such as "large-region-unique-id" and "small-region-unique-id" and make one pass where you set all these variables. Then a turtle would only have to look at a patch to know what small and large region it is part of.
If you also made a breed of agents called "regions" (say), you could have regions-own variables and have a unique-region-id. ( actually, the agent's who number would work
for that)
That should encode the information so that a moving turtle could easily look up relevant information.
breed [ large-regions large-region ]
large-regions-own [
terrain-type
large-scale-variables
...
(who)
]
breed [ small-regions small-region ]
small-regions-own [
snow-cover
small-scale-variables
...
(who)
]
patches-own [
large-scale-region-who ;; the id (who) of the large-scale-region the patch is in
small-scale-region-who ;; the id (who) of the small-scale-region the patch is in
...
]
Then a turtle could ask a patch for the relevant who information and use it to look up data from the larger "patches".
Here's what that might look like
print (word " hilly region count: " count large-regions with [terrain = "hilly"] )
print (word " deep snow count: " count small-regions with [snow-cover > 75])
;; how about highlighting patches that are mountainous with deep snow?
no-display
ask patches [
set terrain-type ""
set my-snow-cover -1
set srw small-scale-region-who
if srw > 0 [set my-snow-cover [snow-cover] of (small-region srw)]
set lrw large-scale-region-who
if lrw > 0
[ set terrain-type [terrain] of large-region lrw]
if-else (terrain-type = "mountain") and (my-snow-cover > 75)
[ set pcolor white ]
[ set pcolor black ]
]
display
print " The mountainous terrain with deep snow-cover is shown in white "
I've been using this post (how to do replacing-item in use nested list) as a guide to work out how to replace items in a list, that meet a given criteria.
Specifically, I want to replace all zeros in a list with the value = 0.5. However, the code I've come up with only seems to replace the first zero in the list and I can't seem to work out why.
This is my code:
to-report A-new-list-without-zeros [old new the-list]
let A-index-list n-values length the-list [?]
( foreach A-index-list the-list
[ if ?2 = old
[ report replace-item ?1 the-list new ]
])
report the-list
end
And this is what happens:
observer> show A-new-list-without-zeros 0 0.5 [0 1 0 5 5 0]
observer: [0.5 1 0 5 5 0]
Any help would be much appreciated! Thanks
This task is more easily accomplished with map than foreach.
NetLogo 6 syntax:
to-report A-new-list-without-zeros [old new the-list]
report map [[x] -> ifelse-value (x = old) [new] [x]] the-list
end
NetLogo 5 syntax:
to-report A-new-list-without-zeros [old new the-list]
report map [ifelse-value (? = old) [new] [?]] the-list
end
Anytime you use report, it exits the procedure and reports the output at that point. The quick fix using your code is to change the report line in your if statement so that it replaces the item at the current index:
to-report A-new-list-without-zeros [old new the-list]
let A-index-list n-values length the-list [?]
( foreach A-index-list the-list
[ if ?2 = old
[ set the-list replace-item ? the-list new ]
])
report the-list
end
observer> print A-new-list-without-zeros 0 0.5 [ 0 1 0 5 5 0 ]
[0.5 1 0.5 5 5 0.5]
I've tried to find a way to do this more neat/more efficient cause I don't believe that I wouldn't be able to achieve the same result more efficient.
I have a csv file containing data with initial states for my turtles. Each row represents values for turtle-owned variables and each column represents an individual turtle. For each turtle, I would like to initialize his variables. At this moment I'm doing it the following way (which works, but to me looks not efficient):
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; GENERAL PROCEDURES ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
extensions [ csv ]
breed[households household]
globals ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[
HH-data
HHx-list
HHy-list
HHsize-list
HHcolor-list
]
households-own ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[
HHx
HHy
HHsize
Hhcolor
]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; SETUP PROCEDURES ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
to startup ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
set HH-data (csv:from-file "TestHH.csv" ";")
show HH-data
set HHx-list item 0 HH-data
set HHy-list item 1 HH-data
set HHsize-list item 2 HH-data
set HHcolor-list item 3 HH-data
show HHx-list
let numberOfHH length HHx-list
create-households numberOfHH
(
foreach (sort households) HHx-list
[ [?1 ?2] -> ask ?1
[
set xcor ?2
]
]
)
(
foreach (sort households) HHy-list
[ [?1 ?2] -> ask ?1
[
set ycor ?2
]
]
)
(
foreach (sort households) HHsize-list
[ [?1 ?2] -> ask ?1
[
set HHsize ?2
]
]
)
(
foreach (sort households) HHcolor-list
[ [?1 ?2] -> ask ?1
[
set color ?2
]
]
)
end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
However, in the global HH-data already all my data is present. How could I extract this and assign the turtle variables to each turtle without having to make all these individual for-each statements. I tried a few things like this:
set HH-data (csv:from-file "TestHH.csv" ";")
show HH-data
let numberOfHH length (item 0 HH-data)
create-households numberOfHH
(
foreach (sort households) HH-data
[[?1 ?2] -> ask ?1
[
set xcor ?2
set ycor ?2
set HHsize ?2
set HHcolor ?2
]
]
)
But then I keep getting errors.
Found out myself, while I was writing this question, how to solve it.
Thought it might be useful to others and thus therefore to still post it.
set HH-data (csv:from-file "TestHH.csv" ";")
;;show HH-data
let numberOfHH length (item 0 HH-data)
create-households numberOfHH
(
foreach (sort households) (item 0 HH-data) (item 1 HH-data) (item 2 HH-data) (item 3 HH-data)
[[?1 ?2 ?3 ?4 ?5] -> ask ?1
[
set xcor ?2
set ycor ?3
set HHsize ?4
set color ?5
]
]
)
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]
I would like to do the following with maple
let
omega := z -> 2*<Re(z), Im(z), 1>/(1+abs(z)^2):
and
phi := -> z (l*z+a)/(1-l*conjugate(a)*z):
where a is complex and l is real.
I consider Omega=omega( phi(z) ) and i would like to evaluate diff(Omega,x) diff(Omega,y) but also compute some limit like
> expr := omega(phi(1/e));
> Omega := simplify(map(limit, expr, e = 0));
> expr2 := (omega(phi(1/(e^2*conjugate(z))))-Omega)/e^2;
> H := limit(expr2, e = 0);
Unfortunately i have tried every thing (Vector Calculus , Complex...) and i have always a probleme either because i work with vector or because the variable is complex.
Does someone have any idea of the good way to code such a problem?
Thx
[edited:] I cannot tell whaht your original definition of operator phi is, as there is a syntax error in the original post (invalid syntax). In particular I cannot tell whether you meant,
phi := z -> (l*z+a)/(1-l*conjugate(a)*z):
or,
phi := z -> z (l*z+a)/(1-l*conjugate(a)*z):
I used the former below. The results will depend upon the choice, of course.
In a previous question by you an answer involved using evalc, under which all unknowns would be treated as real.
But now you seem to have a mix, where l is to be taken as real while a may be complex.
As shown in your earlier question another approach is to use assumptions on the unknowns, which in this case can give finer control over your mix.
Note that a will get treated as being possibly complex, by default. So we can use an assumption on just l.
restart:
omega := z -> 2*<Re(z), Im(z), 1>/(1+abs(z)^2):
phi := z -> (l*z+a)/(1-l*conjugate(a)*z):
expr := omega(phi(1/e)):
map(limit,expr,e=0) assuming l::real:
map(simplify,%);
[ 2 Re(a) ]
[- ----------]
[ 2 ]
[ | a | + 1]
[ ]
[ 2 Im(a) ]
[- ----------]
[ 2 ]
[ | a | + 1]
[ ]
[ 2 ]
[ 2 | a | ]
[ ---------- ]
[ 2 ]
[ | a | + 1 ]
Here is another way to get a result. We could let a=S+T*I and use evalc to handle altogether the assumptions that S and T (and l) are purely real.
map(limit,subs(a=S+T*I,expr),e=0) assuming l::real:
simplify(map(evalc,%));
[ 2 S ]
[- -----------]
[ 2 2 ]
[ S + T + 1]
[ ]
[ 2 T ]
[- -----------]
[ 2 2 ]
[ S + T + 1]
[ ]
[ 2 2 ]
[ 2 (S + T ) ]
[ ----------- ]
[ 2 2 ]
[ S + T + 1 ]