diff --git a/lib/PDL/Slices.pd b/lib/PDL/Slices.pd index 9dfe2b52f..07f3672e3 100644 --- a/lib/PDL/Slices.pd +++ b/lib/PDL/Slices.pd @@ -1186,7 +1186,8 @@ pp_def('rldvec', PMCode =>pp_line_numbers(__LINE__, <<'EOC'), sub PDL::rldvec { my ($a,$b,$c) = @_; - ($c,my $sm) = defined($c) ? ($c,$c->dim(1)) : (PDL->null,$a->sumover->max->sclr); + $c = PDL->null unless defined $c; + my $sm = $c->isnull ? $a->sumover->max->sclr : $c->dim(1); PDL::_rldvec_int($a,$b,$c,$sm); return $c; } @@ -1209,6 +1210,9 @@ of row-vectors each of length $M, run-length decode to $c(). Can be used together with clump() to run-length decode "values" of arbitrary dimensions. +Note: $sumover_max is used internally only. Any value provided will be +ignored. + See also: L. Contributed by Bryan Jurish Emoocow@cpan.orgE. EOD @@ -1257,7 +1261,8 @@ pp_def('rldseq', PMCode =>pp_line_numbers(__LINE__, <<'EOC'), sub PDL::rldseq { my ($a,$b,$c) = @_; - ($c,my $sm) = defined($c) ? ($c,$c->dim(1)) : (PDL->null,$a->sumover->max->sclr); + $c = PDL->null unless defined $c; + my $sm = $c->isnull ? $a->sumover->max->sclr : $c->dim(1); PDL::_rldseq_int($a,$b,$c,$sm); return $c; } @@ -1283,6 +1288,9 @@ as for: $c = null; $c = $c->append($b($_)+sequence($a->type,$a($_))) foreach (0..($N-1)); +Note: $sumover_max is used internally only. Any value provided will be +ignored. + See also: L. Contributed by Bryan Jurish Emoocow@cpan.orgE. EOD @@ -1352,19 +1360,21 @@ sub rldND { my ($counts,$elts) = (shift,shift); my @vdimsN = $elts->dims; - ##-- construct output pdl - my ($data); - if ($#_ >= 0) { $data = $_[0]; } - else { - my $size = $counts->sumover->max; ##-- get maximum size for Nth-dimension for small encodings - my @countdims = $counts->dims; - shift(@countdims); - $data = zeroes($elts->type, @vdimsN, @countdims); - } + ##-- allocate output pdl if none given + my $data = @_ ? $_[0] : PDL->null; + my $have_null = $data->isnull; ##-- guts: call rldvec() - rldvec($counts, $elts->clump($#vdimsN), $data->clump($#vdimsN)); - + rldvec($counts, $elts->clump($#vdimsN), + $have_null ? $data : $data->clump($#vdimsN)); + + ##-- reshape output according to $elts + if ($have_null) { + my @dims = $data->dims; + pop(@vdimsN); + splice(@dims, 0, 1, @vdimsN); + $data->reshape(@dims); + } return $data; } EOF diff --git a/t/slice.t b/t/slice.t index 7a4c42fbc..871d3df16 100644 --- a/t/slice.t +++ b/t/slice.t @@ -404,6 +404,11 @@ is_pdl $pv, my $pv_expect = pdl([[1,2],[3,4],[5,6],[0,0],[0,0],[0,0]]), "rlevec( my $pd = rldvec($pf,$pv); is_pdl $pd, $p, "rldvec()"; +rldvec($pf,$pv,my $pdn = null); +is_pdl $pdn, $p, "rldvec() all args"; +my $pdp = zeroes($p); +rldvec($pf,$pv,$pdp); +is_pdl $pdp, $p, "rldvec() pre-alloc"; is_pdl enumvec($p), indx([0,1,2,0,1,0]), "enumvec()"; is_pdl enumvecg($p), indx([0,0,0,1,1,2]), "enumvecg()"; @@ -413,6 +418,16 @@ is_pdl $pv, $pv_expect, "rleND():2d:elts"; $pd = rldND($pf,$pv); is_pdl $pd, $p, "rldND():2d"; +my $pfnz = which $pf; +my $pfr = $pf->dice($pfnz); +my $pvr = $pv->dice('X', $pfnz); +my $pdr = rldND($pfr, $pvr); +is_pdl $pdr, $p, "rldND() nonzero freqs"; +rldND($pfr, $pvr, my $pdn_nd = PDL->null); +is_pdl $pdn_nd, $p, "rldND() all args"; +my $pdpND = zeroes($p); +rldND($pfr, $pvr, $pdpND); +is_pdl $pdpND, $p, "rldND() pre-alloc"; ## rleND, rldND: Nd my $pnd1 = (1 *(sequence(long, 2,3 )+1))->slice(",,*3"); @@ -432,6 +447,8 @@ is_pdl $pv_nd, $pv_expect_nd, "rleND():Nd:elts"; ## 11..11: test rldND(): Nd my $pd_nd = rldND($pf_nd,$pv_nd); is_pdl $pd_nd, $p_nd, "rldND():Nd"; +rldND($pf_nd,$pv_nd,my $pd_nd_n = PDL->null); +is_pdl $pd_nd_n, $p_nd, "rldND():Nd all args"; ## 12..12: test enumvec(): nd my $v_nd = $p_nd->clump(2); @@ -453,6 +470,8 @@ my $seqs = zeroes(short, 0); $seqs = $seqs->append(sequence(short,$_)) foreach ($lens->list); $seqs += $lens->rld($offs); is_pdl $lens->rldseq($offs), $seqs, "rldseq():data"; +$lens->rldseq($offs, my $seq_dec = null); +is_pdl $seq_dec, $seqs, "rldseq():null"; my ($len_got,$off_got) = $seqs->rleseq(); is $off_got->type, $seqs->type, "rleseq():type"; is_pdl $len_got->where($len_got), $lens->where($lens), "rleseq():lens";