I would create a periodic function in Netlogo based on ticks and a price variable.
I would like a function where price is maintained between 2 rang (0 and 1) and I will be great if I can choose the periodicity.
my small reproducible example :
patches-own[
price
]
to setup
clear-all
ask patches [
set price 0.1
]
reset-ticks
end
to go
ask patches [
set price (sin ticks) + price
]
tick
end
Thank you in advance
It sounds like you just want a mod based cycle.
to test
ca
reset-ticks
print map price n-values 100 [?]
print map [price02 0 1 ?] n-values 100 [?]
end
to-report price [#ticks]
let _cycle 10 ;cycle length
let _first 3 ;length of first cycle component
report ifelse-value (#ticks mod _cycle < _first) [
0.1
][
0.2
]
end
Edit:
Alternatively, you may simply be trying to scale a sine wave.
to-report price02 [#min #max #ticks]
let _cycle 10
let _sin sin (#ticks * 360 / _cycle)
let _scaledsin (1 + _sin) / 2
report #min + (#max - #min) * _scaledsin
end
Related
I would like to set a regular grid of turtles. With the following example, I have gotten to distribute the reader agents equally spaced in the x dimension, but I can not set a maximum number of agents per row and place the followings rows of readers in the world.
breed [readers reader]
globals [ reader-ycor ]
to setup
clear-all
setup-globals
setup-readers
end
to setup-globals
set-default-shape readers "square 2"
set reader-ycor (min-pycor + 1)
end
to setup-readers
let horizontal-interval (world-width / number-of-readers)
create-readers number-of-readers [
set color green
setxy (min-pxcor - 0.5 + horizontal-interval * (0.5 + who)) reader-ycor
set size 3
set label ""
]
end
to go
setup
end
The global number-of-readers indicates the total number of readers, and max-number-per-row would be a variable set to 10 (the maximum number of readers per row).
I do not know how to tell the x-coordinate to stop when a row has 10 readers and how to tell Netlogo to add a new row of readers when the who of a reader is greater than 10.
Regards
I think instead of using who numbers (which is not recommended) you might be better off just calculating the coordinates manually and then spawning the turtles on the calculated values. With this setup:
breed [ readers reader ]
to setup
ca
spawn-by-row
reset-ticks
end
And these sliders for readers per row and number of readers:
This code will build readers from the lowest x/y value (details in comments):
to spawn-by-row
; get the intervals
let h-int world-width / readers-per-row
let v-int world-height / readers-per-row
; Get a range of horizontal and vertical coordinates, starting at half
; of the interval value from the minimum x coordinate
let h-vals ( range ( min-pxcor + h-int / 2 ) max-pxcor h-int )
let v-vals ( range ( min-pycor + v-int / 2 ) max-pycor v-int )
; Create an empty list to build into
let possible-coords []
; For each possible vertical value, map all horizontal values in order and
; combine these into an ordered list starting at the lowest px and py coords
foreach v-vals [
v ->
set possible-coords ( sentence possible-coords map [ i -> (list i v) ] h-vals )
]
; Use the number of readers to sublist the possible coordinates, and
; create a turtle at each of the coordinate combinations left.
let use-coords sublist possible-coords 0 number-of-readers
foreach use-coords [
coords ->
create-readers 1 [
setxy item 0 coords item 1 coords
set shape "square 2"
]
]
end
If you have more number-of-readers than can be accommodated by readers-per-row you will throw an error, but that would be easily fixed.
Edit 2:
Add a slider for distance-var to the interface above, and try this modified version of spawn-by-row
to spawn-by-row
; Get a range of coordinate values
let half-step 0.5 * distance-var
let d-vals ( range ( min-pxcor + half-step ) ( max-pxcor ) distance-var )
; Create an empty list to build into
let possible-coords []
; For each possible vertical value, map all horizontal values in order and
; combine these into an ordered list starting at the lowest px and py coords
foreach d-vals [
d ->
set possible-coords ( sentence possible-coords map [ i -> (list i d) ] d-vals )
]
; Use the number of readers to sublist the possible coordinates, and
; create a turtle at each of the coordinate combinations left.
let max-positions length possible-coords
if max-positions > number-of-readers [ set max-positions number-of-readers ]
let use-coords sublist possible-coords 0 max-positions
foreach use-coords [
coords ->
create-readers 1 [
setxy item 0 coords item 1 coords
set shape "dot"
set color white
]
]
end
I have managed a solution but using the avoidable who numbers.
breed [readers reader]
undirected-link-breed [ rris rri ]
globals [ reader-ycor ]
to setup
clear-all
ask patches [ set pcolor blue - 3 ]
setup-globals
setup-readers
end
to setup-globals
set-default-shape readers "square 2"
set separation-distance-ratio 10 ; should be > 10
set number-of-readers 24
set interf-rri-radius 110
end
to setup-readers
let horizontal-interval (world-width / separation-distance-ratio )
let vertical-interval (world-height / separation-distance-ratio )
create-readers number-of-readers [
setxy (min-pxcor - 0.5 + horizontal-interval * (0.5 + who mod 10 ))
(min-pycor - 0.5 + vertical-interval * (0.5 + floor (who / 10) ) )
set size 2.5
set color green
]
ask readers [ create-rris-with other readers in-radius interf-rri-radius ]
end
to go
setup
end
I have a very simple model of 50 turtles moving away from a central point. I would like to be able to extract the spatial coordinates (xcor, ycor) of a subset of them every nth tick in behaviour space. Hope you can help!
The modulo operator mod is probably the simplest way to do this. It outputs the remainder from a division operation, so you can just use a logical flag such that the coordinates are only extracted when ticks divided by n is equal to 0. For example:
to setup
ca
crt 10
reset-ticks
end
to go
; set up lists for example output
let tlist []
let xlist []
let ylist []
ask turtles [
rt random 60 - 30
fd 1
]
tick
; If ticks is not zero, and the remainder of
; the number of ticks / 3 is zero, extract
; some info about the turtles and print it.
if ticks > 0 and ticks mod 3 = 0 [
ask turtles with [ xcor > 0 ] [
set tlist lput self tlist
set xlist lput xcor xlist
set ylist lput ycor ylist
]
print tlist
print xlist
print ylist
]
end
Run this several times and you'll see that on tick 3 (and 6, 9, 12, etc), the lists are printed out. Note that where you have your tick increment will affect when this output is actually extracted- in the example above, tick happens at the end of the go procedure but before the if statement is evaluated.
I want to select all the patches at a randomly-generated distance eps from all turtles in a simulation and reset their color to yellow. This essentially draws a circle of patches around each turtle in the simulation. I have tried a few different options without success. Through perusing this forum I found some code that looks promising but still has some issues (posted here). I appreciate any suggestions for tweaking this code or using something else to solve this problem.
let eps2 eps
foreach [ eps2 ]
[
ask patches with
[
distance myself > eps2 - 0.5 and
distance myself < eps2 + 0.5
]
[
set pcolor yellow
]
]
eps is a turtle variable so using the let command allows me to circumvent using a turtle variable in patch context.
The foreach command does not recognize eps because it is not a constant, is there another command I could use here?
You can use list (see below), but ... why do you want a list? As it stands, there is no need to use a list.
to setup
ca
crt 1
ask turtle 0 [test]
end
to test
let eps2 10
foreach (list eps2 ) ;you can use `list`
[
ask patches with
[
distance myself > eps2 - 0.5 and
distance myself < eps2 + 0.5
]
[
set pcolor yellow
]
]
end
Addendum:
Since you indicate that you do not in fact need that list, you might try something along the lines of the following:
to test2
ca
crt 1
ask encirclingPatches turtle 0 10 1 [set pcolor yellow]
end
to-report encirclingPatches [#t #dist #width]
let _w2 (#width / 2)
report patches with [
distance #t > #dist - _w2
and
distance #t < #dist + _w2
]
end
I have limited programming experience (mechanical engineering student, so a bit of matlab and labview experience) and am very new to NetLogo, so I apologize in advance if this question is pretty basic or my code is of poor quality.
I need to have my turtles move to 1 of 2 possible neighboring patches based on a given probability function. The two patches that I need to input to the probability function are the two neighboring patches with the lowest nest-scent value. I have been able to pull the two lowest nest-scent values, but I cannot figure out how to actually figure out which patches those are, and how to put those coordinates into an ifelse statement to move the turtle to one of them based on the aformentioned probability function. I have the following code that is obviously not working:
to move
set farthest-patch sort-by < [nest-scent] of neighbors
let a1x pxcor of item 0 farthest-patch
let a1y pycor of item 0 farthest-patch
let a2x pxcor of item 1 farthest-patch
let a2y pycor of item 1 farthest-patch
let a1 item 0 farthest-patch
let a2 item 1 farthest-patch
let x (((a1 + a2) / 100 ) - 1)
let probability-move 0.5 * (1 + ((exp(x) - exp( - x)) / (exp(x) + exp( - x))))
ifelse random-float 1 < probability-move
[set to-move 1]
[set to-move 0]
let a1-probability (a1 / (a1 + a2))
ifelse random-float 1 < a1-probability
[set destination [a1x a1y]]
[set destination [a2x a2y]]
ifelse count turtles-here >= 20
[set full 1]
[set full 0]
if [a1x a21] = full
[set destination [a2x a2y]]
if [a2x a2y] = full
[set destination [a1x a1y]]
if [a2x a2y] and [a1x a1y] = full
[set to-move 0]
ifelse to-move = 1
[move-to destination]
[stop]
end
Basically what I have (tried) to do here is sort a farthest-patches list by increasing nest-scent, and I have pulled the two lowest nest-scent values in order to input those values into my probability functions (both for whether or not to move, and if they are to move which of the two patches to select). I am not sure how to properly pull the patch coordinates of the patches that the a1 and a2 values were taken from.
Thanks for any help,
Brad
okay, you are making life way more complicated than it needs to be. You can select the two patches (or turtles) with the smallest values of a variable with min-n-of. Look it up in the dictionary to get the details.
Having found the two candidates, the best option is to use the rnd extension for choosing the destination because it has a primitive for random selection by weight. Finally, since you are using a function of your variable as the weight (rather than the variable value itself), you need a way to construct that weight. The best option is to separate it out - you could also have a second variable with the weight value, but that just proliferates variables.
Here is a complete working model. Please copy the whole thing into a new instance of NetLogo and try and understand how it works, rather than just copy the relevant bits into your code because min-n-of, using agentsets and passing variables to procedures are important aspects of NetLogo that you need to know about. I have also set up colouring etc so you can see the choices it makes.
extensions [rnd]
patches-own [ nest-scent ]
to setup
clear-all
create-turtles 1 [ set color red ]
ask patches
[ set nest-scent random 100
set plabel nest-scent
]
reset-ticks
end
to go
ask one-of turtles [ move ]
tick
end
to move
set pcolor blue
let targets min-n-of 2 neighbors [ nest-scent ]
let destination rnd:weighted-one-of targets [ calc-weight nest-scent ]
move-to destination
end
to-report calc-weight [ XX ]
let weight 0.5 * (1 + ((exp(XX) - exp( - XX)) / (exp(XX) + exp( - XX))))
report weight
end
I want to assign a generated autocorrelated variable (0 to 1) to turtles spread over a grid. I can create autocorrelated data in R and then import them into Netlogo, but for sure, there is a more efficient way to do it in Netlogo.
Here a simple example:
turtles-own [
variable
]
to setup
clear-all
create-turtles 30
[
move-to one-of patches with [ not any? turtles-here ]
; I would like to assign a spatially autocorrelated variable
; for now, I am using a uniform variable
set variable random-float 1.0
]
end
Here an example using R:
N <- 16 * 16
p <- 0.07
# generate some points
set.seed(1234)
x.coord <- rep(1:16, 16)
y.coord <- rep(1:16, each = 16)
points <- cbind(x.coord,y.coord)
# distance matrix between points
Dd <- as.matrix(dist(points))
# weights matrix
w <- exp(-p * Dd)
Ww <- chol(w)
# variable
z <- t(Ww) %*% rnorm(N,0,1)
z <- scale(z, center = min(z), scale = max(z) - min(z)) # rescale to 0-1 variable
# plot
require(ggplot2)
df <- data.frame(x = x.coord, y = y.coord, z = z)
ggplot(df, aes(x = x, y = y, col = z)) +
geom_point() +
scale_colour_gradient(low="red", high="white")
Because I get data for each patch, I can create variable from the patch in which turtles are. Anyway, this looks unnecessarily complicated.
Any ideas?
Probably not the best solution, but at least it is close. I use the k-means extension to generate clusters based on distances between turtles. Then, I assign a random number between 0 to 1 + some noise to the turtles of each cluster.
let clusters k-means:cluster-by-xy targets 10 100 0.1
(foreach clusters (n-values 10 [random-float 1.0])
[ ask ?1 [ set variable random-between ?2 0.15 ]] ) ]
random-between is a report:
to-report random-between [number width-interval]
let half-interval width-interval / 2
let random-number (number - half-interval) + random-float width-interval
if random-number < 0 [set random-number 0]
if random-number > 1 [set random-number 1]
report random-number
end
This is not really clear - I don't believe you mean autocorrelated because you haven't mentioned time at all. Based on your R-code, you want to have turtles at regular points (in which case you want to ask patches [ sprout 1 ] rather than create turtles) and for them to have a variable with a value based on its position, in which case you can write a function with xcor and ycor as inputs.