在参数列表列表上应用函数列表

Applying a list of functions on a list of argument lists

我有一个匿名函数列表,我需要 映射 一个参数列表列表。我的愿望是获得一个包含列表的列表,其元素是函数列表中的函数,在每个参数列表中进行评估。

我的第一个想法是将函数列表映射到参数列表,然后将函数列表中的函数应用于参数列表中的每个元素。

;; definitions for k functions
let fj [ [x1 x2 ... xn ] -> <body j> ]
...

let args [ [ ... ] [ ... ] ... [ ... ] ] ;; list of arguments

let f-list ( list f1 f2 ... fk )

map [ [ arg ] -> map [ [ f ] -> ( runresult f arg ) f-list ] ]  args

此代码存在一两个问题:

  1. f-list 映射到 list arg 的行为与我预期的不同。也就是说,运行 代码会产生 运行 时间错误,因为 f-list 中的函数不是在 list 上定义的,而是在参数的数量。

为了克服后一个困难,我重新定义了 f-list 中的函数,以便得到一个列表作为参数并在函数体中使用 item 以检索各个参数。

这个解决方案,除了它也感觉像 hack 之外,它也非常不切实际,因为它增加了获得给定结果所需的代码,以一种非常容易出错的方式,而不是提到非常乏味(考虑必须使用适度数量的参数重新定义适度数量的函数)。

Mathematica 中,可以将函数参数的 list 转换为 sequence (或 tuple )的参数,如 Apply[f, args] 中那样使用 Apply ,其中 args 是参数值列表。

这有助于在参数列表 (lists) 上应用函数。实际上,可以编写 f @@@ { args1, args2, ..., argsm } 并获得列表 { f[x11, x12, ..., x1n], f[x21, x22, ..., x2n], ..., f[xm1, xm2, ..., xmn] } (其中 @@@ 只是对应于 Apply[f, args, 1] 的中缀符号)。

我想我正在寻找的是如何在本机 NetLogo 代码中实现相同的结果,而不必像本问题前一部分中报告的那样诉诸黑客。

一些实际代码

globals [ f-list args ]

to setup

  let f1 [ [ arg ] -> ( ( item 0 arg ) - 5 ) ^ 2 + ( ( item 1 arg ) - 5 ) ^ 2 + 0 * ( ( item 2 arg ) - 5 ) ^ 2 ]

  let f2 [ [ arg ] -> 4 * ( item 1 arg ) ^ 2 + 4 * ( item 0 arg ) ^ 2 + 0 * ( item 2 arg ) ^ 2 ]

  let f3 [ [ arg ] -> 2 + ( ( item 1 arg ) - 2 ) ^ 2 + ( ( item 2 arg ) - 1 ) ^ 2 + 0 * ( item 0 arg ) ]

  let f4 [ [ arg ] -> 9 * ( item 0 arg ) - ( ( item 2 arg ) - 1 ) ^ 2 + 0 * ( item 1 arg ) ]


  set f-list ( list f1 f2 f3 f4 )


  set args [ [ 2.04 3.09 -1.32 ] [ 5.57 -3.9 4.0 ] [ -1.1 -0.432 8.0 ] [ 1.32 -2.3 -9.103 ] ]


  show map [ [ arg ] -> ( map [ [ f ] -> ( runresult f arg ) ] f-list ) ] args

end

使用调用上述过程的 setup 按钮会产生以下输出:

observer: [[12.4097 54.8388 8.570500000000001 12.977599999999999] [79.53490000000001 184.9396 45.81 41.13] [66.716624 5.586496 56.914624 -58.9] [66.83239999999999 28.129599999999996 122.56060899999999 -90.190609]]

Thanks to Bryan Head,NetLogo 现在通过(实验性和未记录的)__apply__apply-result 原语提供此功能。

在你的情况下,__apply-result 是你需要的:

globals [ f-list args ]

to setup

  let f1 [ [x y z] -> (x - 5) ^ 2 + (y - 5) ^ 2 + 0 * (z - 5) ^ 2 ]
  let f2 [ [x y z] -> 4 * y ^ 2 + 4 * x ^ 2 + 0 * z ^ 2 ]
  let f3 [ [x y z] -> 2 + (y - 2) ^ 2 + (x - 1) ^ 2 + 0 * x ]
  let f4 [ [x y z] -> 9 * x - (z - 1) ^ 2 + 0 * y ]

  set f-list (list f1 f2 f3 f4)
  set args [[2.04 3.09 -1.32] [5.57 -3.9 4.0] [-1.1 -0.432 8.0] [1.32 -2.3 -9.103]]

  print map [ arg -> map [ f -> __apply-result f arg ] f-list ] args

end

如您所见,__apply-result 接受两个参数,一个匿名报告者和一个列表,并自动将列表中的项目作为参数传递给匿名报告者。 __apply 原语类似,但采用匿名命令而不是匿名报告者。