[英]Undefined subroutine &PDL::divide
我正在以下代码中尝试 Perl 的 PDL:
#!/usr/bin/perl -w
use strict;
use PDL::Core qw(pdl);
use PDL::Math qw(isfinite);
use PDL::Primitive qw(statsover);
my $div = 4;
my @array1 = (0..10);
my $pdl_array = log(pdl(@array1)/$div);
$pdl_array->where(!isfinite($pdl_array)) .= 0;
my($mean,$stdev) = statsover($pdl_array);
die $pdl_array,"\n",$mean," ",$stdev,"\n";
我收到此错误:
未定义的子程序 &PDL::divide 在 ./compare_const.pl 第 10 行调用。
有什么提示吗?非常感谢。
PDL 在设计上很不寻常,因此具有不寻常且有些脆弱的导入机制。 每个 PDL 模块通过将新方法直接插入到 PDL 的包中来向 PDL 添加功能。 这个决定是在 PDL v2 的设计早期就做出的,并且在此后的十年中没有改变。 (没有理由不能改变它,即使以向后兼容的方式,但没有一个 PDL 开发人员留出时间这样做。)
因此,您必须加载少量模块以确保 PDL 具有其必需的基本功能。 如果您查看 PDL 的导入函数,您会注意到它显式地将许多包加载到调用者的命名空间中。 这样做的原因是好的——将功能拆分到多个模块以保持分布合理——但实现与常见的 Perl 实践不一致。 这就是您尝试将特定函数导入命名空间失败的原因。
解决方法已经解释过了。 要么用单个use PDL
替换所有use PDL::...
语句:
use strict;
use warnings;
use PDL;
my $div = 4;
...
或者说use PDL::Lite
(以确保 PDL 的包是完整的),然后将特定功能导入到您的(主)包中
use strict;
use warnings;
use PDL::Lite;
use PDL::Core qw(pdl);
use PDL::Math qw(isfinite);
use PDL::Primitive qw(statsover);
my $div = 4;
...
PDL 具有必须加载的最少内容集。 要正确加载所有这些,您必须use PDL
(它也导出一堆东西)或use PDL::Lite
。
(出于某种原因,我认为您是直接调用 PDL::divide 并得到该错误,因此我在下面给出了原始答案。)
原答案:
我想知道为什么你认为这应该有效?
是的,PDL 会导出一堆东西(如果您使用它,则不会),但这并不能保证您从. (事实上,它似乎从许多不同的地方直接导出到使用包中。)
如果你想避免命名空间污染,我建议要么导入到指定的包中,然后使用那里的东西:
{
package My::PDL;
use PDL;
}
...
My::PDL::divide...
或使用 OO 接口(请参阅 PDL::Lite,我想?)
只需添加use PDL;
并且您的代码将起作用:
#!/usr/bin/perl -w
use strict;
use PDL;
use PDL::Core qw(pdl);
use PDL::Math qw(isfinite);
use PDL::Primitive qw(statsover);
my $div = 4;
my @array1 = (0..10);
my $pdl_array = log( pdl(@array1) / $div );
$pdl_array->where(!isfinite($pdl_array)) .= 0;
my ($mean, $stdev) = statsover($pdl_array);
die $pdl_array, "\n", $mean, " ", $stdev, "\n";
输出:
[0 -1.3862944 -0.69314718 -0.28768207 0 0.22314355 0.40546511 0.55961579 0.69314718 0.81093022 0.91629073]
0.112860814716055 0.696414187766251
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.