2012-01-07 8 views
6

Sono interessato a monitorare lo stato di avanzamento di un calcolo utilizzando Dynamic. Questo può essere fatto interattivamente come segue:Uso di Dynamic per monitorare lo stato di avanzamento delle funzioni

In[3]:= Dynamic[iter] 

In[4]:= Table[{iter, iter^2}, {iter, 1, 500000}]; 

Tuttavia, se la tabella è all'interno di una funzione come

f[m_] := Module[{iter}, Table[{iter, iter^2}, {iter, 1, m}]]; 

come posso tenere traccia del valore di iter, quando esegue la funzione tramite

f[500000]; 

?

+0

'Tabella' già scopa' iter', quindi in questo caso non vedo la necessità di includerlo nel primo argomento di 'Modulo'. Questo potrebbe non essere applicabile a funzioni più complicate, nel qual caso potresti prendere in considerazione l'uso di 'Block' invece di' Module'. –

+0

@Brett Penso che sia un po 'più sottile, anche se in questo caso non riesco a trovare un esempio di uso costruttivo. Gli ambiti 'Table' dinamicamente, ma non scopre' iter' - circoscrive un simbolo 'Modulo' già generato come' iter $ 123' (può essere visto ad es. Con 'Trace'). Nel caso di 'Block', ci sono usi costruttivi per combinazioni come' Module [{sym}, Block [{sym}, ...]] ', per esempio come in questa risposta: http: // stackoverflow.it/questions/7394113/defining-a-function-with-an-optional-value-that-is-by-default-a-function-of-anot/7394668 # 7394668 –

+0

@Leonid Sì, lo so nel codice sopra il 'iter' nella' Tabella 'è in realtà 'iter $ 123', il che rende complicato farvi riferimento al di fuori del' Modulo'. Il mio punto è che, in questo caso particolare, includere 'iter' come una variabile' Module' non è necessario, e in effetti rende le cose più difficili di quanto debbano essere. –

risposta

4

Non sono sicuro che è un buon consiglio, ma:

f[m_] := 
Module[{iter}, getIter[] := iter; 
    Table[{iter, iter^2}, {iter, 1, m}]]; 

E poi:

Dynamic[getIter[]] 

f[500000]; 

EDIT

Questo sarà meglio, ma un po 'più oscura:

ClearAll[f]; 
SetAttributes[f, HoldRest]; 
f[m_, monitorSymbol_: monitor] := 
    Block[{monitorSymbol}, 
    Module[{iter}, 
     monitorSymbol := iter; 
     Table[{iter, iter^2}, {iter, 1, m}]] 
    ]; 

Qui viene designato un determinato simbolo per monitorare lo stato della variabile localizzata. Utilizzando Block, si assicura che il proprio simbolo non ottenga alcun valore globale alla fine (più precisamente, il suo valore globale non viene modificato alla fine - si può anche usare un simbolo che ha un valore globale, se lo si desidera). Il simbolo predefinito è monitor, ma è possibile modificarlo. Ecco come lo si utilizza:

Dynamic[monitor] 

f[500000]; 

Questo è un suggerimento un po 'meglio rispetto al primo più semplice, dal momento utilizzando Block si garantisce che nessuna modifica di stato globali avvengono dopo la funzione termina.

+0

Quanto segue funziona anche, f [m_]: = Modulo [{iter}, getIter = iter; Tabella [{iter, iter^2}, {iter, 1, m}]]. Quale è preferibile? – asim

+0

@asim Tra questi due, è in gran parte una questione di stile. Preferisco quello con 'getIter []', ma questa è solo una preferenza personale. Ma vedi la mia modifica per quello che penso sia una soluzione generalmente migliore. –

+0

Grazie! Sembra sofisticato. – asim

2

Se si desidera utilizzare ProgressIndicator, si può fare qualcosa di simile:

(*version 1.0*) 
Manipulate[ 

msg = "busy..."; 
result = process[[email protected], max]; 
msg = "done!"; 
result, 


[email protected][{ 
    {ProgressIndicator[progressCounter, {0, 100}, 
     ImageSize -> {105, 23}, ImageMargins -> 0, 
     BaselinePosition -> Bottom], 
    Spacer[5], 
    progressCounter, " %"}, 
    {msg} 
    } 
    ], 


{{max, 100, "maximum"}, 10, 10000, 10, Appearance -> "Labeled", 
    ContinuousAction -> False}, 

{{progressCounter, 0}, None}, 
{{result, 0}, None}, 
SynchronousUpdating -> False, 
TrackedSymbols :> {max}, 

Initialization :> 
    (

    process[c_, max_] := Module[{i, tbl}, 
    c = 0.; 
    tbl = Table[0, {max}]; 

    Do[ 
     tbl[[i]] = {i, i^2}; 
     Pause[0.00001]; 
     c = i/max*100., 
     {i, 1, max} 
     ]; 
    c = 0.; 
    tbl[[-1]] 
    ] 
    ) 
] 

enter image description here

2

Per monitorare l'espressione si potrebbe provare a utilizzare Monitor:

Monitor[ 
t = Table[{i, i^2}, {i, 500000}]; 
Last[t] 
, 
i 
] 

Inoltre è possibile utilizzare ProgressIndicator con l'intervallo su i:

Monitor[ 
t = Table[{i, i^2}, {i, 500000}]; 
Last[t] 
, 
ProgressIndicator[i, {1, 500000}] 
] 
Problemi correlati