1

I'm considering implementing argmax using (map and reduce) and iterating.

Here's my implementation using map and reduce:

 to-report argmax1 [arguments f]
   if length arguments = 0 [ show "incorrect length of arguments" report nobody]
   report first reduce [ ifelse-value ((last ?1) > (last ?2)) [?1] [?2]] map [(list ? (runresult f ?))] arguments
 end

Here's my implementation using iterations.

 to-report argmax2 [arguments f]
   if length arguments = 0 [ show "incorrect length of arguments" report nobody]
   let max-argument first arguments 
   let max-evaluation runresult f max-argument

   foreach arguments 
   [
     let current-evaluation runresult f ?
     if current-evaluation > max-evaluation
     [
      set max-argument ?
      set max-evaluation current-evaluation 
     ]
   ]
   report max-argument
 end

My question is: Is there any benefits from using the built-in functions? In my map/reduce code, I iterate over the list twice compared with iterating over it once when not using map/reduce. In python, map/reduce would be a speed-up since it compiles to C rather than python byte code. Is there an equivalent for netlogo?

Thoughts?

mattsap
  • 3,790
  • 1
  • 15
  • 36
  • 1
    I would hesitate to guess one way or the other in this case. Interpreter overhead is higher in the `foreach` case here, but the `reduce` version makes a lot of temporary lists. If forced to bet, I'd think `reduce` would win out. – Seth Tisue May 05 '16 at 22:24

1 Answers1

1

You can get rid of the map:

to-report argmax [#args #f]
  let _x0 first #args
  let _best (list _x0 (runresult #f _x0))
  set _best reduce
    [update ?1 ?2 #f]
    fput _best butfirst #args
  report first _best
end

to-report update [#xf #x #f]
  let _f0 last #xf
  let _f1 (runresult #f #x)
  report ifelse-value (_f1 > _f0) [list #x _f1] [#xf]
end

to test  ;to illustrate
  let _xs n-values 10 [?]
  show argmax _xs task [(- ?) * ?]
end
Alan
  • 9,410
  • 15
  • 20
  • Nice. But, is there any performance improvement compared to just iterating over the arguments list? – mattsap May 04 '16 at 18:46
  • You could time them. Now that they're both down to one loop, I'd expect a slight advantage from reduce, which in principle won't have to keep fetching the function. But that is probably JVM dependent. – Alan May 04 '16 at 19:34
  • To be honest, I'm trying to avoid timing them since it's not that simple due to optimizations being done under the hood and my lack of knowledge of how JVM works/how to properly do a micro-benchmark. See here http://stackoverflow.com/q/504103/4379026. I think your expectations are reasonable though...I'd like someone to confirm though. – mattsap May 04 '16 at 19:43