Skip to content

Commit

Permalink
use continue to simplify qsort PDL_IF_BAD
Browse files Browse the repository at this point in the history
  • Loading branch information
mohawk2 committed Nov 1, 2024
1 parent b0b1b99 commit 950325d
Showing 1 changed file with 63 additions and 71 deletions.
134 changes: 63 additions & 71 deletions Basic/Ufunc/ufunc.pd
Original file line number Diff line number Diff line change
Expand Up @@ -984,22 +984,20 @@ EOD
sub qsort_returnempty { 'if ($PDL(a)->nvals == 0) return PDL_err;' }

# move all bad values to the end of the array
pp_def(
'qsort',
pp_def('qsort',
HandleBad => 1,
Inplace => 1,
Pars => 'a(n); [o]b(n);',
Code =>
'register PDL_Indx nn = 0;
PDL_IF_BAD(register PDL_Indx nb = $SIZE(n) - 1;,)
'.qsort_returnempty().'
loop(n) %{
PDL_IF_BAD(if ($ISBAD(a())) { $SETBAD(b(n=>nb)); nb--; }
else,) { $b(n=>nn) = $a(); nn++; }
%}
if ( nn != 0 ) {
nn -= 1;
' . generic_qsort('b') . ' }',
Code => '
register PDL_Indx nn = 0;
PDL_IF_BAD(register PDL_Indx nb = $SIZE(n) - 1;,)
'.qsort_returnempty().'
loop(n) %{
PDL_IF_BAD(if ($ISBAD(a())) { $SETBAD(b(n=>nb)); nb--; continue; },)
$b(n=>nn) = $a(); nn++;
%}
if ( nn == 0 ) continue; nn -= 1;
' . generic_qsort('b'),
Doc => '
=for ref
Expand All @@ -1020,27 +1018,26 @@ Bad values are moved to the end of the array:
pdl> p qsort($y)
[22 25 32 32 41 42 47 59 74 76 76 79 96 96 96 98 BAD BAD BAD BAD]
',
); # pp_def qsort
);

sub generic_qsort_ind {
'qsort_ind_$PPSYM() ($P(a), $P(indx),
0, nn);';
}

pp_def(
'qsorti',
pp_def('qsorti',
HandleBad => 1,
Pars => 'a(n); indx [o]indx(n);',
Code =>
'register PDL_Indx nn = PDL_IF_BAD(0,$SIZE(n)-1), nb = $SIZE(n) - 1;
'.qsort_returnempty().'
loop(n) %{
PDL_IF_BAD(if ($ISBAD(a())) { $indx(n=>nb) = n; nb--; }
else { $indx(n=>nn) = n; nn++; } /* play safe since nn used more than once */
,$indx() = n;)
%}
PDL_IF_BAD(if ( nn == 0 ) continue; nn -= 1;,)
' . generic_qsort_ind(),
Code => '
register PDL_Indx nn = PDL_IF_BAD(0,$SIZE(n)-1), nb = $SIZE(n) - 1;
'.qsort_returnempty().'
loop(n) %{
PDL_IF_BAD(if ($ISBAD(a())) { $indx(n=>nb) = n; nb--; }
else { $indx(n=>nn) = n; nn++; } /* play safe since nn used more than once */
,$indx() = n;)
%}
PDL_IF_BAD(if ( nn == 0 ) continue; nn -= 1;,)
' . generic_qsort_ind(),
BadDoc =>
'Bad elements are moved to the end of the array:
Expand All @@ -1061,53 +1058,49 @@ Quicksort a vector and return index of elements in ascending order.
=cut
'
); # pp_def: qsorti
);

# move all bad values to the end of the array
#
pp_def(
'qsortvec',
pp_def('qsortvec',
HandleBad => 1,
Inplace => 1,
Pars => 'a(n,m); [o]b(n,m);',
Code =>
'register PDL_Indx nn = PDL_IF_BAD(0,$SIZE(m)-1), nb = $SIZE(m) - 1;
char is_inplace = ($P(a) == $P(b));
PDL_Indx nd = $SIZE(n);
'.qsort_returnempty().'
PDL_IF_BAD(loop(m) %{
char allgood_a = 1;
loop(n) %{ if ( $ISBAD(a()) ) { allgood_a = 0; break; } %}
PDL_Indx copy_dest = allgood_a ? nn++ : nb--;
if (is_inplace) {
if (allgood_a) continue; /* nothing to do */
char anybad_b = 0;
do {
anybad_b = 0;
loop(n) %{ if ($ISBAD(b(m=>copy_dest))) { anybad_b = 1; break; } %}
if (anybad_b) copy_dest = nb--;
} while (anybad_b);
if (m != copy_dest)
loop(n) %{
/* as in-place we know same badval source and dest */
$GENERIC() tmp = $b(m=>copy_dest);
$b(m=>copy_dest) = $a();
$a() = tmp;
%}
if (m >= nb-1) { nn = nb+1; break; } /* run out of "good" vectors */
} else {
loop(n) %{
if ($ISBAD(a())) $SETBAD(b(m=>copy_dest));
else $b(m=>copy_dest) = $a();
%}
}
%}
if ( nn != 0 ) {
nn -= 1;,
if (!is_inplace) { loop(n,m) %{ $b() = $a(); %} }
{)' .
generic_qsortvec('b','nd') .'
}',
Code => '
register PDL_Indx nn = PDL_IF_BAD(0,$SIZE(m)-1), nb = $SIZE(m) - 1;
char is_inplace = ($P(a) == $P(b));
PDL_Indx nd = $SIZE(n);
'.qsort_returnempty().'
PDL_IF_BAD(loop(m) %{
char allgood_a = 1;
loop(n) %{ if ( $ISBAD(a()) ) { allgood_a = 0; break; } %}
PDL_Indx copy_dest = allgood_a ? nn++ : nb--;
if (is_inplace) {
if (allgood_a) continue; /* nothing to do */
char anybad_b = 0;
do {
anybad_b = 0;
loop(n) %{ if ($ISBAD(b(m=>copy_dest))) { anybad_b = 1; break; } %}
if (anybad_b) copy_dest = nb--;
} while (anybad_b);
if (m != copy_dest)
loop(n) %{
/* as in-place we know same badval source and dest */
$GENERIC() tmp = $b(m=>copy_dest);
$b(m=>copy_dest) = $a();
$a() = tmp;
%}
if (m >= nb-1) { nn = nb+1; break; } /* run out of "good" vectors */
} else {
loop(n) %{
if ($ISBAD(a())) $SETBAD(b(m=>copy_dest));
else $b(m=>copy_dest) = $a();
%}
}
%}
if ( nn == 0 ) continue; nn -= 1;,
if (!is_inplace) { loop(n,m) %{ $b() = $a(); %} }
)' . generic_qsortvec('b','nd'),
Doc => '
=for ref
Expand Down Expand Up @@ -1142,16 +1135,15 @@ Vectors with bad components are moved to the end of the array:
[ BAD 0]
]
',
); # pp_def qsortvec
);

sub generic_qsortvec_ind {
my $pdl = shift;
my $ndim = shift;
'pdl_qsortvec_ind_$PPSYM() ($P(' . $pdl . '), $P(indx), '. $ndim.', 0, nn);';
}

pp_def(
'qsortveci',
pp_def('qsortveci',
HandleBad => 1,
Pars => 'a(n,m); indx [o]indx(m);',
Code =>
Expand Down Expand Up @@ -1192,7 +1184,7 @@ so qsortveci may be thought of as a collapse operator of sorts (groan).
Vectors with bad components are moved to the end of the array as
for L</qsortvec>.
',
);
);

pp_def('magnover',
HandleBad => 1,
Expand Down

0 comments on commit 950325d

Please sign in to comment.