I am trying to place plotting procedures within the code so that I can flip a switch to determine if plots will be graphed. Strangely, I am getting a "recursion to deep error" (see screen shot at bottom). I only get this error when my show-plots? switch is true. Below is the relevant code:
to setup
;many non relevant setup procedures
reset-ticks
end
to go
;many non relevant go procedures
if show-plots? = true [plot-data]
to plot-data
let input-list (list "MS" "IC" "GF" "S" "R" "Ri" "DC")
let reporter-list (list Mech_stim Intra-IC Intra-GF cell-energy GLUT hunger Death-Prob)
set-current-plot "Intracellular Network"
(foreach input-list reporter-list [set-current-plot-pen ?1 plotxy T_hrs ?2])
end
I have tried to use this plotting procedure with lists to save on the typing the same thing over and over, because I have many plots to update.
I find it very strange that my code within the go procedure is determining when I get the "recursion too deep error" for something in the setup. Can anyone tell me why this is happening, and how it can be fixed? Thx.
Related
When running two exact same procedures for specific patches, one of the two is stating an error because "it cannot be run in observer context, it is a patches/turtles context only".
to start
ask patches with [seed = 1 AND age = retirement-age] [retirement]
ask patches with [seed = 1 AND age = death] [successor]
end
The retirement-age is an input from the interface.
The death is a patch property, I tried the startprocedure as well with an input from the interface.
The retirement and death procedure are just a copy-paste of each other, using lists created in other procedures. Only the result is different, see below :
to retirement
;;; other calculations same as successor procedure
ifelse (successor-result = 1) [set age 35 ] [set over-retirement 1]
end
to successor
;;; other calculations same as retirement procedure
ifelse (successor-result = 1) [set age 18] [dispatch-parcels]
end
Running the retirement procedure do not create error, but the successor procedure does create an error.
I did not copy-paste everything because I don't think it is useful as the two procedure are exactly the same. The other calculations use global variables and lists created in other procedures in the observer context.
Here-below is the dispatch-parcels procedure that regards to concerned patches from the beginning.
to dispatch-parcels
;; this regards the patches with seed = 1 that has been processed in the successor procedure. But doesn't work as for updating the age and death of the agent
set seed 0
set age 0
set death 0
;; if there is no successor, the parcels of the farm are distributed along the closest parcels : one farm can distribute its own parcels to multiple different farms
ask patches with [ ID-farm = [ID-farm] of myself]
;; for each parcel, finds the closest parcel and use the ID-farm as the new ID-farm, same for the region in case it changes.
[
set ID-farm ([ID-farm] of (min-one-of patches with [(ID-farm != 0) AND (ID-farm != [ID-farm] of myself)] [distance myself] ))
set region ([region] of (min-one-of patches with [(region != 0) AND (region != [region] of myself)] [distance myself] ))
]
end
I also tried to the successor procedure with the same final command line as from the retirement procedure but I get the same error message. So there should be something "hidden" somewhere about this successor procedure.
Any insight about the likely source of error, what I should more attention to ?
Thanks for your time.
I finally figured out what was wrong. It was so obvious that it became invisible and I'm a bit embarrased.
I'd like to share my answer anyway because it might opened the eyes of tired beginners like me.
In order to test this part of my code, I created a button to only test the successor procedure, which was in observer context, which was not possible with the commands I wrote. That's just it.
This is my code to switch breeds. How can I tell if the agents are changing breeds. I have a monitor that counts but the number is not changing. It is supposed to count passives vs. actives which should be changing.
to switch-A
ask managers-A
with [Rhat-A < mean-Rhat-P] [set breed managers-P]
end
That code looks fine. What does the code box in the monitor have? I assume you are counting As in one monitor and Ps in another.
If nothing's happening, it's likely that you either never call the switch-A procedure, or that there aren't any A's that meet the condition. Try this:
to switch-A
type "As with low value:" print count managers-A with [Rhat-A < mean-Rhat-P]
ask managers-A with [Rhat-A < mean-Rhat-P]
[ set breed managers-P
]
end
If you don't get output then it's not being called. If the count is 0 then you know to find out the values that are being tested etc.
I have people moving forward and I need the simple code to let these people when they intersect with each other ( if the number of people in the patch exceed certain number ---> lead to danger?
the second behavior: people need to walk then stop for some time to do some task then complete their walking.. how can I code this ? is there any idea for that?
the message from the below code tell that : Nothing named >=2 has been defined?
to go
ask pilgrims
[fd 1]
if any? other turtles-here >=2 [ set in-danger? true]
My code has one condition:
if ticks = 10^7 [ do-something ]
Now this condition is checked on every ticks though I know exactly when I have to execute the command. This might be slowing my code. The time extension does exactly this by time:go command. My command using time extension is:
time:schedule-event patches task do-something 1000000
But this throwing an error:
Extension exception: Attempted to schedule an event for tick 999999.0 which is before the present 'moment' of 1000000.0
error while observer running TIME:SCHEDULE-EVENT
called by procedure GO
called by Button 'go'
Is there something I am missing? Or any other efficient way to schedule some event at specific tick without checking the ticks condition every tick?
If this looks like a bug in the time extension, please post it at https://github.com/colinsheppard/time/issues
and tell us where we can find your code. (Or email it to me.)
I have a grid of 10x10 nodes where all adjacent nodes are linked to create a graph of 180 links - i.e:
What I hope to do is create a procedure which will break x% of these links, but importantly do so without creating any isolated subgraphs - that is, so that any 1 of the 100 nodes remain accessible from all other 99 nodes - i.e.
I initially (and naively) thought I could do something like the following:
ask n-of 45 nodes with [count my-links > 1]
[
ask one-of my-links [die]
]
However, this does not prevent sub-graphs from being orphaned from the main graph - i.e.
Another option might be to repeatedly ask single links to die and then check the total number of graphs does not exceed 1 - if it does, recreate the link and choose another to break. However, (1) this does not seem particularly elegant; and (2) I have been unable to find a way to count the number of distinct graphs using the inbuilt link or nw procedures.
I do think that part of my problem is not knowing the correct terminology for these subgraphs/isolates/cliques etc...
If anyone has any ideas on how this might be done (or can correct my woefully inadequate comprehension of graph theory terminology) it would be much appreciated.
Many thanks for the heads-up re nw:weak-component-clusters - I wasn't aware of that.
I have now implemented the following simple recursive procedure which will kill a link and if that link splits the graph recreate it and recall the procedure. This works well for what I wanted to do. Do note however that if you run this enough times you will end up stuck in a recursive loop as there will be no further links to break without splitting the graph and the procedure will keep calling itself.
to breakLink
let breakCandidate one-of links
let end1Candidate [end1] of breakCandidate
let end2Candidate [end2] of breakCandidate
ask breakCandidate [die]
if (length nw:weak-component-clusters > 1)
[
ask end1Candidate
[
create-link-with end2Candidate
breakLink
]
]
end
Cheers
For the solution you thought of, you can use the nw extension to check if there's still a path between the nodes you just disconnected by checking if nw:distance-to returns false or a number.
Alternatively, you can count the number of connected components.
I think removing the link and testing connectedness is a perfectly reasonable way to go. Any algorithm you implement will have to awkwardly pretend the link doesn't exist anyway, so will likely be more complicated than just removing the thing.
Edit: Adding code for the distance version to clarify:
to break-link
let break-candidate one-of links
let end-one [end1] of break-candidate
let end-two [end2] of break-candidate
ask break-candidate [die]
if [nw:distance-to end-two] of end-one = false [
ask end-one [ create-link-with end-two ]
break-link
]
end
Not sure if this or the nw:weak-component-cluster version will be faster. That will likely depend on the size of the network.