File Coverage

blib/lib/PDL/ApplyDim.pm
Criterion Covered Total %
statement 56 58 96.5
branch 9 12 75.0
condition 8 10 80.0
subroutine 9 9 100.0
pod 0 2 0.0
total 82 91 90.1


line stmt bran cond sub pod time code
1             package PDL::ApplyDim;
2              
3 1     1   353865 use v5.36;
  1         3  
4             our $VERSION = '0.002';
5 1     1   4 use Carp;
  1         2  
  1         104  
6             require Exporter;
7             our @ISA=qw(Exporter);
8             our @EXPORT=qw(apply_to apply_not_to);
9 1     1   8 no strict "refs";
  1         2  
  1         762  
10              
11 9     9 0 221175 sub PDL::apply_to($ndarray, $code, $dims, @extra_args){
  9         15  
  9         13  
  9         11  
  9         10  
  9         15  
12             # if code is string, assume it is defined in caller's package
13 9 100 100     55 $code="".caller. "::$code" #
14             unless ref $code eq 'CODE' || $code =~/::/; #
15 9 100       94 return $code->($ndarray->mv($dims, 0), @extra_args)->mv(0,$dims) unless ref $dims;
16 2 50       14 return $code->($ndarray->reorder(_shuffle($dims, $ndarray->ndims)),
17             @extra_args)->reorder(_unshuffle($dims, $ndarray->ndims))
18             if ref $dims eq "ARRAY";
19 0         0 croak "Argument $dims is not scalar nor array";
20             }
21              
22             *apply_to=\&PDL::apply_to;
23              
24 3     3 0 2275 sub PDL::apply_not_to($ndarray, $code, $dims, @extra_args){
  3         5  
  3         4  
  3         4  
  3         21  
  3         5  
25             # if code is string, assume it is defined in caller's package
26 3 50 33     14 $code="".caller. "::$code" #
27             unless ref $code eq 'CODE' || $code =~/::/; #
28 3 100       20 return $code->($ndarray->mv($dims, -1), @extra_args)->mv(-1,$dims) unless
29             ref $dims;
30 2 50       12 return $code->($ndarray->reorder(_shuffle_end($dims, $ndarray->ndims)),
31             @extra_args)->reorder(_unshuffle_end($dims, $ndarray->ndims))
32             if ref $dims eq "ARRAY";
33 0         0 croak "Argument $dims is not scalar nor array";
34             }
35              
36             *apply_not_to=\&PDL::apply_not_to;
37              
38              
39             # ancillary routines
40              
41             # reorder 0..$ndims-1 so @$dims go first
42 4     4   5 sub _shuffle($dims, $ndims){
  4         5  
  4         4  
  4         5  
43 4         4 my %seen;
44 4         19 $seen{$_}++ for my @shuffle=@$dims;
45 4   100     25 $seen{$_}||push @shuffle, $_ for 0..$ndims-1;
46 4         20 return @shuffle;
47             }
48              
49             # reorder 0..$ndims-1 so the first dims
50             # go to positions @$dims. Undo the
51             # effects of _shuffle
52              
53 4     4   362 sub _unshuffle($dims, $ndims){
  4         11  
  4         5  
  4         5  
54 4         6 my %seen;
55             my %unshuffle;
56 4         24 $unshuffle{$dims->[$_]}=$_ for 0..@$dims-1;
57 4         7 my $count=@$dims;
58 4   100     34 (defined $unshuffle{$_}) || ($unshuffle{$_}=$count++) for 0..$ndims-1;
59 4         64 return @unshuffle{0..$ndims-1};
60             }
61              
62             # reorder 0..$ndims-1 so @$dims go last
63 2     2   3 sub _shuffle_end($dims, $ndims){
  2         3  
  2         3  
  2         1  
64 2         4 my @shuffle=_shuffle($dims, $ndims);
65 2         32 return @shuffle[@$dims..$ndims-1, 0..@$dims-1];
66             }
67              
68             # reorder 0..$ndims-1 so the last dims
69             # go to positions @$dims. Undo the
70             # effects of _shuffle_end
71              
72 2     2   269 sub _unshuffle_end($dims, $ndims){
  2         4  
  2         3  
  2         2  
73 2         5 my $division=$ndims-@$dims;
74 2         5 return map {($_+$division)%$ndims} _unshuffle($dims, $ndims);
  8         19  
75             }
76              
77             1;
78              
79             __END__