在Mathematica中,您通常如何编写复合函数?

3

如果我想要做以下事情:

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

或者

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

还有哪些其他写法?你通常如何提高速度和效率?

编辑

顺便说一下,我以一种通用的方式提出了这个问题,而不是针对特定的问题。我有时会感到缺乏脑力来以mma的函数式编程思维方式思考。只是想用各种其他方式扩充我的工具库,并学习它们的复杂性/效率分析。所以请添加类似的问题。


抱歉我刚看到你的编辑。Module 用于局部变量,With 用于局部常量,这种区别是通用的。 - Verbeia
3个回答

4
我不知道什么是凸包,但我会假设我理解了这个问题。
    getCH[pts_]:=pts[[ConvexHull[pts]]]


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

如果由于某种原因您希望pts仅出现一次,您可以使用With、Module或Block。我认为最重要的是要说出我不认为这样做有意义。实际上,With会将每个pts的出现都替换为点列表。对于这个问题来说,似乎有些过度,但请自由发挥。
     getCH[pts_]:=With[{p=pts},p[[ConvexHull[p]]]]

模块创建一个新变量。如果您的变量不需要分配值,则通常比With慢。换句话说,对于定义常量,With更快。我认为Block也比Module快(略微),但其动态作用域(对抗Module的词法作用域)使它有点奇怪。有很多关于这些的主题。

我不认为有任何内置函数可以接受列表和函数或符号,并提取该列表上由评估该列表上的函数结果索引的元素,如果这是您为“通用”问题寻找的内容。当然,您可以轻松创建一个,然后将来使用它。我认为对于如此简单的问题来说,这太多了,但也许这正是您所追求的函数式编程。

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

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

你也可以考虑使用 List /@ ... 而不是 Transpose@{...} - Szabolcs
1
@Szabolcs List/@ 在这种情况下可能更清晰且更有效,但我有一个习惯,如果适用的话就选择Transpose...似乎更快。Map比Transpose更通用,需要一个List、一个方阵等。 - Rojo
1
是的,对于紧凑数组来说,它绝对会更快。出于好奇,Partition[..., 1]也是一个同样快速(可读性较差的)替代方法。 - Szabolcs

3
您可以像这样在模块中初始化变量。
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]

这个问题与 使用嵌套插槽 有关。不建议在没有为变量命名的情况下嵌套纯函数。
您可以像这样“反转”函数,但我不能保证它的工作原理。
Function[x,Part[#,x]]& /@ ConvexHull[#] & @ pts

如果我想让pts只出现一次,并且在Map[Function[{x}, Part[#, x]], ConvexHull[#]]&中去掉Function,是否有一种方法,例如使用@、/@、~等? - Qiang Li
通常情况下,我真的不想写两次pts。 - Qiang Li

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}}
]]]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接