2

让我首先声明我是 Mathematica 新手,这个问题可能很容易回答,但到目前为止,我还没有为这个在互联网上搜索的特定问题找到任何帮助。在这里,我基本上总结了我需要我的代码做什么。使用带有条件语句的/.替换命令存在一些问题。IF基本上,我有一个很长的函数,其中包含另一个由IF条件全局定义的函数。这几行代码演示了我遇到的错误......

In[1]:= y[x_, z_] = 2*x + 3*z;

In[2]:= zz[x_, z_] := If[y[x, z] < 0, 4*y[x, z], y[x, z]]

In[3]:= zz[-1, -2]

Out[3]= -32

但是我需要...

In[4]:= zz[x_, z_] /. x -> -1 /. z -> -2

Out[4]= If[3 Pattern[-2, _] + 2 Pattern[-1, _] < 0, 
 4 y[Pattern[-1, _], Pattern[-2, _]], 
 y[Pattern[-1, _], Pattern[-2, _]]]

这不会产生预期的数字项。提前感谢大家的帮助,尽管这个问题听起来很愚蠢。x注意:我必须使用 replace 命令,而不是直接为and赋值z

附录:

我过于简化了我的例子。举个例子:

In[91]:= a[b_, c_] = -3*b + 2*c + d + e + f;

In[92]:= g[b_, c_] := If[a[b, c] < 0, -3*a[b, c], a[b, c]];

In[10]:= g[2, 4] /. d -> 1 /. e -> 2 /. f -> 3

Out[10]= 2 + d + e + f

但我希望看到结果Out[10]= 8

希望另一个简单的修复。

4

2 回答 2

3

当您定义一个函数时,您使用x_,它告诉mathematica 找到命名的模式并将x定义应用到它。所以f[x_]=x^2“取表达式 x 并将其转换为 Power[x,2]”。

当您调用函数时,您不再使用模式,而是使用mathematica 最终替换的变量或值x。所以f[a]会给你a^2如果a是未定义的,或者使用定义a并相应地给出结果。

所以正如霍华德在评论中提到的,如果你只是删除下划线,你会得到你想要的表达式。

In[1]:= zz[x, z] /. x -> -1 /. z -> -2

Out[1]= -32

编辑

要回答您的评论,

If仅在评估条件后评估第二个和第三个参数。所以如果你看g[2,4],你会得到

If[2 + d + e + f < 0, -3 a[2, 4], a[2, 4]]

您会看到“then”和“else”语句仍未评估,尽管a[2,4]它们本身会给您2 + d + e + f.

因此,当您进行替换时,mathematica 开始替换d,e,f它在表达式中找到的任何位置(仅在条件中),并且一旦它评估条件并到达“then”或“else”步骤,就没有其他东西可以替换了.

您需要使用的是ReplaceAll//.重复应用规则,直到无法再应用。就是这样

In[2]:= rules = {d -> 1, e -> 2, f -> 3};
        g[2, 4] //. rules
Out[2]= 8
于 2011-05-24T19:55:37.537 回答
1

我建议您的“附录”代码的这种变体:

a[b_, c_] = -3*b + 2*c + d + e + f;

g[b_, c_] := If[# < 0, -3*#, #] & @ a[b, c]

g[2, 4] /. {d -> 1, e -> 2, f -> 3}

(* Out = 8 *)

这些变化是:

  1. If语句移动到与 . 分开的纯函数中a[b, c]。这种方式a[b, c]只评估一次,这通常是一个很好的做法。

  2. 将您的替换移动到单个/.操作和规则列表中。同样,良好的做法,除非您真的打算进行串行更换。

在这种情况下,第一个更改解决了您的问题,因为g[2, 4]计算结果为:

If[2 + d + e + f < 0, -3 (2 + d + e + f), 2 + d + e + f]

明确使用d,ef. ReplaceAll因此,这些对( )是可见的,/.并且替换工作正常。

有一种更好的方法可以实现您的目标是合理的,但我不会猜测您的其余代码。

于 2011-05-25T08:14:19.870 回答