你通常在Mathematica中编写复合函数

时间:2011-12-30 23:15:15

标签: wolfram-mathematica

如果我想执行以下操作:

getCH[pts_List] := Module[{t}, t = ConvexHull[pts]; Map[Part[pts, #] &, t]];

Map[Function[{x}, Part[#, x]], ConvexHull[#]]&

有什么其他方法可以写这个?你通常如何提高速度和效率?

修改

顺便说一句,我是以一般方式问这个问题,不是针对这个特殊问题。我有时会觉得缺乏脑力来思考mma中的函数式编程。只是想用各种其他方式扩展我的武器库来编写函数组合并学习它们的复杂性/效率分析。所以请添加类似的问题。

3 个答案:

答案 0 :(得分:4)

我不知道什么是ConvexHull,但我认为我理解了这个问题

    getCH[pts_]:=pts[[ConvexHull[pts]]]


    getCH[pts_]:=Extract[pts, Transpose@{ConvexHull[pts]}]

如果您希望pts因某种原因只出现一次,您可以随时使用With,Module或Block。我认为最重要的是要说我没有看到这样做的重点。使用,有效地用点列表替换pts的每个外观。看起来像是一种矫枉过正,但随时写下

     getCH[pts_]:=With[{p=pts},p[[ConvexHull[p]]]]

模块创建一个新变量。对于您的变量不需要赋值的情况,它通常比With慢。换句话说,With更快地定义常量。块我认为也比Module(稍微)快,但它的动态范围(对模块的词法范围)使它有点怪异。关于这些的很多线索。

我认为没有任何内置函数接受列表和函数或符号,并提取该列表上的元素,该元素由在同一列表上评估函数的结果索引,如果这是您要查找的内容为你的“通用”问题。当然,您可以轻松创建一个,然后在将来使用它。我认为这对于这么简单的问题来说太过分了,但也许它是你想要的功能性编程

    ExtractIndexed[l_List, fun_]:=l[[fun[l]]]

    getCH[pts_]:=ExtractIndexed[pts, ConvexHull]

答案 1 :(得分:3)

您可以像这样Module初始化变量

Module[{t = ConvexHull[pts]}, Map[Part[pts, #] &, t]]

但在这种情况下,您不会重新定义t,因此它是一个局部常量,您最好使用With

With[{t = ConvexHull[pts]}, Map[Part[pts, #] &, t]]

或者只是

Map[Part[pts, #] &, ConvexHull[pts] ]

Part[pts, #] & /@ ConvexHull[pts]

这个问题是相关的:Using nested slots。不建议在没有命名变量的情况下嵌套纯函数。

你可以像这样“反转”你的功能,但我不能保证它有效。

Function[x,Part[#,x]]& /@ ConvexHull[#] & @ pts

答案 2 :(得分:1)

也许尝试使用Through

Part @@ Through[ 
 List[ Identity, Graphics`Mesh`ConvexHull][{{0, 0}, {1, 0}, {.5, .5}, {1, 1}, {0, 1}}]
]

这个给出警告(因为Part评估),但然后“工作”:

Through[
 Part[Identity, Graphics`Mesh`ConvexHull][{{0, 0}, {1, 0}, {.5, .5}, {1, 1}, {0, 
 1}}]]

我认为这是解决上述Part评估问题的方法:

Through[
 Unevaluated[
  Part[
   Identity, Graphics`Mesh`ConvexHull][
   {{0, 0}, {1, 0}, {.5, .5}, {1, 1}, {0, 1}}
]]]