2011-12-21 56 views
0

我已经创建了一个PDL矩阵。我需要在每一行之间进行两两比较。目前,我正在使用'where'和'cov'命令来返回两个片的成对比较(在perl循环中生成)。PDL成对排比较

我的问题:如何使用'范围'和'切片'以成对的方式循环行?我怎样才能返回我的指数头寸?我用perl遍历了矩阵。我已经读过使用perl循环会真正瘫痪PDL的威力。

所需的输出:

indexA indexB Value 
pos1 pos5 1 
pos1 pos6 5 
pos1 pos0 7 

要清楚,我只希望使用PDL功能。

这里有一些伪代码会(希望)更好地说明我的观点。

p $b 

[ 
[1 0 3 0] 
[0 1 0 1] 
[1 3 1 3] <- example piddle y 
[0 1 0 1] <- example piddle z 
] 

my concept function{ 


slice $b (grab row z) - works fine 
slice $b (grab row y) - works fine 


($a, $b) = where($a,$b, $a < 3 && $b < 3) - works fine 

p $a [1 1] 
p $b [0 0] 

cov($a $b) - works just fine. 

} 

我只是需要一种方法来在所有行上执行pairwise。我需要做阶乘(n行)比较。

+0

无奈之举......我正在写一个perl循环,但是很遗憾。 – 2011-12-22 16:25:33

+0

我不太清楚你在找什么。你能举出一个更具体的你使用的数据的例子吗? – 2012-02-13 20:07:16

回答

0

我认为你要找的是找到阵列中所有不同行对的方法,然后使用cov来处理每一对行?如果这是正确的,那么我没有听说过cov,通过文档的快速搜索没有帮助。不过,我可以说一些可能有帮助的事情。

我认为你对PDL退出Perl代码过于谨慎,如果你正在做的是循环遍历所有行对的索引并使用slice来拉出那些行,那将是很好的。这在下面的一些示例代码中显示。

此外,你不能像where那样打电话$a < 3等是自己的小辫子和布尔运算符不会做你想做的。改为使用&运算符,并添加一些括号以确保表达式按正确的顺序执行。

除此之外,我不能帮助,除非你纠正我对你的问题的理解,或指示我去cov子程序的一些文件。

use strict; 
use warnings; 

use PDL; 

my $dat = pdl <<END; 
[ 
[1 0 3 0] 
[0 1 0 1] 
[1 3 1 3] 
[0 1 0 1] 
] 
END 

my $max2 = $dat->dim(1) - 1; 

for my $i (0 .. $max2 - 1) { 
    for my $j ($i + 1 .. $max2) { 

    my $row1 = $dat->slice(",($i)"); 
    my $row2 = $dat->slice(",($j)"); 

    ($row1, $row2) = where($row1, $row2, ($row1 < 3) & ($row2 < 3)); 

    cov($row1, $row2); 
    } 
} 
+0

请注意,初始化'$ dat'的方式可能会更清晰。你不需要heredoc。只需使用多行字符串。注释中缺少换行符会造成困难,但是如果您只是在方括号的前方放置字母“q”并删除heredoc cruft,它就可以正常工作:'$ dat = q [1 0 3 0; 0 1 0 1; 1 3 1 3; 0 1 0 1];'注意'q'就在方括号将方括号变成Perl引用之前,同时保持意图。 – 2014-06-10 22:01:50

+0

@DavidMertens:我知道Perl的引用是如何工作的。我使用了heredoc,以便我可以直接从问题中复制数据。 – Borodin 2014-06-10 22:14:25

+0

可以使用'q'运算符直接从问题中复制数据。请参阅http://pdl.perl.org/PDLdocs/Core.html#pdl – 2014-07-08 21:45:22

1

PDL线程是您在这里寻找的概念。沿尺寸循环的一般技术是在适当的位置添加虚拟尺寸,以便计算生成所需的隐式线程循环。对于一个多维问题,可以有多种不同的方式来添加变暗,从而创建线程回调。

对于您的成对行计算,您可以选择两个嵌套的循环,它们在两个索引计数上具有perl循环的切片索引,并且将沿行生成PDL线程。您可以在索引上使用一个perl循环,但可以利用隐式线程来一次计算所有行。

完全PDL线程计算将为每个参数的行上的循环添加一个虚拟维度,以便您一次计算整个N ** 2行计算。这里为形状[4,3]阵列的计算是==运算符的一个示例:

pdl> $b = floor(random(4,3)*5) 

pdl> p $b 

[ 
[0 4 3 3] 
[3 3 4 2] 
[4 0 1 4] 
] 

pdl> p $b(,*3)==$b(,,*3) 

[ 
[ 
    [1 1 1 1] 
    [0 0 0 0] 
    [0 0 0 0] 
] 
[ 
    [0 0 0 0] 
    [1 1 1 1] 
    [0 0 0 0] 
] 
[ 
    [0 0 0 0] 
    [0 0 0 0] 
    [1 1 1 1] 
] 
] 

结果的形状[4,3,3]与对应于该行的第0维小罐由成对计算得到,第一个和第二个dims对应于==操作中涉及的行索引。

如果从或用于这些threadloop计算中的一个需要的索引值,使用xvalsyvals变量容器,或axisvals以生成具有对应于该阵列轴的索引值的小罐。

pdl> p $b->xvals 

[ 
[0 1 2 3] 
[0 1 2 3] 
[0 1 2 3] 
] 


pdl> p $b->yvals 

[ 
[0 0 0 0] 
[1 1 1 1] 
[2 2 2 2] 
] 

有很多与PDL线程实现有关的细节(与perl线程或posix线程不一样)。我建议perldl mailing list供其他PDL用户和开发人员参考和讨论。此外,请参阅PDL Book的第一个在线草案,其中有更全面的PDL计算和线程覆盖。