Este es el comando PDL :: Dataflowp que se puede ejecutar en el proveedor de alojamiento gratuito de OnWorks utilizando una de nuestras múltiples estaciones de trabajo en línea gratuitas, como Ubuntu Online, Fedora Online, emulador en línea de Windows o emulador en línea de MAC OS.
PROGRAMA:
NOMBRE
PDL :: Dataflow - descripción de la filosofía del flujo de datos
SINOPSIS
pdl> $ a = ceros(10);
pdl> $ b = $ a-> segmento ("2: 4: 2");
pdl> $ b ++;
pdl> imprimir $ a;
[0 0 1 0 1 0 0 0 0 0]
ADVERTENCIA
El flujo de datos es muy experimental. Muchas funciones están deshabilitadas para 2.0, particularmente
familias para el flujo de datos unidireccional. Si desea utilizar un flujo de datos unidireccional para
algo, comuníquese primero con el autor y resolveremos cómo hacerlo funcional
de nuevo.
Flujo de datos bidireccional (que implementa ->rebanada() etc.) es completamente funcional, sin embargo.
Casi cualquier función que devuelva algún subconjunto de los valores en algún piddle hará una
vinculante para que
$ a = algo de pipí
$ b = $ a-> slice ("algunas partes");
$ b-> conjunto (3,3,10);
también cambia el elemento correspondiente en $ a. $ b se ha convertido efectivamente en una ventana para algunos
subelementos de $ a. También puede definir sus propias rutinas que realizan diferentes tipos de
subconjuntos. Si no desea que $ b sea una ventana a $ a, debe hacerlo
$ b = $ a-> corte ("algunas partes") -> copiar;
La copia apaga todo el flujo de datos entre los dos piddles.
Las dificultades con el flujo de datos unidireccional están relacionadas con secuencias como
$ b = $ a + 1;
$ b ++;
donde hay varios resultados posibles y la semántica se vuelve un poco turbia.
DESCRIPCIÓN
El flujo de datos es nuevo en PDL2.0. La filosofía básica detrás del flujo de datos es que
> $ a = pdl 2,3,4;
> $ b = $ a * 2;
> imprimir $ b
[2 3 4]
> $ a-> conjunto (0,5);
> imprimir $ b;
[10 3 4]
Deberia trabajar. No es así. Se consideró que hacer esto podría resultar demasiado confuso para
novatos y usuarios ocasionales del idioma. Por lo tanto, debe activar explícitamente
flujo de datos, entonces
> $ a = pdl 2,3,4;
> $ a-> doflow ();
> $ b = $ a * 2;
...
produce el resultado inesperado. El resto de este documento explica varias características y
detalles de la implementación del flujo de datos.
Lazy evaluación
Cuando calcula algo como lo anterior
> $ a = pdl 2,3,4;
> $ a-> doflow ();
> $ b = $ a * 2;
no se habrá calculado nada en este momento. Incluso la memoria para el contenido de $ b
no ha sido asignado. Solo el comando
> imprimir $ b
en realidad hará que se calcule $ b. Es importante tener esto en cuenta al realizar
mediciones de rendimiento y puntos de referencia, así como al rastrear errores.
Hay una explicación para este comportamiento: puede ahorrar ciclos pero, lo que es más importante,
imagina lo siguiente:
> $ a = pdl 2,3,4;
> $ b = pdl 5,6,7;
> $ c = $ a + $ b;
...
> $ a->cambiar el tamaño(4);
> $ b->cambiar el tamaño(4);
> imprimir $ c;
Ahora, si $ c se evaluó entre los dos cambios de tamaño, una condición de error incompatible
se producirían tamaños.
Lo que sucede en la versión actual es que al cambiar el tamaño de $ a se levanta una bandera en $ c:
"PDL_PARENTDIMSCHANGED" y $ b simplemente levantan la misma bandera nuevamente. La próxima vez que se evalúe $ c,
se comprueban las banderas y se encuentra que se necesita un nuevo cálculo.
Por supuesto, la evaluación perezosa a veces puede hacer que la depuración sea más dolorosa porque los errores pueden
ocurren en algún lugar donde no los esperaría. Un mejor seguimiento de pila para errores está en el
funciona para PDL, probablemente para que pueda alternar un interruptor $ PDL :: traceevals y obtener una buena
rastro de dónde estaba realmente el error.
Familias
Este es uno de los conceptos más intrincados del flujo de datos unidireccional. Considera el
siguiente código ($ ay $ b son pdls que tienen el flujo de datos habilitado):
$ c = $ a + $ b;
$ e = $ c + 1;
$ d = $ c-> diagonal ();
$ d ++;
$ f = $ c + 1;
¿Qué deberían contener $ e y $ f ahora? ¿Qué pasa cuando se cambia $ a y se vuelve a calcular
motivado.
Para que el flujo de datos funcione como es de esperar, se debe utilizar un concepto bastante extraño
introducido: familias. Hagamos un diagrama:
ab
\ /
c
/|
/ |
y
Esto es lo que PDL tiene en la memoria después de las tres primeras líneas. Cuando se cambia $ d,
queremos que $ c cambie pero no queremos que $ e cambie porque ya está en el gráfico. Eso
puede que no esté claro ahora por qué no desea que cambie, pero si hubiera 40 líneas de código
entre la segunda y la cuarta línea, lo haría. Entonces necesitamos hacer una copia de $ cy $ d:
ab
\ /
C' . . . C
/ | | \
/ | | \
ed '. . . df
Observe que imprimamos las cyd originales, porque no corresponden a los objetos
en $ cy $ d más. Además, observe las líneas de puntos entre los dos objetos: cuando $ a es
cambiado y este diagrama se vuelve a evaluar, $ c realmente obtiene el valor de c 'con el
diagonal incrementada.
Para generalizar sobre lo anterior, siempre que se mute un piddle, es decir, cuando su * valor * real es
cambiado a la fuerza (no solo la referencia:
$ d = $ d + 1
produciría un resultado completamente diferente ($ cy $ d ya no estarían ligados mientras que
$ d. = $ d + 1
daría lo mismo que $ d ++), una "familia" que consta de todos los demás piddles unidos a la
Se crea piddle mutado por una transformación bidireccional y todos esos se copian.
Todos los cortes o transformaciones que simplemente seleccionan un subconjunto del pdl original son bidireccionales.
La matriz inversa debería ser. No hay operadores aritméticos.
Fuentes
Lo que le dijeron en la sección anterior no es del todo cierto: el comportamiento descrito es
no * siempre * lo que quieres. A veces, probablemente le gustaría tener una "fuente" de datos:
$ a = pdl 2,3,4; $ b = pdl 5,6,7;
$ c = $ a + $ b;
línea ($ c);
Ahora, si sabe que $ a va a cambiar y quiere que sus hijos cambien con
, puede declararlo en una fuente de datos (XXX no implementado en la versión actual):
$ a->fuente de datos(1);
Después de esto, $ a ++ o $ a. = Algo no creará una nueva familia pero alterará $ ay cortará
su relación con sus padres anteriores. Todos sus hijos seguirán su valor actual.
Entonces, si $ c en la sección anterior se hubiera declarado como fuente, $ e y $ f permanecerían
igual.
Encuadernación
Un mecanismo de flujo de datos no sería muy útil sin la capacidad de enlazar eventos en
datos modificados. Por lo tanto, proporcionamos dicho mecanismo:
> $ a = pdl 2,3,4
> $ b = $ a + 1;
> $ c = $ b * 2;
> $ c-> bind (sub {imprimir "A ahora: $ a, C ahora: $ c \ n"})
> PDL :: dowhenidle ();
A ahora: [2,3,4], C ahora: [6 8 10]
> $ a-> conjunto (0,1);
> $ a-> conjunto (1,1);
> PDL :: dowhenidle ();
A ahora: [1,1,4], C ahora: [4 4 10]
Observe cómo las devoluciones de llamada solo se llaman durante PDL :: dowhenidle. Una forma fácil de interactuar
se está planificando esto para los mecanismos de bucle de eventos de Perl (como Tk).
Hay muchos tipos de usos para esta función: gráficos de actualización automática, por ejemplo.
Bla, bla, bla, XXX más explicación
Limitaciones
El flujo de datos como tal es una adición bastante limitada en la parte superior de Perl. Para conseguir un mas refinado
Además, las partes internas de Perl deben ser pirateadas un poco. Una verdadera implementación
permitir el flujo de todo, incluido
datos
tamaño de datos
tipo de datos
operaciones
De momento solo tenemos los dos primeros (oye, el 50% en un par de meses no está mal;) pero
incluso esto es útil por sí mismo. Sin embargo, especialmente el último es deseable ya que
agregaría la posibilidad de fluir cierres de un lugar a otro y haría muchos
cosas más flexibles.
Para que el resto funcione, los componentes internos del flujo de datos probablemente deban cambiarse para que sean un
marco más general.
Además, sería bueno poder hacer fluir los datos en el tiempo, de manera lúcida (para que pudiera
definir fácilmente todo tipo de cosas de procesamiento de señales).
Use PDL :: Dataflowp en línea usando los servicios de onworks.net