[英]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.