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   139 use strict;
  33         36  
  33         1165  
5 33     33   143 use warnings;
  33         37  
  33         754  
6 33     33   157 use Carp;
  33         44  
  33         1863  
7              
8 33     33   157 use Statistics::Basic;
  33         42  
  33         241  
9 33     33   157 use Scalar::Util qw(blessed);
  33         50  
  33         1478  
10 33     33   142 use base 'Statistics::Basic::_OneVectorBase';
  33         44  
  33         5231  
11              
12             use overload
13             '""' => sub {
14 1 50   1   12 defined( my $q = $_[0]->query ) or return "n/a";
15 1 50       15 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   201 fallback => 1; # tries to do what it would have done if this wasn't present.
  33         50  
  33         271  
24              
25             sub new {
26 4     4 1 1141 my $class = shift;
27              
28 4 50       16 warn "[new $class]\n" if $Statistics::Basic::DEBUG >= 2;
29              
30 4         12 my $this = bless {}, $class;
31 4 50       7 my $vector = eval { Statistics::Basic::Vector->new(@_) } or croak $@;
  4         22  
32 4 50       16 my $c = $vector->_get_computer("mode"); return $c if defined $c;
  4         27  
33              
34 4         207 $this->{v} = $vector;
35              
36 4         19 $vector->_set_computer( mode => $this );
37              
38 4         15 return $this;
39             }
40              
41             sub _recalc {
42 7     7   18 my $this = shift;
43 7         9 my $v = $this->{v};
44 7         20 my $cardinality = $v->query_size;
45              
46 7         22 delete $this->{recalc_needed};
47 7         18 delete $this->{_value};
48 7 50       21 return unless $cardinality > 0;
49 7 50       19 return unless $v->query_filled; # only applicable in certain circumstances
50              
51 7         7 my %mode;
52 7         9 my $max = 0;
53              
54 7         18 for my $val ($v->query) {
55 33     33   7528 no warnings 'uninitialized'; ## no critic
  33         64  
  33         6331  
56 51         65 my $t = ++ $mode{$val};
57 51 100       96 $max = $t if $t > $max;
58             }
59 7         20 my @a = sort {$a<=>$b} grep { $mode{$_}==$max } keys %mode;
  8         22  
  23         45  
60              
61 7 100       29 $this->{_value} = ( (@a == 1) ? $a[0] : Statistics::Basic::Vector->new(\@a) );
62              
63 7 50       16 warn "[recalc " . ref($this) . "] count of $this->{_value} = $max\n" if $Statistics::Basic::DEBUG;
64              
65 7         19 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;