File Coverage

blib/lib/Math/VecStat.pm
Criterion Covered Total %
statement 111 122 90.9
branch 37 58 63.7
condition 4 6 66.6
subroutine 13 15 86.6
pod 13 13 100.0
total 178 214 83.1


line stmt bran cond sub pod time code
1            
2             require Exporter;
3             package Math::VecStat;
4             @Math::VecStat::ISA=qw(Exporter);
5             @EXPORT_OK=qw(max min maxabs minabs sum average
6             vecprod ordered convolute
7             sumbyelement diffbyelement
8             allequal median);
9             $Math::VecStat::VERSION = '0.08';
10            
11 1     1   743 use strict;
  1         2  
  1         1514  
12            
13             sub max {
14 5 100   5 1 92 my $v=ref($_[0]) ? $_[0] : \@_;
15 5         5 my $i=$#{$v};
  5         9  
16 5         6 my $j=$i;
17 5         7 my $m=$v->[$i];
18 5 100       12 while (--$i >= 0) { if ($v->[$i] > $m) { $m=$v->[$i]; $j=$i; }}
  6         19  
  1         2  
  1         3  
19 5 50       24 return wantarray ? ($m,$j): $m;
20             }
21            
22             sub min {
23 5 100   5 1 80 my $v=ref($_[0]) ? $_[0] : \@_;
24 5         6 my $i=$#{$v};
  5         9  
25 5         6 my $j=$i;
26 5         7 my $m=$v->[$i];
27 5 100       14 while (--$i >= 0) { if ($v->[$i] < $m) { $m=$v->[$i]; $j=$i; }}
  6         15  
  3         5  
  3         7  
28 5 50       26 return wantarray ? ($m,$j): $m;
29             }
30            
31             sub maxabs {
32 2 50   2 1 8 my $v=ref($_[0]) ? $_[0] : \@_;
33 2         4 my $i=$#{$v};
  2         4  
34 2         4 my $j=$i;
35 2         3 my $m=abs($v->[$i]);
36 2 100       24 while (--$i >= 0) { if (abs($v->[$i]) > $m) { $m=abs($v->[$i]); $j=$i}}
  4         21  
  2         3  
  2         5  
37 2 50       10 return (wantarray ? ($m,$j) : $m);
38             }
39            
40             sub minabs {
41 1 50   1 1 5 my $v=ref($_[0]) ? $_[0] : \@_;
42 1         2 my $i=$#{$v};
  1         1  
43 1         2 my $j=$i;
44 1         3 my $m=abs($v->[$i]);
45 1 50       3 while (--$i >= 0) { if (abs($v->[$i]) < $m) { $m=abs($v->[$i]); $j=$i}}
  2         8  
  0         0  
  0         0  
46 1 50       19 return (wantarray ? ($m,$j) : $m);
47             }
48            
49             sub sum {
50 4 50   4 1 10 my $v=ref($_[0]) ? $_[0] : \@_;
51 4         6 my $s=0;
52 4         6 foreach(@{$v}) { $s+=$_; }
  4         6  
  8         17  
53 4         8 return $s;
54             }
55            
56             # spinellia@acm.org, handle the empty array case
57             sub average {
58 5 100   5 1 46 my $v=ref($_[0]) ? $_[0] : \@_;
59 5 100       6 return undef unless $#{$v} >= 0;
  5         16  
60 4 50       4 return $#{$v}==-1 ? 0 : sum($v)/(1+$#{$v});
  4         15  
  4         19  
61             }
62            
63             sub vecprod {
64 0     0 1 0 my $c = shift;
65 0 0       0 my $v=ref($_[0]) ? $_[0] : \@_;
66 0 0       0 return undef unless $#{$v} >= 0;
  0         0  
67 0         0 my @result = map( $_ * $c, @{$v} );
  0         0  
68 0         0 return \@result;
69             }
70            
71             sub ordered
72             {
73 5 50   5 1 45 my $v=ref($_[0]) ? $_[0] : \@_;
74 5 50       8 if( scalar( @{$v} ) < 2 ){ return 1; }
  5         14  
  0         0  
75 5         8 for(my $i=0; $i<$#{$v}; $i++ ){
  13         27  
76 10 100       32 return 0 if $v->[$i] > $v->[$i+1];
77             }
78 3         17 return 1;
79             }
80            
81             sub allequal
82             {
83 12     12 1 70 my($v,$u) = @_;
84 12 50 33     53 return undef unless (defined($v) and defined($u)); # this is controversial
85 12 100       13 return undef unless ($#{$v} == $#{$u});
  12         16  
  12         33  
86 9         11 my $i= @{$v};
  9         11  
87 9 100       38 while (--$i >= 0) { return 0 unless( $v->[$i] == $u->[$i]); }
  19         53  
88 7         18 return 1;
89             }
90            
91             sub sumbyelement
92             {
93 2     2 1 21 my($v,$u) = @_;
94            
95 2 50       3 return undef unless ($#{$v} == $#{$u});
  2         3  
  2         6  
96 2         4 my @summed;
97 2         3 my $i= @{$v};
  2         5  
98 2         5 while (--$i >= 0) { $summed[$i] = $v->[$i] + $u->[$i]; }
  3         8  
99 2         8 return \@summed;
100             }
101            
102             sub diffbyelement
103             {
104 4     4 1 32 my($v,$u) = @_;
105            
106 4 50       5 return undef unless ($#{$v} == $#{$u});
  4         6  
  4         12  
107 4         5 my @summed;
108 4         5 my $i= @{$v};
  4         7  
109 4         9 while (--$i >= 0) { $summed[$i] = $v->[$i] - $u->[$i]; }
  12         34  
110 4         20 return \@summed;
111             }
112            
113             sub convolute
114             {
115 3     3 1 32 my($v,$u) = @_;
116            
117 3 50       4 return undef unless ($#{$v} == $#{$u});
  3         6  
  3         7  
118 3         4 my @conv;
119 3         5 my $i= @{$v};
  3         4  
120 3         9 while (--$i >= 0) { $conv[$i] = $v->[$i]*$u->[$i]; }
  6         17  
121 3         15 return \@conv;
122             }
123            
124             sub _justToAvoidWarnings
125             {
126 0     0   0 my $a = $Math::VecStat::VERSION;
127             }
128            
129             sub median
130             {
131 5 50   5 1 68 my $v=ref($_[0]) ? $_[0] : \@_;
132 5         5 my $n = scalar @{$v};
  5         11  
133            
134             # generate a list of [value,index] pairs
135 5         10 my @tras = map( [$v->[$_],$_], 0..$#{$v} );
  5         62  
136             # sort by ascending value, then by original position
137             # suggested by david@jamesgang.com
138 5 50       24 my @sorted = sort { ($a->[0] <=> $b->[0])
  59         145  
139             or ($a->[1] <=> $b->[1]) } @tras;
140             # find the middle ordinal
141 5         16 my $med = int( $n / 2 );
142            
143             # when there are several identical median values
144             # we arbitrarily (but consistently) choose the first one
145             # in the original array
146            
147 5   100     34 while( ($med >= 1) && ($sorted[$med]->[0] == $sorted[$med-1]->[0]) ){
148 6         26 $med--;
149             }
150            
151 5         28 return $sorted[$med];
152             }
153            
154            
155             1;
156            
157             __END__