2

我想通过将列表传递给某个函数来评估下面的 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.

非常感谢您的任何贡献。

4

1 回答 1

2

请考虑在Mathematica的专用 StackExchange 站点上询问您未来的问题。
您的问题不太可能成为风滚草,并且可能会被许多专家查看。


您可以将 的值注入a两者的主体FunctionSetDelayed使用With

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

检查定义:

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

您会注意到Z已成为Z$由于嵌套范围构造中的自动重命名,但行为是相同的。


在你说的评论中:

再次困扰我的是,如果z[i]更改了 的值,那么这种解决方法将失败。

虽然在如上所述定义之后 这应该不是问题,但如果您希望保护为您完成的替换,您可以使用正式符号而不是. 这些是用例如Formal z 输入的。形式符号具有受保护的属性,并且专门存在以避免此类冲突。F[Z_]azEsc$zEsc

这在笔记本中看起来比在此处要好得多:

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]
F[Z$_] := ({#1 #2, #2^2} &) @@ Z$
于 2013-08-06T08:41:17.850 回答