File Coverage

lib/Spreadsheet/Engine/Fn/Approximator.pm
Criterion Covered Total %
statement 30 30 100.0
branch 4 4 100.0
condition 8 11 72.7
subroutine 4 4 100.0
pod 1 1 100.0
total 47 50 94.0


line stmt bran cond sub pod time code
1             package Spreadsheet::Engine::Fn::Approximator;
2              
3 28     28   157 use strict;
  28         292  
  28         869  
4 28     28   152 use warnings;
  28         60  
  28         688  
5              
6 28     28   134 use base 'Exporter';
  28         61  
  28         8538  
7              
8             our @EXPORT_OK = qw/iterate/;
9              
10             sub iterate {
11 72     72 1 341 my %arg = @_;
12              
13 72   50     224 my $guess = $arg{initial_guess} || 0.01;
14 72   100     242 my $maxloop = $arg{max_iterations} || 20;
15 72   50     293 my $epsilon = $arg{epsilon} || 0.0000001;
16              
17 72         129 my $value = $guess;
18 72         96 my $oldvalue = 0;
19 72         123 my $delta = 1;
20 72         83 my $olddelta;
21             my $factor;
22 72         108 my $tries = 0;
23              
24 72   66     378 while (abs($delta) > $epsilon && ($value != $oldvalue)) {
25 1646         4304 $delta = $arg{function}->($value);
26              
27 1646 100       3341 if (defined $olddelta) {
28 1574         2659 my $m = ($delta - $olddelta) / ($value - $oldvalue); # get slope
29 1574         1620 $oldvalue = $value;
30 1574   100     4452 $value = $value - $delta / ($m || 0.01); # look for zero crossing
31 1574         2076 $olddelta = $delta;
32             } else { # first time - no old values
33 72         192 $oldvalue = $value;
34 72         92 $value = 1.1 * $value;
35 72         93 $olddelta = $delta;
36             }
37              
38             # error if we don't converge quickly enough
39 1646 100       12503 return if (++$tries >= $maxloop);
40             }
41              
42 60         183 return $value;
43             }
44              
45             1;
46              
47             __END__