2011-08-21 16 views
7

Quando uso Manipolare che posso fare:Definire controllo come variabile in Mathematica

Manipulate[x, {u, 1, 10}] 

In realtà i miei controlli sono molte e complicato, quindi io preferirei prendere la loro definizione fuori l'espressione Manipolare, come quello :

control = {u, 1, 10} 
Manipulate[x, control] 

Ma questo risultato in un errore:

Manipulate argument control does not have the correct form for a \ 
variable specification. 

Perché non funziona in questo modo?

+1

L'esempio che hai fornito, e quello che vedo nella maggior parte delle risposte è che la complessità del codice è non ridotto affatto. Alcune delle risposte creano una parte di codice molto complessa usando un numero significativamente maggiore di caratteri, una serie di costrutti di scoping aggiuntivi ecc. Sento che solo migliorando il _layout_ del codice (ogni controllo sulla propria linea, raggruppando visivamente i controlli correlati ecc.) In la maggior parte dei casi è sufficiente. –

+0

Attraverso le risposte capisco meglio cosa sta succedendo, ma hai perfettamente ragione: nessuno dei costrutti rende il codice molto più semplice. Quello che mi fa impazzire è la folle profondità di annidamento delle parentesi nel mio codice. Probabilmente è il modo Lisp di farlo, ma non c'è un modo per rendere i miei programmi più lineari? –

+1

@Sieda bene, se un pezzo di codice appare in un posto, quindi sono per lo più d'accordo con te. Di solito, ciò ha senso se a) si sta utilizzando il codice in più di un posto, oppure b) il codice completo sta diventando troppo lungo per essere facilmente modificato. Ad esempio, ho un notebook con un 'Manipulate' il cui codice non è presente sullo schermo da 13 pollici del mio macbook. Devo usare un trucco come questo, o provare a caricare l'intera cosa nella mia testa ogni volta che ho bisogno di modificarlo.Poiché devo già riflettere sul problema che sto effettivamente risolvendo, preferisco ridurre la complessità del codice aggiungendo alcuni caratteri. – acl

risposta

10

Questo

con = {u, 1, 10}; 
Manipulate[ 
u, 
[email protected] 
] 

funziona. Suppongo che non funziona senza il Evaluate perché

Attributes[Manipulate] 

mostra che Manipulate ha l'attributo HoldAll (ma potrei sbagliarmi). Per vedere l'effetto di questo attributo, provate questo:

SetAttributes[f, HoldAll] 
f[con] 
f[[email protected]] 
g[con] 
(* 
f[con] 
f[{u, 1, 10}] 
g[{u, 1, 10}] 
*) 

Così, sembra che a causa della HoldAll atribute, Manipulate semplicemente non vede "dentro" con a meno che non si valuta in modo esplicito.

+1

Mi hai battuto per * così tanto! Quindi, +1 – Simon

+0

@Simon grazie! +1 anche per te. Suppongo che finirò con meno uptotes comunque :) – acl

+0

Grazie, funziona quando copio e incollo il tuo esempio in un nuovo foglio di lavoro. Nel mio vecchio foglio di lavoro dovevo premere Maiusc + Invio su ogni riga prima che funzionasse, anche sulla riga con control = {u, 1, 10}, che non era cambiato. Perché devo rivalutare le linee? –

11

Manipulate ha il HoldAll attribute. È possibile forzare control per valutare e tutto funziona ok

control = {u, 1, 10}; 
Manipulate[x[u], Evaluate[control]] 

Il problema di questo è che la variabile u non è correttamente localizzata, quindi se avete già impostato, ad esempio, u=1 da qualche parte, allora la Manipulate restituirà un errore .

Potrebbe essere meglio se si utilizzano costrutti di scoping appropriati come With o DynamicModule a seconda esattamente di ciò che si sta tentando di fare.

Questo è forse eccessivo, ma assicura che u è locale e si muove control al di fuori della manipolare:

DynamicModule[{u}, With[{control = {u, 1, 10}}, Manipulate[x[u], control]]] 
Problemi correlati