File Coverage

blib/lib/AI/Fuzzy/Label.pm
Criterion Covered Total %
statement 44 54 81.4
branch 17 22 77.2
condition 10 18 55.5
subroutine 9 12 75.0
pod 0 11 0.0
total 80 117 68.3


line stmt bran cond sub pod time code
1             package AI::Fuzzy::Label;
2              
3             ## Fuzzy Label ####
4 1         17 use overload ( '>' => \&greaterthan,
5             '<' => \&lessthan,
6             '>=' => \&greaterequal,
7             '<=' => \&lessequal,
8             '<=>'=> \&spaceship,
9             '""' => \&stringify
10 1     1   5438 );
  1         1464  
11              
12             sub new {
13 22     22 0 123 my ($class, $name, $low, $mid, $high) = @_;
14 22         33 my $self = {};
15              
16 22         38 bless $self, $class;
17              
18 22         81 $self->{name} = $name;
19 22         29 $self->{low} = $low;
20 22         35 $self->{mid} = $mid;
21 22         26 $self->{high} = $high;
22              
23 22         80 return $self;
24             }
25              
26             sub name {
27 30     30 0 40 my ($self, $name) = @_;
28              
29 30 50       56 $self->{name} = $name if ($name);
30 30         75 return $self->{name};
31             }
32              
33             sub stringify {
34 0     0 0 0 my $self=shift;
35 0         0 return qq([$self->{name}: $self->{low},$self->{mid},$self->{high}]);
36             }
37              
38             sub lessthan {
39 2     2 0 8 my ($self, $that) = @_;
40              
41 2 100       7 if ($self->{low} < $that->{low}) {
42 1         3 return 1;
43             } else {
44 1         4 return 0;
45             }
46             }
47              
48             sub lessequal {
49 7     7 0 9 my ($self, $that) = @_;
50              
51 7 100       15 if ($self->{low} <= $that->{low}) {
52 4         17 return 1;
53             } else {
54 3         16 return 0;
55             }
56             }
57              
58             sub greaterthan {
59 3     3 0 11 my ($self, $that) = @_;
60              
61 3 100       10 if ($self->{high} > $that->{high}) {
62 1         3 return 1;
63             } else {
64 2         5 return 0;
65             }
66             }
67              
68             sub greaterequal {
69 0     0 0 0 my ($self, $that) = @_;
70              
71 0 0       0 if ($self->{high} >= $that->{high}) {
72 0         0 return 1;
73             } else {
74 0         0 return 0;
75             }
76             }
77              
78             sub between {
79 2     2 0 3 my ($self, $that1, $that2) = @_;
80              
81 2 100 66     7 if ( ( $that1 <= $self and $self <= $that2) ||
      66        
      33        
82             ( $that2 <= $self and $self <= $that1) ) {
83 1         3 return 1;
84             } else {
85 1         3 return 0;
86             }
87             }
88              
89             sub spaceship {
90 35     35 0 58 my ($self, $that) = @_;
91              
92 35         107 return ( $self->{mid} <=> $that->{mid} );
93             }
94              
95             sub applicability {
96             # this function should be called something else..
97             # calculates to what degree this label applies to a $value
98              
99 28     28 0 36 my ($self, $value) = @_;
100 28         25 my $membership = 0;
101              
102             # if the low and mid points are same as value, full membership
103             # same if mid and high are same as value
104 28 50 33     92 if ($self->{mid} == $self->{low} && $value == $self->{low}) { return 1 };
  0         0  
105 28 50 33     94 if ($self->{high} == $self->{mid} && $value == $self->{high}) { return 1 };
  0         0  
106              
107             # m = slope of the line.. (change in y/change in x)
108             # change in y is 1 as membership increases, -1 as it decreases
109 28         50 my $mIncreasing = 1 / ($self->{mid} - $self->{low});
110 28         36 my $mDecreasing = -1 / ($self->{high} - $self->{mid});
111              
112             # reject values that are "out of bounds"
113 28 100 100     135 return ($membership = 0)
114             if ($value <= $self->{low} ) or ($value >= $self->{high} );
115              
116             # now calculate membership:
117             # y=mx+b , just like in algebra
118 8 100       31 if ($value < $self->{mid}) {
    100          
119 3         5 $membership = ($value - $self->{low}) * $mIncreasing;
120             } elsif ($value == $self->{mid}) {
121 1         2 $membership = 1;
122             } else {
123 4         9 $membership = (($value - $self->{mid}) * $mDecreasing) + 1;
124             }
125            
126 8         24 return $membership;
127             }
128              
129             sub range {
130             # returns the distance from one endpoint to the other
131            
132 0     0 0   my ($self) = @_;
133 0           return abs( $self->{high} - $self->{low} );
134             }
135              
136             1;