File Coverage

blib/lib/Statistics/Basic/Mode.pm
Criterion Covered Total %
statement 54 61 88.5
branch 12 24 50.0
condition n/a
subroutine 11 13 84.6
pod 2 2 100.0
total 79 100 79.0


line stmt bran cond sub pod time code
1              
2             package Statistics::Basic::Mode;
3              
4 33     33   179 use strict;
  33         47  
  33         1231  
5 33     33   139 use warnings;
  33         44  
  33         818  
6 33     33   123 use Carp;
  33         46  
  33         1904  
7              
8 33     33   168 use Statistics::Basic;
  33         53  
  33         303  
9 33     33   183 use Scalar::Util qw(blessed);
  33         49  
  33         2003  
10 33     33   173 use base 'Statistics::Basic::_OneVectorBase';
  33         51  
  33         6262  
11              
12             use overload
13             '""' => sub {
14 1 50   1   6 defined( my $q = $_[0]->query ) or return "n/a";
15 1 50       6 return $q if ref $q; # vectors interpolate themselves
16 0         0 $Statistics::Basic::fmt->format_number($_[0]->query, $Statistics::Basic::IPRES);
17             },
18             '0+' => sub {
19 0     0   0 my $q = $_[0]->query;
20 0 0       0 croak "result is multimodal and cannot be used as a number" if ref $q;
21 0         0 $q;
22             },
23 33     33   186 fallback => 1; # tries to do what it would have done if this wasn't present.
  33         56  
  33         302  
24              
25             sub new {
26 4     4 1 1103 my $class = shift;
27              
28 4 50       13 warn "[new $class]\n" if $Statistics::Basic::DEBUG >= 2;
29              
30 4         12 my $this = bless {}, $class;
31 4 50       6 my $vector = eval { Statistics::Basic::Vector->new(@_) } or croak $@;
  4         18  
32 4 50       17 my $c = $vector->_get_computer("mode"); return $c if defined $c;
  4         11  
33              
34 4         179 $this->{v} = $vector;
35              
36 4         17 $vector->_set_computer( mode => $this );
37              
38 4         11 return $this;
39             }
40              
41             sub _recalc {
42 7     7   7 my $this = shift;
43 7         8 my $v = $this->{v};
44 7         16 my $cardinality = $v->query_size;
45              
46 7         14 delete $this->{recalc_needed};
47 7         15 delete $this->{_value};
48 7 50       15 return unless $cardinality > 0;
49 7 50       16 return unless $v->query_filled; # only applicable in certain circumstances
50              
51 7         9 my %mode;
52 7         7 my $max = 0;
53              
54 7         16 for my $val ($v->query) {
55 33     33   8744 no warnings 'uninitialized'; ## no critic
  33         166  
  33         7514  
56 51         114 my $t = ++ $mode{$val};
57 51 100       83 $max = $t if $t > $max;
58             }
59 7         22 my @a = sort {$a<=>$b} grep { $mode{$_}==$max } keys %mode;
  9         22  
  23         41  
60              
61 7 100       31 $this->{_value} = ( (@a == 1) ? $a[0] : Statistics::Basic::Vector->new(\@a) );
62              
63 7 50       15 warn "[recalc " . ref($this) . "] count of $this->{_value} = $max\n" if $Statistics::Basic::DEBUG;
64              
65 7         17 return;
66             }
67              
68             sub is_multimodal {
69 0     0 1   my $this = shift;
70 0           my $that = $this->query;
71              
72 0 0         return (blessed($that) ? 1:0);
73             }
74              
75             1;