1

I have each patch holding two lists: directions and magnitudes. Both lists contain values that are computed based on nearby turtles:

  • directions contains the headings from the patch to the various turtles (so basically it is just the turtle's heading rotated by 180°);
  • magnitudes contains a value that is directly proportional to the turtles' mass and inversely proportional to the distance between the patch and the turtles;
  • The items of the two lists are coupled in their order, i.e. the first item of directions and the first item of magnitudes are computed based on the same turtle, the two second items are computed based on another turtle and so on.

What I want to achieve is to come up with two single patch-own values, my-direction and my-magnitude, representing in some way the weighted average of directions, where the weights are magnitudes. To put it another way, I am thinking of this in terms of vectors: turtles are exerting on the patch a force that can be represented as a vector, always pointing in the direction of the turtle and with a certain intensity (the magnitude). The resulting vector (represented by my-direction and my-magnitude) should be the resulting average of these forces.

I have seen this question. It does not address the issue of a weighted average; however it mentions the concept of circular mean. I've delved into it a bit, but I'm not sure how to apply it to my case and even if to apply it: does it still apply even with the formulation of the problem in terms of vectors?

I've seen this question/answer on SE Mathematics where it is said that the average vector can be found by averaging x- and y-coordinates of the initial vectors. In my case, ideally all the pairs of values in the two lists form a different vector with origin in the patch at issue, with heading found in directions and length found in magnitude. I suspect I can find the coordinates of each vector by multiplying its sine and cosine by its magnitude, however at this point I'd use some guidance as I might be overcomplicating things (either from the maths perspective or the NetLogo perspective).

This one below is a reduced version of the code that brings to the point where target-patches (not focusing on all patches, in order to make it quicker) have the two lists populated.

globals [
 target-patches 
]

turtles-own [
 mass
 reach
]

patches-own [
 my-direction
 my-magnitude
 directions-list
 magnitudes-list 
]

to setup
  clear-all
  
  set target-patches n-of 10 patches
  ask target-patches [
    set directions-list (list)
    set magnitudes-list (list)
    set pcolor yellow + 3
  ]
  
  create-turtles 10 [
    move-to one-of patches with [(not any? turtles-here) AND (not member? self target-patches)]
    set mass (random 11) + 5
    set reach (mass * 0.8)
    set size (mass / 8)
    set shape "circle"
  ]
  
  populate-lists
end

to populate-lists
  ask turtles [
    let relevant-targets (target-patches in-radius reach)
    ask relevant-targets [
      set directions-list lput (towards myself) (directions-list)
      set magnitudes-list lput (magnitude-based-on-distance) (magnitudes-list)
    ]
  ]
end

to-report magnitude-based-on-distance
  report [mass] of myself / (distance myself * 1.2)
end
Matteo
  • 2,774
  • 1
  • 6
  • 22
  • Another way to build your lists is to use the OF reporter. Like: Set directions-list [ towards myself ] of relevant-targets —— this may be faster than accumulating the lists with lput, and it frees you from having to initialize and empty list. – TurtleZero Oct 07 '21 at 07:40
  • @TurtleZero I cannot do that because I need to have the `directions-list` and `magnitudes-list` built so that the two first elements of both lists refer to one specific turtle, the two second elements of both lists refer to another specific turtle and so on. This is something that I can achieve by asking each turtle to `lput` both lists, while using `of` would return agents from the agentset in a random order (and thus, using `of` once for one list and one other time for the other list, would mess up the order). PS: I'll reply to your answer when I have a bit more time. – Matteo Oct 07 '21 at 21:18
  • Oh right, you need strictly ordered lists. I forgot. – TurtleZero Oct 09 '21 at 07:34
  • You could also get the two values at the same time, so you’d have one list, each item containing a list with two values. It’s not so hard to use that, for using “first prop-pair” and “last prop-pair” or whatever. – TurtleZero Oct 09 '21 at 07:38
  • Another way that is totally not efficient is using a turtle as a container for the two measurements. Lol madness. – TurtleZero Oct 09 '21 at 07:44

1 Answers1

0

Your initial instinct is right. You can do something like

LET my-dx mean (map direction magnitude [ theta scalar -> scalar * sin theta ])

(I may have that map and anonymous syntax wrong please edit)

And do the same for my-dy using cos (edit: or maybe negative cos?)

patch-at my-dx my-dy is one way of getting the patch.

You can also do (atan my-dx my-dy) to gets the new direction And distancexy my-dx my-dy to get the magnitude

Don’t remember if patch can use distancexy or patch-at, but hopefully so. Otherwise you have to use a helper turtle, and do the math yourself.

I think I did a orbital mechanics toy model once that did something like this. It’s hiding on turtlezero.com.

Seth Tisue
  • 29,985
  • 11
  • 82
  • 149
TurtleZero
  • 1,013
  • 7
  • 15