这是 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> 打印 $a;
[0 0 1 0 1 0 0 0 0 0
警告
数据流是非常实验性的。 它的许多功能在 2.0 中被禁用,特别是
用于单向数据流的系列。 如果您希望将单向数据流用于
有事,请先联系作者,我们会想办法让它发挥作用
一次。
双向数据流(实现 ->片() 等)功能齐全,但是。
几乎任何返回某些 piddle 中值的某些子集的函数都会产生一个
绑定,以便
$a = 一些小玩意儿
$b = $a->slice("某些部分");
$b->set(3,3,10);
还更改了 $a 中的相应元素。 $b 已成为某些人的有效窗口
$a 的子元素。 您还可以定义自己的例程来执行不同类型的
子集。 如果你不希望 $b 成为 $a 的窗口,你必须这样做
$b = $a->slice("某些部分")->copy;
复制关闭了两个 piddles 之间的所有数据流。
单向数据流的困难与序列有关
$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 是启用了数据流的 pdls):
$ c = $ a + $ b;
$e = $c + 1;
$d = $c->diagonal();
$d++;
$f = $c + 1;
$e 和 $f 现在应该包含什么? 当 $a 被改变并且重新计算是
触发。
为了使数据流像您期望的那样工作,必须有一个相当奇怪的概念
介绍:家庭。 让我们做一个图表:
AB
\ /
c
/|
/ |
编辑
这就是 PDL 在前三行之后实际在内存中的内容。 当 $d 改变时,
我们希望 $c 改变,但我们不希望 $e 改变,因为它已经在图表上。 它
现在可能不清楚为什么你不希望它改变但如果有 40 行代码
在第 2 行和第 4 行之间,您会。 所以我们需要复制 $c 和 $d:
AB
\ /
C' 。 . . C
/ | |
/ | |
ed' 。 . . df
请注意,我们为原始 c 和 d 设置了底色,因为它们不对应于对象
在 $c 和 $d 中。 另外,请注意两个对象之间的虚线:当 $a 是
更改并重新评估此图,$c 确实获得了 c' 的值
对角线增加。
概括上述内容,每当 piddle 发生突变时,即当其实际 *value* 为
强行更改(不仅仅是参考:
$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)正在计划中。
此功能有多种用途:例如,自更新图形。
等等等等等等XXX更多解释
限制
像这样的数据流是 Perl 之上的一个相当有限的补充。 为了获得更精致的
此外,Perl 的内部结构需要稍微修改一下。 一个真正的实施将
启用一切流动,包括
data
数据大小
数据类型
操作
目前我们只有前两个(嘿,几个月后 50% 还不错;)但是
即使这本身很有用。 然而,尤其是最后一个是可取的,因为它
将增加从一个地方到另一个地方流动关闭的可能性,并使许多
东西更灵活。
为了让其余部分工作,数据流的内部可能需要更改为
更通用的框架。
此外,能够像清醒一样及时地流动数据会很好(这样你就可以
轻松定义各种信号处理的东西)。
使用 onworks.net 服务在线使用 PDL::Dataflowp