2011-12-06 31 views
9

专家;如何让Mathematica用1代替0到0的电源?

鉴于

f = (#1^#2) & 

有一种方法,以限定上述这样“F”,如果#1 #2都为0,那么纯函数“F”的值应为1?

,这样,当我写

f[0,0] 

它将返回1,而不是不确定?

顺便说一句,我知道我可以写

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

但我想一般规则或模式,所以我没有写这些检查,因为纯函数可以更复杂(许多#它),而且我不想为可能出现的每个可能的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,那么生活会更简单。

更新12/7/11 感谢大家的回答和评论,所有人都非常有用,解决了我的问题,我从他们身上学到了东西。

我选择了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,以适应与我在做什么。

enter image description here

+2

您确定要将它们评估为1而不是0吗?该符号使得它看起来好像您正在评估指数是非负整数或可能是实数的多项式。连续性考虑将表明,在这种情况下,值0可能更可取。 –

+0

@DanielLichtblau,好的,谢谢,将0^0替换为0而不是1。但是,无论是哪种情况,如果我使用IF THEN ELSE(或者通过为每个可能情况定义许多不同签名来实现其功能)仍然有16种不同情况。希望有一种方法可以将这个短路,但告诉Mathematica用X代替0^0,其中X是正确的选择(0或1,因为它可能是)。 – Nasser

+0

另请参阅本数学小组讨论:http://mathforum.org/kb/message.jspa?messageID=6577581&tstart=0以及关于程序员SE的这个问题:http://programmers.stackexchange.com/questions/9788/how- do-language-x-handle-indeterminate-forms-like-00 –

回答

10

我同意@Deep黄色的答案,但如果你坚持一个纯粹的功能,这里是一个办法:

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 
+0

+1不错,虽然让我指出'f [foo,0]'为未定义的'foo'返回'1'。 –

+0

@深黄色感谢您的支持。关于你的评论 - 这是预期的,并且基于“Power”的内置规则,而不是我的特定定义。您的解决方案展现出相同的行为 –

+0

Oh yeah :-) * Mathematica *假设未定义的表达式对于'Power'而言不等于零。 –

4

您可以尝试像f = Quiet[Check[#1^#2,1]] &写它。

Quiet将抑制"Power::indet: "Indeterminate expression 0^0 encountered."消息,并且Check将取代1的结果,如果它是不确定的。

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

+5

请注意,这也将抑制产生相同错误和输出1的所有内容,而不管这是否是期望的结果。例如,'f [0,I]'。 – abcd

16

当然有很多方法可以在Mathematica中做事,但我经常使用的设计惯用法是编写“函数”(实际上是一种模式),其特性越来越小。 Mathematica有一个属性,它将在较少特定之前应用更具体的模式。

因此,对于你的情况下,我只是写:

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

我假设你指望一个整数的工作,因为这是这种类型的情况,例如通常的情况下在评估伯恩斯坦基函数时。

+0

+1好,没有多余的答案。顺便说一句,我想你的意思是说“具有降低的特异性”。 – DavidC

+0

@DavidCarraher:谢谢,纠正。 –

3

我有点惊讶,琐碎(尽管有点危险)的修复没有得到提及。如果你真的不希望表达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՝,因此可能很难区分不同笔记本的上下文以避免此修补程序产生冲突。

相关问题