【问题标题】:How to tell Mathematica to replace 0 to power 0 by 1?如何告诉 Mathematica 将 0 替换为 1 的幂?
【发布时间】:2011-12-06 16:49:37
【问题描述】:

专家;

给定

f = (#1^#2) &

有没有办法在上面定义'f',如果#1 #2都为零,那么纯函数'f'的值应该是1?

这样写的时候

f[0,0]

它会返回 1 而不是 Indeterminate?

顺便说一句,我知道我会写

f = (If[#1 == 0 && #2 == 0, 1, #1^#2]) &

但我想要一个通用规则或模式,所以我不必编写这些检查,因为纯函数可能更复杂(其中有很多 # )而且我不想做很多这样的 'if then else ' 检查每个可能出现的 0^0。

谢谢

更新:

也许我应该更清楚地说明我这样做的原因。
我有一个用户从菜单中选择一个功能。功能是

a x^n0 + b y^n1 + c x^n2 y^n3

其中,参数'n0'、'n1'、'n2'和'n3'也可以从滑块中选择,可以为零。

现在,'x' 和 'y' 是坐标,它们也可以为零。

因此,在对上述函数求值时,可能会遇到 0^0。

在自己做的时候,有很多情况需要检查。例如 'y^n3' 可以是 0^0 而不是另一个,y^n1 可以是 0^0 而不是另一个,x^n2 y^n3 可以是 0^0 而不是其他,等等。 ,所以我必须定义许多不同的情况。 (我认为有 16 种可能的情况)。

我正在努力避免这种情况。如果我可以告诉 Mathematica 在较低级别将 0^0 替换为 1,那么生活会更简单。

2011 年 12 月 7 日更新 感谢大家的回答和cmets,都非常有用,解决了我的问题,我向他们学习了。

我选择了 Leonid 答案,因为它允许我用最少的额外编码来解决我的问题。

这是一个小例子

Manipulate[Row[{format[x, n], "=", eval[x, n]}],
 {{x, 0.0, "x="}, 0, 1, .1, Appearance -> "Labeled"},
 {{n, 0.0, "n="}, 0, 1, .1, Appearance -> "Labeled"},
 Initialization :>
  (
   format[x_, n_] := HoldForm["(" x ")"^n];
   eval = Unevaluated[#1^#2] /. HoldPattern[0.0^0.0] :> 0.0 &
   )
 ]

我在代码中到处使用实数(它是一个数值 pde 求解器),这就是为什么我在上面使用 0.0 而不是 0^0 来适应我正在做的事情。

【问题讨论】:

  • 您确定要将这些评估为 1 而不是 0?该符号看起来好像您正在评估指数为非负整数或实数的多项式。连续性考虑表明,在这种情况下,值 0 可能更可取。
  • @DanielLichtblau,好的,谢谢,将研究 0^0 是否被 0 代替 1。但无论哪种情况,如果我使用 IF THEN ELSE (或通过定义许多不同的签名来实现它的功能等价物每个可能的情况),仍然有 16 种不同的情况。希望有办法将其短路,但告诉 Mathematica 将 0^0 替换为 X,其中 X 是正确的选择(可能是 0 或 1)。

标签: wolfram-mathematica


【解决方案1】:

当然,在Mathematica中有很多方法可以做事,但我经常使用的一个设计习惯是编写具有递减特异性的“函数”(实际上是一种模式)。 Mathematica 具有在不太具体之前应用更具体的模式的属性。

所以,对于你的情况,我只想写:

Clear[f];
f[0, 0] = 1;
f[a_, b_] := a^b;

我假设您希望使用整数值,因为这是这种情况的通常上下文,例如在评估 Bernstein 基函数时。

【讨论】:

  • +1 好的、清晰的答案,没有多余的装饰。顺便说一句,我认为您的意思是“特异性降低”。
【解决方案2】:

我同意@Deep Yellow 的回答,但如果你坚持纯函数,这里有一种方法:

f = Unevaluated[#1^#2] /. HoldPattern[0^0] :> 1 &

编辑

在纯函数领域内,您在编辑中描述的情况可以像我对您的特定原始示例的解决方案一样解决。您可以通过一点点元编程来自动执行此操作,定义以下函数转换器:

z2zProtect[Function[body_]] := 
   Function[Unevaluated[body] /. HoldPattern[0^0] :> 1]

那么,我之前的代码可以改写为:

 f = z2zProtect[#1^#2 &]

但你可以更一般地这样,例如:

ff = z2zProtect[#1^#2 + 2 #2^#3 + 3 #3^#4 &]

In[26]:= ff[0,0,0,0]
Out[26]= 6

【讨论】:

  • +1 很好,尽管让我指出 f[foo, 0] 为未定义的 foo 返回 1
  • @Deep Yellow 感谢您的支持。关于您的评论 - 这是预期的,并且基于Power 的内置规则,而不是我的特定定义。您的解决方案表现出相同的行为。
  • 哦,是的 :-) Mathematica 假定 Power 的未定义表达式不等于零。
  • @LeonidShifrin,谢谢,将在我的程序中尝试您的 Protect 元解决方案,因为它似乎会起作用,将根据我今天晚些时候发现的内容进行更新。
【解决方案3】:

你可以试着写成f = Quiet[Check[#1^#2,1]] &

Quiet 将抑制 "Power::indet: "Indeterminate expression 0^0 encountered." 消息,如果结果不确定,Check 将用 1 替换结果。

使用s = Quiet[Check[#1, 1]] 之类的函数并将表达式包装在其中可能会更好。

【讨论】:

  • 请注意,这也将抑制产生相同错误和输出 1 的所有内容,无论这是否是所需的结果。例如,f[0,I]
【解决方案4】:

我有点惊讶之前没有提到这个微不足道(尽管有点危险)的修复。如果您真的不希望表达式 0^0 出现在您 (a) 担心它会出现的任何上下文中,或者 (b) 希望它将其评估为 1 以外的值,您可以简单地试试

Unprotect[Power];
Power[0, 0] = 1;
Protect[Power];
0^0

如果一个复杂的函数有多次调用x^n 形式的表达式,其中x 是实数,n 是整数,我需要这个修复,在这种情况下应该看到0^0由于x^0=1 的极限为x 为0。

但需要注意的是,这样做会“污染”当前内核会话的Power,因此可能会破坏其他同时运行且条件 (a) 和 (b) 可能不成立的笔记本。由于Power 位于System՝ 上下文而不是Global՝,因此可能难以分离不同笔记本的上下文以避免此修复产生的冲突。

【讨论】:

  • 这应该是默认的。
猜你喜欢
  • 2017-10-14
  • 2015-12-06
  • 1970-01-01
  • 2020-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多