File Coverage

blib/lib/Math/Spline.pm
Criterion Covered Total %
statement 47 56 83.9
branch 2 4 50.0
condition 0 3 0.0
subroutine 10 11 90.9
pod 0 5 0.0
total 59 79 74.6


line stmt bran cond sub pod time code
1             package Math::Spline;
2 2     2   69347 use 5.006;
  2         6  
  2         63  
3 2     2   9 use strict;
  2         3  
  2         57  
4 2     2   9 use warnings;
  2         8  
  2         61  
5 2     2   8 use Exporter 'import';
  2         2  
  2         123  
6             #require Exporter;
7             #@ISA=qw(Exporter);
8             our @EXPORT_OK=qw(linsearch binsearch spline);
9             our $VERSION = 0.02;
10 2     2   10 use Carp;
  2         2  
  2         164  
11 2     2   1654 use Math::Derivative qw(Derivative2);
  2         1012  
  2         5220  
12              
13             sub new {
14 1     1 0 20 my $type=shift;
15 1         3 my $self=[];
16 1         2 push @{$self},shift; # x
  1         4  
17 1         3 push @{$self},shift; # y
  1         3  
18 1         6 my $y2=[Derivative2($self->[0],$self->[1])];
19 1         42 push @{$self},$y2;
  1         3  
20 1         4 bless $self,$type;
21             }
22              
23             sub evaluate {
24 1     1 0 5 my ($self,$v)=@_;
25 1         10 my $idx=binsearch($self->[0],$v);
26 1         6 spline($self->[0],$self->[1],$self->[2],$idx,$v);
27             }
28              
29             sub spline {
30 1     1 0 2 my ($x,$y,$y2,$i,$v)=@_;
31 1         4 my ($klo,$khi)=($i,$i+1);
32 1         3 my $h=$x->[$khi]-$x->[$klo];
33 1 50       5 if ($h==0) { croak "Zero interval in spline data.\n"; }
  0         0  
34 1         2 my $a=($x->[$khi]-$v)/$h;
35 1         3 my $b=($v-$x->[$klo])/$h;
36 1         7 return $a*$y->[$klo] + $b*$y->[$khi]
37             +(($a*$a*$a-$a)*$y2->[$klo]
38             +($b*$b*$b-$b)*$y2->[$khi])*($h*$h)/6.0;
39             }
40              
41             sub binsearch { # binary search routine finds index just below value
42 1     1 0 2 my ($x,$v)=@_;
43 1         2 my ($klo,$khi)=(0,$#{$x});
  1         2  
44 1         3 my $k;
45 1         23 while (($khi-$klo)>1) {
46 1         4 $k=int(($khi+$klo)/2);
47 1 50       5 if ($x->[$k]>$v) { $khi=$k; } else { $klo=$k; }
  1         3  
  0         0  
48             }
49 1         3 return $klo;
50             }
51              
52             sub linsearch { # more efficient if repetatively doint it
53 0     0 0   my ($x,$v,$khi)=@_; $khi+=1;
  0            
54 0           my $n=$#{$x};
  0            
55 0   0       while($v>$x->[$khi] and $khi<$n) { $khi++; }
  0            
56 0           $_[2]=$khi-1;
57             }
58              
59             1;
60              
61             __END__