2011-12-06 11 views
9

Expertos;¿Cómo decirle a Mathematica que reemplace 0 por potencia 0 por 1?

Dado

f = (#1^#2) & 

¿Hay una manera de definir 'f' por encima de tal manera que si # 1 y # 2 son ambos cero, entonces el valor de la función pura 'f' debe ser de 1?

de manera que cuando escribo

f[0,0] 

devolverá 1 y no indeterminado?

por cierto, sé que puedo escribir

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

pero quería una regla general o patrón, así que no tiene que escribir estos controles, ya que la función pura puede ser más complicado (muchos # en ella) y no quiero hacer muchas de estas comprobaciones 'si entonces no' para cada posible 0^0 que pueda aparecer.

gracias

Actualización:

Puede ser Debo aclarar más por qué estoy haciendo esto.
Tengo un usuario que selecciona una función de un menú. La función es

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

Cuando en lo anterior, los parámetros 'n0', 'n1', 'n2' y 'n3' también se pueden seleccionar a partir de controles deslizantes, y estos pueden ser cero.

Ahora, 'x' y 'y' son coordenadas, y estas también pueden ser cero.

Por lo tanto, es posible que 0^0 pueda encontrarse al evaluar la función anterior.

Hay muchos casos para verificar, al hacerlo yo mismo. Por ejemplo 'y^n3' puede ser 0^0 y no el otro, y^n1 puede ser 0^0 y no el otro, x^n2 y^n3 pueden ser tanto 0^0 como no los demás, etc. , y entonces tengo que definir muchos casos diferentes. (16 posibles casos, creo).

Y estoy tratando de evitar esto. Si puedo decirle a Mathematica que reemplace 0^0 por 1 en un nivel inferior, entonces la vida será más simple.

Actualización 12/7/11 Gracias por las respuestas y los comentarios de todos, todos son muy útiles y resuelven mi problema y he aprendido de ellos.

He seleccionado la respuesta de Leonid, ya que me permitió resolver mi problema con la menor cantidad de codificación adicional.

He aquí un pequeño ejemplo

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 & 
    ) 
] 

utilizo números reales en todas partes de mi código (que es un solucionador de PDE numérica), así que por eso utilicé 0.0 en lo anterior y no 0^0 para encajar con lo que estoy haciendo

enter image description here

+2

¿Estás seguro de que quieres evaluar esto para 1 y no para 0? La notación hace que parezca que estás evaluando polinomios donde los exponentes son enteros no negativos o quizás reales. Las consideraciones de continuidad indicarían que un valor de 0 podría ser preferible en ese escenario. –

+0

@DanielLichtblau, Ok, gracias, consideraré 0^0 reemplazado por 0 en lugar de 1. Pero en cualquier caso, si utilizo IF THEN ELSE (o su equivalente funcional definiendo muchas firmas diferentes para cada posible caso), hay todavía 16 casos diferentes. Estaba esperando que haya una forma de cortocircuitar esto, pero decirle a Mathematica que reemplace 0^0 por X, donde X es la elección correcta (0 o 1 como podría ser). – Nasser

+0

Consulte también este debate de mathgroup: http://mathforum.org/kb/message.jspa?messageID=6577581&tstart=0 y esta pregunta sobre los programadores SE: http://programmers.stackexchange.com/questions/9788/how- does-language-x-handle-indeterminate-forms-like-00 –

Respuesta

10

Estoy de acuerdo con la respuesta de @Deep amarillo, pero si usted insiste en una función pura, aquí es una manera:

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

EDITAR

El permanecer dentro del ámbito de las funciones puras, la situación que describió en su edición puede abordarse de la misma manera que mi solución a su ejemplo original específico. Puede automatizar esto con un poco de metaprogramming, que define la siguiente función del transformador:

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

Entonces, mi código anterior se puede reescribir como:

f = z2zProtect[#1^#2 &] 

Pero usted puede es esto de manera más general, por ejemplo:

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

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

+1 Agradable, aunque permítanme señalar que 'f [foo, 0]' devuelve '1' para undefined' foo'. –

+0

@Deep Yellow Gracias por el voto popular. En cuanto a su comentario, esto es como se esperaba, y se basa en una regla incorporada para "Poder", no en mi definición particular. Su solución exhibe el mismo comportamiento. –

+0

Oh, sí :-) * Mathematica * asume que las expresiones indefinidas no son iguales a cero para 'Poder'. –

4

Puede intentar escribirlo como f = Quiet[Check[#1^#2,1]] &.

Quiet suprimirá el mensaje "Power::indet: "Indeterminate expression 0^0 encountered." y Check reemplazará el resultado con 1 si es indeterminado.

Probablemente sea mejor usar alguna función como s = Quiet[Check[#1, 1]] y envolver sus expresiones en ella.

+5

Tenga en cuenta que esto también suprimirá todo lo que produzca el mismo error y la salida 1, independientemente de si ese es el resultado deseado. Por ejemplo, 'f [0, I]'. – abcd

16

Por supuesto, hay muchas maneras de hacer las cosas en Mathematica, pero un modismo de diseño que a menudo uso es escribir la "función" (en realidad, un patrón) con una especificidad decreciente. Mathematica tiene la propiedad de que aplicará patrones más específicos antes de que sea menos específico.

Por lo tanto, para su caso que acababa de escribir:

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

Asumo que espera trabajar con valores enteros ya que es el contexto habitual para este tipo de situaciones, por ejemplo, al evaluar las funciones básicas de Bernstein.

+0

+1 Buena, clara respuesta sin lujos. Por cierto, creo que quisiste decir "con especificidad decreciente". – DavidC

+0

@DavidCarraher: Gracias, corregido. –

3

Estoy un poco sorprendido de que la solución trivial (aunque ligeramente peligrosa) no haya sido mencionada anteriormente. Si realmente no espera que aparezca la expresión 0^0 en un contexto en el que (a) le preocuparía que ocurriera, o (b) quisiera evaluarlo en algo distinto de 1, simplemente puede intentar

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

que necesitaba esta revisión en una situación en la que una función complicada tenía un número de llamadas a las expresiones de la forma x^n donde x es real y n es un número entero, en cuyo caso 0^0 debe ser visto como el límite de x^0=1 como x va a 0.

Es importante tener en cuenta, sin embargo, que hacer esto 'contaminará' Power para la sesión actual del kernel, y puede por lo tanto romper otros cuadernos que se ejecutan simultáneamente y para los cuales las condiciones (a) y (b) pueden no ser válidas.Dado que Power se encuentra en el contexto System՝ en lugar de Global՝, puede ser difícil separar los contextos de diferentes blocs de notas para evitar conflictos producidos por esta corrección.