1

I am combining and rewriting some system dynamics models (i.e. stock-and-flow models) with agent based models in Netlogo.

System dynamics models often include table functions for describing non-linear relationships. If we have two continuous variables x and y, and we know that an approximate relationship is (x = 0, y = 100; x = 1, y = 50; x = 2, y = 45, x = 3, y = 40; x = 4, y = 35), we can use interpolation to find the value of y for any value of x. In R, for instance, you can use the appoxfun() function.

Is there a way of addressing these relationships in Netlogo, in absence of actually knowing the causal mechanisms and coding them in the model? I have searched around on internet resources, but haven't been able to find much.

Thanks for your help!

JenB
  • 17,620
  • 2
  • 17
  • 45
user_15
  • 151
  • 9

1 Answers1

2

There is not an existing function. However, it is straightforward to construct an interpolation function that you can call. This version does linear interpolation and handles values outside the specified range of x values by reporting the appropriate end y value. Someone who is better than me at list functions (eg reduce) might find a more elegant method.

to-report calc-piecewise [#xval #xList #yList]
  if not (length #xList = length #ylist)
  [ report "ERROR: mismatched points"
  ]
  if #xval <= first #xList [ report first #yList ]
  if #xval >= last #xList [ report last #yList ]
  ; iterate through x values to find first that is larger than input x
  let ii 0
  while [item ii #xlist <= #xval] [ set ii ii + 1 ]
  ; get the xy values bracketing the input x
  let xlow item (ii - 1) #xlist
  let xhigh item ii #xlist
  let ylow item (ii - 1) #ylist
  let yhigh item ii #ylist
  ; interpolate
  report ylow + ( (#xval - xlow) / (xhigh - xlow) ) * ( yhigh - ylow )  
end

to testme
  let xs [0 1 2 3 4]
  let ys [100 50 30 20 15]
  print calc-piecewise 1.5 xs ys
end

This version requires you to specify the x-value list and y-value list (as well as the x value for interpolation) each time you use it. If you are always going to use the same points, they can be specified inside the function.

JenB
  • 17,620
  • 2
  • 17
  • 45