2011-02-07 19 views
11

Supongamos que quiero construir algo así comoUso de ranuras anidados (#)

Array[#1^#2 == 3 &, {3, 3}] 

Y ahora quiero reemplazar el "3" con una variable. Que puedo hacer, por ejemplo:

f[x_] := Array[#1^#2 == x &, {x, x}] 

La pregunta es: ¿Hay alguna manera usando sólo ranuras y & como la notación funcional?

+4

Esto me hizo mirar los documentos para 'Slot' (+1). La definición de función recursiva y pura para el factorial: 'f = Si [# ​​1 == 1, 1, # 1 # 0 [# 1 - 1]] &' ¡es bastante astuto! – Simon

+0

@ Simon Yep. Ese # 0 también me preocupaba: D –

+1

@Simon, nunca antes había leído la documentación de Slot. El '# 0' es definitivamente molesto, y potencialmente muy útil. – rcollyer

Respuesta

4

¿Qué tal

Map[Last, #] & /@ Array[#1^#2 == #3 &, {#, #, #}] &[3] 

extracción elemento terriblemente feo, y muy interesante Map[Last, #]& me da un resultado diferente que Last /@. ¿Esto se debe al hecho de que Map tiene atributos diferentes que &?

+2

Mapa [Last, #] &/@ === (Last/@ #) &/@! = Last/@ –

+0

¡Buen truco, por cierto! –

+0

Gracias por la explicación. – Timo

3

Supongo que ya sabe lo que dice la documentación sobre nested pure functions.

Uso nombres explícitos para establecer anidados funciones puras (por ejemplo):

Function[u, Function[v, f[u, v]]][x]

De todos modos, aquí está lo mejor que podía llegar a sin seguir el consejo anterior:

f[x_] := Array[#1^#2 == x &, {x, x}] 
g = Array[With[{x = #}, #1^#2 == x &], {#, #}] & 

g es funcionalmente idéntico a su original f, pero no es realmente mejor que la recomendada

h = Function[x, Array[#1^#2 == x &, {x, x}]] 
+0

Sí, conozco los documentos: D.Sin embargo, este caso, en el que deseo utilizar el mismo valor de variable para los parms internos y externos, parece proclive a algunas intrusiones. –

+1

@belisarius: En realidad, no noté que fue usted quien hizo la pregunta. ¡Lo siento! – Simon

+0

la próxima vez incluiré un ['nice portrait'] (http://www.life.com/image/53368173) para facilitar el reconocimiento: D –

9
No

realmente la respuesta a la pregunta original, pero me di cuenta de que mucha gente se interesó en #0 cosas, así here pongo un par de ejemplos no triviales, esperamos que se sé útil.

En cuanto a la afirmación de que para funciones anidadas se deben usar funciones con argumentos nombrados: aunque esto es cierto en general, siempre se debe tener en cuenta que el ámbito léxico para funciones puras (y generalmente) se emula en Mathematica y se puede romper . Ejemplo:

In[71]:= 
Clear[f,g]; 
f[fun_,val_]:=val/.x_:>fun[x]; 
g[fn_,val_]:=f[Function[{x},fn[#1^#2==x&,{x,x}]],val]; 
g[Array,3] 

During evaluation of In[71]:= Function::flpar: Parameter specification {3} in 
    Function[{3},Array[#1^#2==3&,{3,3}]] should be a symbol or a list of symbols. >> 
During evaluation of In[71]:= Function::flpar: Parameter specification {3} in 
    Function[{3},Array[#1^#2==3&,{3,3}]] should be a symbol or a list of symbols. >> 

Out[74]= Function[{3},Array[#1^#2==3&,{3,3}]][3] 

Este comportamiento tiene que ver con la naturaleza intrusiva de sustituciones de reglas - es decir, con el hecho de que Rule y RuleDelayed no se preocupan por posibles colisiones de nombres entre en construcciones de alcance que pueden estar presentes en expresiones sujetas a aplicaciones de reglas y nombres de variables de patrones en reglas. Lo que empeora las cosas es que g y f funcionan completamente bien cuando se toman por separado. Es cuando se mezclan, que ocurre este enredo, y solo porque tuvimos la mala suerte de usar la misma variable de patrón x en el cuerpo de f, como en una función pura. Esto hace que estos errores sean muy difíciles de detectar, mientras que tales situaciones suceden a veces en la práctica, por lo que recomendaría no pasar funciones puras con argumentos con nombre como parámetros en funciones de orden superior definidas a través de patrones.

Editar:

Ampliando un poco en la emulación del ámbito léxico.Lo que quiero decir es que, por ejemplo, cuando creo una función pura (que es una construcción de alcance léxico que une los nombres de las variables en su cuerpo a los valores de los parámetros pasados), espero que no pueda alterar esta unión después de haber creado una función. Esto significa que, no importa dónde use Function[x,body-that-depends-on-x], debería poder tratarlo como una caja negra con parámetros de entrada y salidas resultantes. Pero, en Mathematica, Function[x,x^2] (por ejemplo) también es una expresión, y como tal, se puede modificar como cualquier otra expresión. Por ejemplo:

In[75]:= 
x = 5; 
Function[Evaluate[x],x^2] 

During evaluation of In[75]:= Function::flpar: Parameter specification 5 in Function[5,x^2] should 
    be a symbol or a list of symbols. >> 
Out[76]= Function[5,x^2] 

o, aún más simple (la esencia de mi advertencia anterior):

In[79]:= 1/.x_:>Function[x,x^2] 

During evaluation of In[79]:= Function::flpar: Parameter specification 1 in Function[1,1^2] should 
    be a symbol or a list of symbols. >> 

Out[79]= Function[1,1^2] 

Me picaron por esta última comportamiento algunas veces muy dolorosa. Este comportamiento también fue notado por @WReach en la parte inferior de su publicación en la página this; obviamente, él tuvo experiencias similares. Hay otras formas de romper el alcance, basadas en el conocimiento exacto de cómo Mathematica cambia el nombre de las variables durante los conflictos, pero en la práctica son comparativamente menos nocivas. En general, no creo que este tipo de cosas se puedan evitar si se insiste en el nivel de transparencia representado por las expresiones de Mathematica. Simplemente parece ser "demasiado transparente" para funciones puras (y construcciones de ámbito léxico en general), pero por otro lado también tiene su uso, por ejemplo, podemos forjar una función pura en tiempo de ejecución como esta:

In[82]:= Block[{x},[email protected]@{x,Integrate[HermiteH[10,y],{y,0,x}]}] 

Out[82]= Function[x,-30240 x+100800 x^3-80640 x^5+23040 x^7-2560 x^9+(1024 x^11)/11] 

Donde la integral se calcula solo una vez, en el tiempo de definición (también podría usarse Evaluate). Entonces, esto parece una compensación. De esta forma, la abstracción funcional está mejor integrada en Mathematica, pero tiene fugas, como lo señaló @WReach. Alternativamente, podría haber sido "resistente al agua", pero quizás por el precio de estar menos expuesto. Esta fue claramente una decisión de diseño.

+0

@Leonid Gracias por la buena explicación y ejemplos. Creo que este http://stackoverflow.com/questions/4198961/what-is-in-your-mathematica-tool-bag es un buen lugar para publicarlo, y quizás también contribuyas con otras ideas. –

+0

@belisarius Gracias, no estaba seguro de dónde poner cosas como esta. ¿Crees que es una buena idea reubicar esta publicación allí y vincularla desde aquí? Y en caso afirmativo, ¿cómo puedo reubicar la publicación? ¿Debería eliminarla aquí y publicar allí? –

+0

@Leonid Creo que puede publicarlo allí y dejar aquí una respuesta básicamente con el primer párrafo y un puntero a la otra respuesta. Yo (con suerte, "Nosotros") nos gustaría recopilar en el _toolbag_ recetas útiles y conceptos aclaratorios. ¡Estoy seguro de que puedes ayudar mucho con eso! También tenga en cuenta que en la pregunta que estamos recopilando un índice, si ya tiene derechos de edición, puede actualizar el índice, o lo haremos por usted si aún no puede hacerlo. –

2

Quizás

Array[#1^#2 &, {#, #}] /. i_Integer :> i == # &[3] 

O

Thread /@ Thread[# == Array[#1^#2 &, {#, #}]] &[3] 
+0

+1 Me gusta mucho el primero –

+0

@belisarius Gracias. :-) Es muy gratificante que un novato como yo tenga algo para ofrecer un gran maestro de la república 13.7K. –

+2

A menudo verá aquí grandes preguntas y respuestas publicadas por personas con muy pocos puntos de representante. No se deje engañar por los números, encontrará usuarios con un conocimiento superior de Mma, y ​​mucho menos representante. Por cierto: ¡bienvenido! –

3

With[{x = #1}, Array[#1^#2 == x &, {x, x}]] & ¿Qué tal?

+1

+1. Sí, esta es una de las posibilidades. En realidad, utilizo este constructo con bastante frecuencia cuando necesito anidar funciones basadas en ranuras, y sé que otras personas también lo usan. –

+0

El argumento designado es de alguna manera necesario. Bueno, la función anónima tiene limitaciones cuando se enfrenta a construir nido. Buena lección para mí novato! – Life

+0

'Secuencia [x, Matriz [# 1^# 2 == x &, {x, x}]] &' también es una habilidad. – Life