File Coverage

blib/lib/Math/ErrorPropagation.pm
Criterion Covered Total %
statement 104 107 97.2
branch 23 24 95.8
condition 2 6 33.3
subroutine 20 21 95.2
pod 5 16 31.2
total 154 174 88.5


line stmt bran cond sub pod time code
1             package Math::ErrorPropagation;
2              
3             our $VERSION = '0.01';
4              
5 1     1   21476 use 5.006;
  1         3  
  1         46  
6 1     1   6 use strict;
  1         2  
  1         30  
7 1     1   4 use warnings;
  1         1  
  1         30  
8 1     1   3 use Carp;
  1         2  
  1         162  
9              
10             use overload
11 1         14 '+' => \&plus,
12             '-' => \&minus,
13             '/' => \÷,
14             '*' => \×,
15             '**' => \&power,
16             'exp' => \&eexp,
17             'log' => \&elog,
18             'sin' => \&esin,
19             'cos' => \&ecos,
20             'sqrt' => \&esqrt,
21 1     1   10821 '=' => \©
  1         1116  
22              
23             sub datum{
24 20     20 1 42 my $caller = shift;
25 20   66     77 my $class = ref($caller)||$caller;
26 20         67 my $self = {
27             var => 0.0,
28             value => undef,
29             @_,
30             };
31 20         91 return bless $self, $class;
32             }
33              
34             sub copy{
35 1     1 1 2 my $caller = shift;
36 1         5 my $self = $caller->datum(%$caller);
37 1         3 return $self;
38             }
39              
40              
41             sub central_value{
42 23     23 1 433 my $self = shift;
43 23 100       44 if(@_){$self->{value} = shift}
  2         36  
44 23         88 return $self->{value};
45             }
46              
47             sub sd{
48 3     3 1 4 my $self = shift;
49 3 100       8 if(@_){
50 1         1 my $sd = shift;
51 1         5 $self->{var} = $sd*$sd;
52             }
53 3         11 return sqrt($self->{var});
54             }
55              
56             sub variance{
57 27     27 1 40 my $self = shift;
58 27 100       68 if(@_){
59 2         4 $self->{var} = shift;
60 2 50       6 croak "Given negative value $self->{var} for variance.\n"
61             if($self->{var}<0.0);
62             }
63 27         88 return $self->{var};
64             }
65              
66             sub add{
67 0     0 0 0 my ($caller, $x, $y) = @_;
68 0   0     0 my $class = ref($caller)||$caller;
69 0         0 return $class->datum(value=>$x->{value}+$y->{value},
70             var=>$x->{var}+$y->{var});
71             }
72              
73              
74             # Handles for overloaded operators:
75              
76             # For the binary operators, we assume at least one argument, $x, is an object.
77             # If $y is a ref we assume it is also an Errdatum object; otherwise we
78             # assume it is a number.
79              
80             sub plus{
81 2     2 0 4 my ($x,$y) = @_;
82 2         3 my $class = ref($x);
83              
84 2 100       10 return $class->datum(value=>$x->{value}+$y->{value},
85             var=>$x->{var}+$y->{var}) if ref($y);
86 1         5 return $class->datum(value=>$x->{value}+$y, var=>$x->{var});
87             }
88              
89             sub minus{
90 3     3 0 7 my ($x,$y, $swapped) = @_;
91 3         24 my $class = ref($x);
92 3         7 my $newvar = $x->{var};
93 3         4 my $newval = $x->{value};
94              
95 3 100       7 if (ref($y)){
96 1         3 $newval -= $y->{value} ;
97 1         2 $newvar += $y->{var};
98             }else{
99 2         3 $newval -= $y;
100 2 100       5 if($swapped){ $newval = -$newval;}
  1         2  
101             }
102              
103 3         587 return $class->datum(value=>$newval, var=>$newvar);
104             }
105              
106             sub times{
107 2     2 0 4 my ($x,$y) = @_;
108 2         3 my $class = ref($x);
109              
110 2 100       11 return $class->datum(value=>$x->{value}*$y->{value},
111             var=> $y->{value}*$y->{value}*$x->{var} +
112             $x->{value}*$x->{value}*$y->{var}) if ref($y);
113              
114 1         5 return $class->datum(value=>$x->{value}*$y, var=>$y*$y*$x->{var});
115             }
116              
117             sub divide{
118 3     3 0 7 my ($x,$y, $swapped) = @_;
119 3         4 my $class = ref($x);
120 3         3 my ($newvar, $newval);
121            
122 3 100       7 if (ref($y)){
123 1         3 $newval = $x->{value}/$y->{value};
124 1         5 $newvar = ($x->{var}+$newval*$newval*$y->{var})/($y->{value}*$y->{value});
125             }else{
126 2 100       4 if($swapped){
127 1         7 $newval = $y/$x->{value};
128 1         4 $newvar = ($newval*$newval*$x->{var})/($x->{value}*$x->{value});
129             }else{
130 1         3 $newval = $x->{value}/$y;
131 1         2 $newvar = $x->{var}/($y*$y);
132             }
133             }
134              
135 3         8 return $class->datum(value=>$newval, var=>$newvar);
136             }
137              
138             sub power{
139 3     3 0 6 my ($x,$y, $swapped) = @_;
140 3         4 my $class = ref($x);
141 3         4 my ($newvar, $newval);
142            
143 3 100       8 if (ref($y)){
144 1         17 $newval = $x->{value}**$y->{value};
145 1         3 $newvar = $y->{value}*$newval/$x->{value};
146 1         3 $newvar *= $newvar*$x->{var};
147 1         4 my $otherbit = log($x->{value})*$newval;
148 1         2 $newvar += $otherbit*$otherbit*$y->{var};
149             }else{
150 2 100       6 if($swapped){
151 1         4 $newval = $y**$x->{value};
152 1         3 $newvar = log($y)*$newval;
153 1         2 $newvar *= $newvar*$x->{var};
154             }else{
155 1         3 $newval = $x->{value}**$y;
156 1         3 $newvar = $y*$newval/$x->{value};
157 1         2 $newvar *= $newvar*$x->{var};
158             }
159             }
160              
161 3         8 return $class->datum(value=>$newval, var=>$newvar);
162             }
163              
164             sub eexp{
165 1     1 0 2 my $x = shift;
166 1         2 my $class = ref($x);
167 1         4 my $newval = exp($x->{value});
168 1         4 return $class->datum(value=>$newval,
169             var=>$x->{var}*$newval*$newval);
170             }
171              
172             sub elog{
173 1     1 0 3 my $x = shift;
174 1         2 my $class = ref($x);
175              
176 1         7 return $class->datum(value=>log($x->{value}),,
177             var=>$x->{var}/($x->{value}*$x->{value}));
178             }
179              
180             sub esin{
181 1     1 0 2 my $x = shift;
182 1         2 my $class = ref($x);
183              
184 1         5 my $newval = sin($x->{value});
185 1         4 my $newvar = $newval*cos($x->{value});
186              
187 1         5 return $class->datum(value=>$newval,
188             var=>$x->{var}*$newvar*$newvar);
189             }
190              
191             sub ecos{
192 1     1 0 2 my $x = shift;
193 1         2 my $class = ref($x);
194              
195 1         3 my $newval = cos($x->{value});
196 1         3 my $newvar = $newval*sin($x->{value});
197            
198 1         3 return $class->datum(value=>$newval,
199             var=>$x->{var}*$newvar*$newvar);
200             }
201              
202             sub esqrt{
203 1     1 0 3 my $x = shift;
204 1         3 my $class = ref($x);
205            
206 1         7 return $class->datum(value=>sqrt($x->{value}),
207             var=>$x->{var}/(4.0*$x->{value}));
208              
209             }
210              
211              
212             1;
213              
214             __END__