使用带有Pure函数和SetDelayed的Evaluate

时间:2013-07-31 18:07:05

标签: wolfram-mathematica

我想通过将列表传递给某个函数来评估f:

f = {z[1] z[2], z[2]^2};
a = % /. {z[1]-> #1,z[2]-> #2};
F[Z_] := Evaluate[a] & @@ Z ; 

现在,如果我尝试F[{1,2}],我会按预期获得{2, 4}。但仔细看?F会返回定义

F[Z_] := (Evaluate[a] &) @@ Z

取决于a的值,因此如果我们设置a=3然后评估F[{1,2}],我们会得到3。我知道添加最后一个&会使Evaluate[a]成立,但是优雅的工作是什么?基本上我需要强制评估Evaluate[a],主要是为了提高效率,因为a实际上非常复杂。

有人可以提供帮助,并考虑到f必须包含Array[z,2]某个未知计算。所以写作

F[Z_] := {Z[[1]]Z[[2]],Z[[2]]^2}

还不够,我需要从我们的f自动生成。

非常感谢任何贡献。

1 个答案:

答案 0 :(得分:2)

请考虑在dedicated StackExchange site for Mathematica询问您未来的问题 你的问题不太可能成为风滚草,许多专家都可能会看到它们。


您可以使用aFunction的值注入SetDelayedWith的正文中:

With[{body = a},
 F[Z_] := body & @@ Z
]

检查定义:

Definition[F]
F[Z$_] := ({#1 #2, #2^2} &) @@ Z$

您会注意到Z由于嵌套范围构造中的automatic renaming而变为Z$,但行为是相同的。


你在评论中说:

  

再次让我感到困扰的是,如果z[i]的值发生了变化,那么这种解决方法就会失败。

虽然 F[Z_]定义如上所述不应该是一个问题,如果您希望保护a的替换,您可以使用Formal Symbols而不是{ {1}}。这些是通过例如输入的Formal z的 Esc z Esc 。正式符号具有Protected属性,专门用于避免此类冲突。

这在笔记本电脑中看起来比在这里好得多:

$z

另一种方法是在f = {\[FormalZ][1] \[FormalZ][2], \[FormalZ][2]^2}; a = f /. {\[FormalZ][1] -> #1, \[FormalZ][2] -> #2}; 表达式中进行替换,并使用Hold保护规则本身不受评估:

Unevaluated
ClearAll[f, z, a, F, Z]

z[2] = "Fail!";

f = Hold[{z[1] z[2], z[2]^2}];
a = f /. Unevaluated[{z[1] -> #1, z[2] -> #2}] // ReleaseHold;

With[{body = a},
 F[Z_] := body & @@ Z
]

Definition[F]