File: 01_ufunc.t

package info (click to toggle)
libpdl-ccs-perl 1.24.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 612 kB
  • sloc: perl: 2,720; makefile: 3; ansic: 3
file content (148 lines) | stat: -rw-r--r-- 4,640 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# -*- Mode: CPerl -*-
# t/01_ufunc.t
use Test::More;
use strict;
use warnings;


##-- common subs
my $TEST_DIR;
BEGIN {
  use File::Basename;
  use Cwd;
  $TEST_DIR = Cwd::abs_path dirname( __FILE__ );
  eval qq{use lib ("$TEST_DIR/$_/blib/lib","$TEST_DIR/$_/blib/arch");} foreach (qw(../../.. ../.. ..));
  do "$TEST_DIR/common.plt" or  die("$0: failed to load $TEST_DIR/common.plt: $@");
}

##-- common modules
use PDL;
use PDL::CCS::Ufunc;
use PDL::VectorValued;
use version;

##-- basic data
my $a = pdl(double, [
                      [10,0,0,0,-2],
                      [3,9,0,0,0],
                      [0,7,8,7,0],
                      [3,0,8,7,5],
                      [0,8,0,9,9],
                      [0,4,0,0,2],
                     ]);

my $agood    = ($a!=0);
my $abad     = !$agood;
my $awhich   = $a->whichND;
my $awhich1  = $awhich->slice("(1)")->qsort->slice("*1,");
my $awhich1i = $awhich->slice("(1)")->qsorti;
my $avals    = $a->indexND($awhich)->index($awhich1i);

##-- i..(i+2): test_ufunc($pdl_ufunc_name, $ccs_ufunc_name, $missing_val)
sub test_ufunc {
  my ($pdl_ufunc_name, $ccs_ufunc_name, $missing_val) = @_;
  print "test_ufunc($pdl_ufunc_name, $ccs_ufunc_name, $missing_val)\n";

  my $ccs_ufunc = PDL->can("ccs_accum_${ccs_ufunc_name}")
    or die("no CCS Ufunc ccs_accum_${ccs_ufunc_name} defined!");
  my $pdl_ufunc = PDL->can("${pdl_ufunc_name}")
    or die("no PDL Ufunc ${pdl_ufunc_name} defined!");

  $missing_val = 0 if (!defined($missing_val));
  $missing_val = PDL->topdl($missing_val);
  if ($missing_val->isbad) { $a = $a->setbadif($abad); }
  else                     { $a->where($abad) .= $missing_val; $a->badflag(0); }

  $missing_val = $missing_val->convert($a->type);
  my @amissing = $missing_val->isbad && $ccs_ufunc_name !~ /^n(?:bad|good)/ ? (0,0) : ($missing_val,$a->dim(0));

  my $dense_rc = $pdl_ufunc->($a);
  my ($which_rc,$nzvals_rc) = $ccs_ufunc->($awhich1, $avals, @amissing);
  my $decoded_rc = $dense_rc->zeroes;
  $decoded_rc   .= $missing_val;
  $decoded_rc->indexND($which_rc) .= $nzvals_rc;

  my $label = "${pdl_ufunc_name}:missing=$missing_val";

  ##-- exceptions
 SKIP: {
    ##-- RT bug #126294 (see also analogous tests in CCS/t/03_ufuncs.t)
    ## - maybe test ($Config{stdchar}=~/unsigned/) or ($Config{stdchar} eq 'unsigned char') instead
    skip("RT #126294 - PDL::borover() appears to be broken", 1)
      if ($label eq 'borover:missing=BAD' && pdl([10,0,-2])->setvaltobad(0)->borover->sclr != -2);

    ##-- actual test
    pdlok("${label}:vals", $decoded_rc, $dense_rc);
  }
}

my $BAD = pdl(0)->setvaltobad(0);

##----------------------------------------------------------------------
## generic tests

for my $missing (0,1,31,$BAD) {
  for my $pdl_ufunc_name (
    #qw(sumover),
    qw(sumover prodover dsumover dprodover),
    qw(andover orover bandover borover),
    qw(maximum minimum),
    qw(nbadover ngoodover), #nnz
    qw(average),
  )
    {
      my $ccs_ufunc_name = $pdl_ufunc_name;
      $ccs_ufunc_name =~ s/over$//;
      test_ufunc($pdl_ufunc_name, $ccs_ufunc_name, $missing);
    }
}


##----------------------------------------------------------------------
## specific tests

##-- test explicit output allocation
my $dense_rv = $a->sumover;
my $which_prealloc = zeroes(indx, 1, 6);
my $nzvals_prealloc = zeroes($a->type, 6);
foreach (
  [null, null],
  [null, $nzvals_prealloc],
  [$which_prealloc, null],
  [$which_prealloc, $nzvals_prealloc],
) {
  my $label = "sumover with explicit output PDLs (".join(', ', map {$_->isnull ? 'null' : 'pre-allocated'} @$_).")";
  my ($tmp_which, $tmp_nzvals) = @$_;
  my ($which_rv,$nzvals_rv) = ccs_accum_sum($awhich1, $avals, 0, 0, $tmp_which, $tmp_nzvals);
  my $decoded_rv = $dense_rv->zeroes;
  $decoded_rv->indexND($which_rv) .= $nzvals_rv;

  pdlok($label, $decoded_rv, $dense_rv);
}

##-- test unexpected output type: https://github.com/moocow-the-bovine/PDL-CCS/issues/18
sub test_borover_output_type {
  my ($label, $missing) = @_;
  PDL::_ccs_accum_bor_int(
    my $ixIn=PDL->pdl(indx, [[0]]),
    my $nzvalsIn=pdl(double, [65536]),
    $missing,
    0,
    my $ixOut=null,
    my $nzvalsOut=null,
    my $nOut=null
  );
  SKIP: {
    skip("expect the unexpected if missing is passed as a scalar", 1)
      if (!ref($missing) && version->parse($PDL::VERSION) >= version->parse('2.096'));

    isok("test_borover_output_type:$label:type", $nzvalsOut->type, longlong);
    pdlok("test_borover_output_type:$label:vals", $nzvalsOut, $nzvalsIn);
  }
}
test_borover_output_type('missing=double', pdl(double, 0));
test_borover_output_type('missing=scalar', 0);

print "\n";

done_testing;