Это команда PDL :: Dataflowp, которую можно запустить в бесплатном хостинг-провайдере OnWorks, используя одну из наших многочисленных бесплатных онлайн-рабочих станций, таких как Ubuntu Online, Fedora Online, онлайн-эмулятор Windows или онлайн-эмулятор MAC OS.
ПРОГРАММА:
ИМЯ
PDL :: Dataflow - описание философии потока данных
СИНТАКСИС
pdl> $ a = обнуляет(10);
pdl> $ b = $ a-> slice ("2: 4: 2");
pdl> $ b ++;
pdl> print $ a;
[0 0 1 0 1 0 0 0 0 0]
ПРЕДУПРЕЖДЕНИЕ
Поток данных очень экспериментальный. Многие его функции отключены в версии 2.0, в частности
семейства для однонаправленного потока данных. Если вы хотите использовать однонаправленный поток данных для
что-то, пожалуйста, сначала свяжитесь с автором, и мы решим, как сделать его работоспособным
.
Двунаправленный поток данных (который реализует ->ломтик() и т. д.), однако, полностью функциональна.
Практически любая функция, которая возвращает некоторое подмножество значений в некотором piddle, создаст
привязка так, чтобы
$ a = какой-то пиддл
$ b = $ a-> slice («некоторые части»);
$ b-> установить (3,3,10);
также изменяет соответствующий элемент в $ a. $ b стал окном для некоторых
подэлементы $ a. Вы также можете определить свои собственные процедуры, которые выполняют разные типы
подмножества. Если вы не хотите, чтобы $ b был окном для $ a, вы должны сделать
$ b = $ a-> slice ("некоторые части") -> копировать;
Копирование отключает весь поток данных между двумя точками.
Сложности с однонаправленным потоком данных связаны с такими последовательностями, как
$ b = $ a + 1;
$ b ++;
где есть несколько возможных результатов, и семантика становится немного туманной.
ОПИСАНИЕ
Поток данных появился впервые в PDL2.0. Основная философия потока данных заключается в том, что
> $ a = pdl 2,3,4;
> $ b = $ a * 2;
> печать $ b
[2 3 4]
> $ a-> set (0,5);
> напечатать $ b;
[10 3 4]
должно сработать. Это не так. Было сочтено, что это может быть слишком запутанным для
новички и случайные пользователи языка. Следовательно, вам нужно явно включить
поток данных, поэтому
> $ a = pdl 2,3,4;
> $ a-> doflow ();
> $ b = $ a * 2;
...
дает неожиданный результат. Остальная часть этого документа объясняет различные функции и
детали реализации потока данных.
ленивый оценка
Когда вы рассчитываете что-то вроде приведенного выше
> $ a = pdl 2,3,4;
> $ a-> doflow ();
> $ b = $ a * 2;
на данный момент ничего не будет рассчитано. Даже память для содержимого $ b
не выделено. Только команда
> печать $ b
фактически приведет к вычислению $ b. Это важно помнить при выполнении
измерения производительности и тесты, а также при отслеживании ошибок.
Этому поведению есть объяснение: это может сэкономить циклы, но, что более важно,
представьте себе следующее:
> $ a = pdl 2,3,4;
> $ b = pdl 5,6,7;
> $ c = $ a + $ b;
...
> $ a->изменить размер(4);
> $ b->изменить размер(4);
> напечатать $ c;
Теперь, если $ c было оценено между двумя изменениями размера, возникнет ошибка несовместимости.
размеры могли бы произойти.
Что происходит в текущей версии, так это то, что изменение размера $ a поднимает флаг в $ c:
«PDL_PARENTDIMSCHANGED» и $ b снова поднимают тот же флаг. При следующей оценке $ c
флажки проверяются, и выясняется, что необходим пересчет.
Конечно, ленивое вычисление иногда может сделать отладку более болезненной, потому что ошибки могут
происходят там, где вы их не ожидаете. Лучшая трассировка стека для ошибок находится в
работает для PDL, вероятно, чтобы вы могли переключить переключатель $ PDL :: traceevals и получить хороший
отслеживание того, где на самом деле была ошибка.
Семьи
Это одна из наиболее сложных концепций однонаправленного потока данных. Рассмотрим
следующий код ($ a и $ b - PDL с включенным потоком данных):
$ c = $ a + $ b;
$ e = $ c + 1;
$ d = $ c-> диагональ ();
$ d ++;
$ f = $ c + 1;
Что теперь должны содержать $ e и $ f? А как насчет того, чтобы изменить $ a и произвести перерасчет?
срабатывает.
Чтобы поток данных работал так, как вы ожидаете, должна быть применена довольно странная концепция.
введены: семьи. Составим схему:
аб
\ /
c
/|
/ |
издание
Это то, что PDL фактически хранит в памяти после первых трех строк. Когда $ d изменяется,
мы хотим, чтобы $ c изменился, но мы не хотим, чтобы $ e изменился, потому что он уже есть на графике. Это
теперь может быть неясно, почему вы не хотите его менять, но если бы было 40 строк кода
между 2-й и 4-й строками. Итак, нам нужно сделать копию $ c и $ d:
аб
\ /
c '. . . c
/ | | \
/ | | \
ред. . . df
Обратите внимание, что мы заштриховали исходные c и d, потому что они не соответствуют объектам
в $ c и $ d больше нет. Также обратите внимание на пунктирные линии между двумя объектами: когда $ a
изменилось, и эта диаграмма была переоценена, $ c действительно получает значение c 'с
диагональ увеличена.
Чтобы обобщить вышесказанное, всякий раз, когда piddle мутируется, то есть когда его фактическое * значение * равно
принудительно изменен (не только ссылка:
$ d = $ d + 1
приведет к совершенно другому результату ($ c и $ d больше не будут связаны, тогда как
$ d. = $ d + 1
даст то же самое, что и $ d ++), "семейство", состоящее из всех остальных piddles, соединенных с
измененный piddle путем двустороннего преобразования создается, и все они копируются.
Все фрагменты или преобразования, которые просто выбирают подмножество исходного pdl, являются двусторонними.
Матрица должна быть инверсной. Никаких арифметических операторов нет.
Источники
То, что вам сказали в предыдущем разделе, не совсем верно: описанное поведение
не * всегда * то, что вы хотите. Иногда вам, вероятно, захочется иметь "источник" данных:
$ a = pdl 2,3,4; $ b = pdl 5,6,7;
$ c = $ a + $ b;
линия ($ c);
Теперь, если вы знаете, что $ a изменится, и что вы хотите, чтобы его дочерние элементы изменились с помощью
его можно объявить в источнике данных (XXX не реализовано в текущей версии):
$ a->источник данных(1);
После этого $ a ++ или $ a. = Something не создаст новое семейство, а изменит $ a и вырежет
его отношения с его предыдущими родителями. Все его дочерние элементы будут следовать его текущему значению.
Итак, если $ c в предыдущем разделе был объявлен как источник, $ e и $ f остались бы
равны.
Переплет
Механизм потока данных не был бы очень полезным без возможности привязки событий к
измененные данные. Поэтому мы предоставляем такой механизм:
> $ a = pdl 2,3,4
> $ b = $ a + 1;
> $ c = $ b * 2;
> $ c-> bind (sub {print "A now: $ a, C now: $ c \ n"})
> PDL :: dowhenidle ();
A сейчас: [2,3,4], C сейчас: [6 8 10]
> $ a-> set (0,1);
> $ a-> set (1,1);
> PDL :: dowhenidle ();
A сейчас: [1,1,4], C сейчас: [4 4 10]
Обратите внимание, что обратные вызовы вызываются только во время PDL :: dowhenidle. Простой способ интерфейса
это для механизмов цикла событий Perl (таких как Tk) планируется.
Эту функцию можно использовать по-разному: например, для самообновляющихся графиков.
Бла-бла-бла ХХХ больше объяснений
ограничения
Dataflow как таковой является довольно ограниченным дополнением к Perl. Чтобы получить более изысканный
Кроме того, внутреннее устройство Perl нужно немного взломать. Настоящая реализация
включить поток всего, в том числе
данным
размер данных
тип данных
операции
На данный момент у нас есть только первые два (эй, 50% через пару месяцев неплохо;), но
даже это полезно само по себе. Однако особенно желателен последний, так как он
добавит возможность перетекания закрытий с места на место и сделает многие
вещи более гибкие.
Чтобы все остальное работало, вероятно, нужно изменить внутреннюю структуру потока данных, чтобы она стала
более общие рамки.
Кроме того, было бы неплохо иметь возможность передавать данные во времени, прозрачно (чтобы вы могли
легко определить все виды обработки сигналов).
Используйте PDL :: Dataflowp в Интернете с помощью сервисов onworks.net