2011-07-15 14 views
5

Estaba jugando con los operadores Prefix y Postfix (@ y // respectivamente) y me encontré con el siguiente problema.Diferentes resultados usando f @ expr y expr // f en Mathematica

Dado el siguiente código, que evalúan de la misma manera exacta:

Hold[[email protected]@data] // FullForm 
(* Hold[MatrixPlot[Sort[data]]] *) 

Hold[data // Sort // MatrixPlot] // FullForm 
(* Hold[MatrixPlot[Sort[data]]] *) 

Sin embargo, teniendo en cuenta las siguientes expresiones, consigo resultados diferentes:

[email protected]'[0] 
(* Abs'[0] *) 

Abs'[0] // FunctionExpand 
(* 0 *) 

No estoy muy seguro de verdad por qué es esto En docenas de otros fragmentos de código que he tenido, [email protected], expr // f y f[expr] todos evalúan el mismo resultado. ¿Por qué este caso particular da este resultado?

+2

Este enlace es posiblemente relevante: http://www.mathprogramming-intro.org/book/node174.html, donde analizo cuestiones similares relacionadas con la precedencia. Usar 'FullForm' en la expresión original a menudo ayuda. –

+0

@Leonid 'FullForm' es una forma mucho mejor de ver lo que sucede que lo que sugerí; Agregué esto a mi respuesta, espero que no te importe – acl

+0

@acl ¡Genial! Estaba escribiendo la respuesta que usaba cuando saliste, así que descarté la mía, voté por la tuya y dejé el enlace. Es bueno tener ambos enfoques en la lista. –

Respuesta

10

Este es un problema de precedencia. @ tiene una precedencia mayor que //. Para ver qué está pasando, coloque el cursor en FunctionExpand en ambos casos, y luego cmd +. (en OS X) o ctrl +. en cualquier otra cosa, y terminas seleccionando cosas por precedencia.

Otra forma de verlo es utilizar Trace:

[email protected]'[0] // Trace 
(* 
-> {{{FunctionExpand[Abs],Abs},Abs^\[Prime]},(Abs^\[Prime])[0]} 
*) 

mientras

Abs'[0] // FunctionExpand//Trace 
(* 
-> {FunctionExpand[(Abs^\[Prime])[0]],0} 
*) 

En particular, observe cómo en el primer caso MMA primero evalúa FunctionExpand[Abs], obteniendo Abs, luego continuar. Esto se debe precisamente a la fuerza con la que se une @ en comparación con //.

EDIT: @ Inspirado por el comentario de Leonid, esto también es informativo:

Hold[[email protected]'[0]] // FullForm 
Hold[Abs'[0] // FunctionExpand] // FullForm 
(* 
-> Hold[Derivative[1][FunctionExpand[Abs]][0]] 
    Hold[FunctionExpand[Derivative[1][Abs][0]]] 
*) 

que es un mucho mejor demostración de lo que está pasando.

+0

Gracias, esto responde mi pregunta perfectamente . –