我有一个AoAs的哈希:
$hash{$key} = [
[0.0,1.0,2.0],
10.0,
[1.5,9.5,5.5],
];
Run Code Online (Sandbox Code Playgroud)
我需要紧缩如下:
$err += (($hash{$key}[0][$_]-$hash{key}[2][$_])*$hash{$key}[1])**2 foreach (0 .. 2);
Run Code Online (Sandbox Code Playgroud)
计算两个数组之间的平方加权差.由于我的哈希很大,我希望PDL有助于加速计算,但它不是出于某种原因.我还是PDL的新手,所以我可能搞砸了.PDL下面的脚本慢了大约10倍.描述:以下两个脚本是我试图简单地表示我的程序中的内容.我将一些参考值读入哈希值,然后我将观察值(在运行中拉入哈希值)与一些权重的那些值进行比较.在脚本中,我将引用数组,权重和观察数组设置为某个任意固定值,但在运行时不会出现这种情况.
这里有两个没有和PDL的简单脚本:
use strict;
use warnings;
use Time::HiRes qw(time);
my $t1 = time;
my %hash;
my $error = 0;
foreach (0 .. 10000){
$hash{$_} = [
[0.000, 1.000, 2.0000],
10.0,
[1.5,9.5,5.5],
];
foreach my $i (0 .. 2){
$error += (($hash{$_}[0][$i]-$hash{$_}[2][$i])*$hash{$_}[1])**2;
}
}
my $t2 = time;
printf ( "total time: %10.4f error: %10.4f\n", $t2-$t1,$error);
Run Code Online (Sandbox Code Playgroud)
use strict;
use warnings;
use PDL;
use Time::HiRes qw(time);
my $t1 = time;
my %hash;
my $error = 0;
foreach (0 .. 10000){
$hash{$_}[0] = pdl[0.000, 1.000, 2.0000];
$hash{$_}[1] = pdl[10.0];
$hash{$_}[2] = pdl[1.5,9.5,5.5];
my $e = ($hash{$_}[0]-$hash{$_}[2])*$hash{$_}[1];
$error += inner($e,$e);
}
my $t2 = time;
printf ( "total time: %10.4f error: %10.4f\n", $t2-$t1, $error);
Run Code Online (Sandbox Code Playgroud)
PDL经过优化,可处理数组计算.您正在为数据使用哈希,但由于键是数字,因此可以根据PDL数组对象重新表示,以获得性能上的巨大成功.示例代码下面的所有PDL版本的运行约36倍比原来快了不PDL代码(300X比原来快与PDL代码).
use strict;
use warnings;
use PDL;
use Time::HiRes qw(time);
my $t1 = time;
my %hash;
my $error = 0;
my $pdl0 = zeros(3,10001); # create a [3,10001] pdl
$pdl0 .= pdl[0.000, 1.000, 2.0000];
my $pdl1 = zeros(1,10001); # create a [1,10001] pdl
$pdl1 .= pdl[10.0];
my $pdl2 = zeros(3,10001); # create a [3,10001] pdl
$pdl2 .= pdl[1.5,9.5,5.5];
my $e = ($pdl0 - $pdl2)*$pdl1;
$error = sum($e*$e);
my $t2 = time;
printf ( "total time: %10.4f error: %10.4f\n", $t2-$t1, $error);
Run Code Online (Sandbox Code Playgroud)
有关使用PDL进行计算的深入介绍,请参阅PDL手册.该PDL主页也是万物PDL一个很好的起点.