2012-01-07 7 views
6

Estoy interesado en monitorear el progreso de un cálculo usando Dynamic. Esto se puede hacer de forma interactiva de la siguiente manera:Uso de Dynamic para monitorear el progreso dentro de las funciones

In[3]:= Dynamic[iter] 

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

Sin embargo, si la tabla está dentro de una función como

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

cómo puedo realizar un seguimiento del valor de ITER, cuando ejecuto la función a través de

f[500000]; 

?

+0

'Table' ya abarca' iter', por lo que en este caso no veo la necesidad de incluirlo en el primer argumento de 'Module'. Es posible que esto no se aplique en funciones más complicadas, en cuyo caso podría considerar usar 'Bloque' en lugar de' Módulo'. –

+0

@Brett Creo que es un poco más sutil, aunque no puedo dar con un ejemplo de uso constructivo de este caso. 'Table' abarca dinámicamente, pero no 'iter': alcanza un símbolo generado por' Module' como 'iter $ 123' (se puede ver, por ejemplo, con' Trace'). En el caso de 'Block', hay usos constructivos para combinaciones como' Module [{sym}, Block [{sym}, ...]] ', por ejemplo como en esta respuesta: http: // stackoverflow.com/questions/7394113/definition-a-function-with-an-optional-value-that-is-by-default-a-function-of-anot/7394668 # 7394668 –

+0

@Leonid Sí, lo sé en el código sobre el 'iter' en' Table' está realmente 'iter $ 123', lo que hace que sea difícil referirse a él desde fuera del' Module'. Mi punto es que, en este caso particular, incluir 'iter' como una variable' Module' es innecesario, y de hecho hace que las cosas sean más difíciles de lo que deben ser. –

Respuesta

4

No estoy seguro de que es un buen consejo, pero:

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

Y luego:

Dynamic[getIter[]] 

f[500000]; 

EDITAR

Ésta será mejor, pero algo más oscura:

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

Aquí, designa un cierto símbolo para controlar el estado de su variable localizada. Al usar Block, se asegura de que su símbolo no obtenga ningún valor global al final (más precisamente, que su valor global no se modifique al final; también puede usar un símbolo que tenga algún valor global, si lo desea).) El símbolo predeterminado es monitor, pero puede cambiarlo. Aquí es cómo lo usa:

Dynamic[monitor] 

f[500000]; 

Esta es una sugerencia un poco mejor que el primero uno más sencillo, ya que al utilizar Block usted garantiza que no hay modificaciones globales del estado ocurren después de la función termina.

+0

Lo siguiente también funciona, f [m_]: = Módulo [{iter}, getIter = iter; Tabla [{iter, iter^2}, {iter, 1, m}]]. ¿Cuál es preferible? – asim

+0

@asim Entre estos dos, es en gran medida una cuestión de estilo. Prefiero el que tiene 'getIter []', pero esto es solo una preferencia personal. Pero vea mi edición por lo que creo que es una solución generalmente mejor. –

+0

Gracias! Eso se ve sofisticado – asim

2

Si desea utilizar ProgressIndicator, se puede hacer algo como esto:

(*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

Para supervisar una expresión que se podría tratar de usar Monitor:

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

Además, puede use ProgressIndicator con el rango en i:

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