Read-from-string troubles - netlogo

I have loaded a GIS file into netlogo. This file has a number of attributes, but I'm really only having trouble with one. The material type is set to p, t, s, c - according to QGIS these are strings. When I read them in they all have quotes around them and so show as "p" "t" "s" "c" and no turtles are returned from:
ask turtles with [is-string? material-type = false] [show who]
The problem I have is when I try to read-from-string. Netlogo raises the error: expected constant.
Any thoughts? I have looked around for an answer, but most are a little different.

Related

Removing an agentset from another agentset (the agents from the first set which are also present in the second set)

in my netlogo code I have a network with companies (that is my breed). I want to ask the companies to share information with their neighbors and their neighbors and so on, this works (see code below, the agentsets are b, c and d).
However when I ask for information on the third level neighbors my agentset also includes the first level neighbors (obviously since it takes all neighbors into acount), so I want to remove these first level neighbors from the third level neighbors agentset. In the code this means I want to remove agents present in D which are also present in B
But I cant find the way to do it, other doesnt work since it is not the agent asking which has to be removed. And remove also doesnt seem to do the job. I also tried != not equal to the first level but this reports a true or false and I just want to remove these agents from the third level agentset so I dont double count them.
ask companies [
let i who
let b link-neighbors
ask b [ let c link-neighbors
ask c [ let d link-neighbors
ask companies with [who = i] [
set iburen [who] of b
set iiburen [who] of other c
set iiiburen [who] of d
]
]
]
]
can somebody help me with this?
I think what you want is the member? primitive. If D and B are agentsets, the following should give you the members of D that are not members of B.
let DminusB D with [not member? self B]
Many things to say here:
Charles' answer is technically correct.
If a and b are agentsets, a with [ not member? self b ] will give you agents from a that are not already in b.
But I think there are better ways to accomplish what you are trying to do. I will come back to that, but first, a general piece of advice:
Don't use who!
The who primitive has some (very few) legitimate usages, but it's mostly evil. It tends to lead to brittle, inefficient code. For example, when you do:
let i who
; ...
ask companies with [who = i] [ ... ]
NetLogo has to scan all companies to find the one with that specific who number.
NetLogo can store agent references directly. Use that instead! For example:
let this-company self
; ...
ask this-company [ ... ]
Especially don't use lists of who numbers!
NetLogo is adequate for manipulating lists, but its awesome for manipulating agentsets. If you do something like this:
set iburen [who] of b
set iiburen [who] of other c
set iiiburen [who] of d
You are forfeiting the power of agentsets. I don't know why you want to store the three different levels separately, but supposing it's OK to store all your neighbors together, you could do:
set my-neighbors other (turtle-set b c d)
The use of other will exclude the original company and turtle-set will make sure that each agent in the set is unique (as agentsets can only contain unique agents anyway).
If you really want three separate variables, use Charles' answer, but make sure to store agentsets, not lists of who numbers!
If you don't need separate variables, however, I think the best solution would be to:
Use nw:turtles-in-radius.
NetLogo's Networks extension has a primitive that does exactly what I think you want to do:
ask companies [ set my-neighbors nw:turtles-in-radius 3 ]
That's it.

NetLogo - Random setup - Random value to each patch - Error

As part of the setup procedure I am trying to use a slider to set the density of patches which will be displayed and assigned a random value. The slider on the interface for density ranges 0 to 100 and the random value of the patch is set using an input on the interface. This will normally be set in the region go 4. So, if 50% is set the the procedure will assign 50% of the patches with a random value.
When i do i get the following error: "Expected command" and the variable 'error-count' is highlighted in the code.
;; The density of patches to be set with a random value is set using variable init-errors on interface.
;; Every patch uses a task which reports a random value.
;; The random value is set using variable error-count on interface
to setup-random
ask patches [
if (random-float 100.0) < init-errors
[setup task random error-count]
]
end
You need to change:
setup task random error-count
to
setup task [ random error-count ]
Anytime the task body isn't just a single primitive (the "concise task syntax"), it needs to be surrounded by square brackets. The error message you're getting happens because task random is valid syntax; NetLogo interprets it as short for task [ random ? ]. Then it doesn't know what to do with the following error-count, hence the error.
I am not entirely clear on the task syntax you are using (in particular, why setup is at the beginning of that line) or why you want to use a task here - but that could be a difference in coding style. But the NetLogo compiler is letting you know that it expected a command after the word random but got a value. Since random does expect a value after, I think it's something to do with the setup and task elements. Here's an alternative way of doing what you want, which might be easier. I have also turned the non-zero error patches green so you can see them. This code assumes you have the two sliders you defined in your problem description.
patches-own [errors]
to setup-random
ask patches [
if (random-float 100.0) < init-errors
[ set errors random error-count
set pcolor green ]
]
end

How to avoid individual patch updates

I am modeling diffusion in my model, but I think I am getting a calculation artifact due to NetLogo sequentially updating individual patches. I will not be using the diffuse command (due to inaccurate diffusion). However, much like how this command works, I would like to update all the calculations of the patches simultaneously, rather than sequentially. I have a slight recollection of seeing some sample code that used values at the beginning of the tick, however I canĀ“t seem to find it now.
Specifically, I need help programming a way to store patch values at the turn of each tick, and then carry out a simultaneous calculation based on these stored values.
Great question. As you indicate, basically you want to calculate the new value of the variable in one ask block, but store it in a separate variable, and then update the actual value of the variable in a second ask block, like so:
turtles-own [
value
new-value
]
...
to go
ask patches [
;; Change this line to however you want the diffusion to work
set new-value 0.5 * value + sum [ 0.5 * value / 4 ] of neighbors4
]
ask patches [
set value new-value
]
end
This way all patches calculate their updated values from the same information, and then actually update the values themselves simultaneously.

NetLogo - compare single agent against many agents (expected input not list)

I am first time poster, six month reader. I love this site and am grateful for the vast array of topics covered. Now that I am feeling a bit more competent using NetLogo, I've tried some harder stuff and got stuck...
Basically, I have created a membership function which measures agents against one another on a vector containing two variables (opinions on rock and hip-hop):
to-report membership [ agent1 agent2 ]
let w 0.5
let w2 sq w
report exp (- d2 agent1 agent2 / w2)
end
where
;;;;;;;;;;;;;;Shortcut functions;;;;;;;;;;;;;;;;;;;;;;;;;;;
to-report d2 [agent1 agent2 ]
report ( (sq ([rock] of agent1 - [rock] of agent2)) + (sq ([hip-hop] of agent1 - [hip-hop] of agent2)) )
end
to-report sq [ x ]
report x * x
end
This all works fine, and I am able to compare any two agents without problem.
However, my trouble arises when I try to compare a single agent [agent1] with all of the agents within his neighbourhood.
to go
ask turtles [
let neighbours turtle-set turtles in-radius neighbourhood
show membership self neighbours]
end
Whenever I run this model I receive an error that the d2 reporter expected an input not a list - which I theoretically understand - by having a neighbourhood of 1+ agent(s), the calculation is receiving for example [0.1 0.8] [0.2 0.4] [0.5 0.6]..............
I was just wondering, is there any way that the procedure can consider all of the neighbours and arrive at one single membership number? I have searched extensively through posts and a couple of netlogo books I have, but no luck so far. Thank you for taking the time to read this post and for any helpful comments.
Your understanding of what is happening is correct: your membership reporter expects two individual agents and you are passing it an agent and an agentset. To calculate each membership individually, and get back a list of membership values, you can use of:
to go
ask turtles [
let neighbours turtle-set turtles in-radius 10
show [ membership myself self ] of neighbours
]
end
Notice the use of myself and self, which can sometimes be tricky to understand. In this case, self is the neighbour and myself is the outer asking turtle.
So now you have a list of membership numbers, but you wonder:
is there any way that the procedure can consider all of the neighbours and arrive at one single membership number?
There are plenty of ways! But we can't really tell you which one to use: it depends on your model and what you want to do with it.
If you wanted something very straightforward, you could just take the mean of the list:
show mean [ membership myself self ] of neighbours
...but I don't know if it makes sense in your context. In any case, NetLogo has plenty of
mathematical primitives that you should be able to use to arrive at the number you want.

LINK expected input to be a number but got the turtle (turtle 26) instead

how can I assign a link to variable. there is a run time error in my code when it run this line
let link-who link node2-who this-one
node2-who and this-one are turtles.
and this is runtime error :
LINK expected input to be a number but got the turtle (turtle 26)
instead.
The procedure link takes the who numbers of two turtles and returns the link connecting them. You're getting that error because at least one of the inputs you're giving it is a turtle, not a who number.
Now, that said, I recommend avoiding using who numbers at all (except in very special circumstances). Instead, if you want to get the link between the current turtle and some other turtle, you can do
link-with other-turtle
where other-turtle is the other turtle (it would probably be called something like node2 in your case).