簡體   English   中英

在PDL上向零舍入

[英]Rounding towards zero on a PDL

我有一個混合值(正數和負數)的PDL(類型double )。 我想將每個條目四舍五入。 所以+1.2變為+1+1.7變為+1-1.2變為-1-1.7變為-1

我考慮過使用int() ,但是它不適用於PDL類型。

我還可以使用round(abs($x) - 0.5) * ($x <=> 0) ,但不確定如何在PDL上使用此邏輯。

指針?

PDL :: Math中的rint函數的文檔說:

如果要將半整數從零舍入,請嘗試floor(abs($x)+0.5)*($x<=>0)

只需對其稍作更改即可使其按您想要的方式工作:

#!/usr/bin/perl
use warnings;
use strict;

use PDL;

my $pdl = 'PDL'->new(
    [  1,  1.3,  1.9,  2,  2.1,  2.7 ],
    [ -1, -1.3, -1.9, -2, -2.1, -2.7 ]
);
$pdl = floor(abs($pdl)) * ($pdl <=> 0);
print $pdl;

輸出:

[
 [ 1  1  1  2  2  2]
 [-1 -1 -1 -2 -2 -2]
]

PDL :: Mathfloorceilrint 所有這些功能都就位。

因此,應執行以下操作:

#!/usr/bin/env perl
use warnings;
use strict;

use PDL;

my $pdl = 'PDL'->new(
    [  1,  1.3,  1.9,  2,  2.1,  2.7 ],
    [ -1, -1.3, -1.9, -2, -2.1, -2.7 ]
);

print $pdl;

floor(inplace $pdl->where($pdl >= 0));
ceil (inplace $pdl->where($pdl <  0));

print $pdl;

輸出:

[
 [   1  1.3  1.9    2  2.1  2.7]
 [  -1 -1.3 -1.9   -2 -2.1 -2.7]
]

[
 [ 1  1  1  2  2  2]
 [-1 -1 -1 -2 -2 -2]
]

PS:@choroba的答案在較舊的MacBook Pro使用無線程 perl 5.24的以下基准測試中運行速度提高了約20%:

#!/usr/bin/env perl
use warnings;
use strict;

use constant N_ELEMS => $ARGV[0] || 100_000;

use Dumbbench;
use PDL;

sub one_scan {
    my $pdl = 100 * grandom(N_ELEMS);
    $pdl = floor(abs($pdl)) * ($pdl <=> 0);
    return;
}

sub two_scans {
    my $pdl = 100 * grandom(N_ELEMS);
    floor(inplace $pdl->where($pdl >= 0));
    ceil (inplace $pdl->where($pdl <  0));
    return;
}

sub baseline {
    my $pdl = 100 * grandom(N_ELEMS);
    return;
}

my $bench = Dumbbench->new;

$bench->add_instances(
    Dumbbench::Instance::PerlSub->new(code => \&baseline,  name => 'Baseline'),
    Dumbbench::Instance::PerlSub->new(code => \&one_scan,  name => 'One Scan'),
    Dumbbench::Instance::PerlSub->new(code => \&two_scans, name => 'Two Scans'),
);

$bench->run;
$bench->report;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM