File Coverage

blib/lib/Math/Interpolator/Robust.pm
Criterion Covered Total %
statement 40 42 95.2
branch 4 4 100.0
condition n/a
subroutine 6 7 85.7
pod 2 2 100.0
total 52 55 94.5


line stmt bran cond sub pod time code
1             =head1 NAME
2              
3             Math::Interpolator::Robust - lazy robust interpolation
4              
5             =head1 SYNOPSIS
6              
7             use Math::Interpolator::Robust;
8              
9             $ipl = Math::Interpolator::Robust->new(@points);
10              
11             $y = $ipl->y($x);
12             $x = $ipl->x($y);
13              
14             =head1 DESCRIPTION
15              
16             This is a subclass of the lazy interpolator class C.
17             This class implements a robust smooth interpolation. See
18             L for the interface. The algorithm is the same one
19             implemented by C in the eager interpolator module
20             C.
21              
22             This code is neutral as to numeric type. The coordinate values used
23             in interpolation may be native Perl numbers, C objects,
24             or possibly other types. Mixing types within a single interpolation is
25             not recommended.
26              
27             Only interior points are handled. Interpolation will be refused at the
28             edges of the curve.
29              
30             =cut
31              
32             package Math::Interpolator::Robust;
33              
34 1     1   20209 { use 5.006; }
  1         3  
  1         50  
35 1     1   7 use warnings;
  1         2  
  1         36  
36 1     1   5 use strict;
  1         2  
  1         117  
37              
38             our $VERSION = "0.005";
39              
40 1     1   816 use parent "Math::Interpolator";
  1         312  
  1         5  
41              
42             =head1 METHODS
43              
44             =over
45              
46             =item $ipl->y(X)
47              
48             =item $ipl->x(Y)
49              
50             These methods are part of the standard C interface.
51              
52             =cut
53              
54             sub _conv {
55 72     72   122 my($self, $x_method, $y_method, $x) = @_;
56 72         104 my $nhood_method = "nhood_$x_method";
57 72         235 my @points = $self->$nhood_method($x, 2);
58 70         203 my($xa, $xb, $xc, $xd) = map { $_->$x_method } @points;
  280         643  
59 70         107 my($ya, $yb, $yc, $yd) = map { $_->$y_method } @points;
  280         649  
60 70         113 my $hxab = $xb - $xa;
61 70         75 my $hxbc = $xc - $xb;
62 70         68 my $hxcd = $xd - $xc;
63 70         74 my $hyab = $yb - $ya;
64 70         83 my $hybc = $yc - $yb;
65 70         78 my $hycd = $yd - $yc;
66 70         100 my $hab = $hxab*$hxab + $hyab*$hyab;
67 70         90 my $hbc = $hxbc*$hxbc + $hybc*$hybc;
68 70         84 my $hcd = $hxcd*$hxcd + $hycd*$hycd;
69 70         141 my $sb = ($hyab*$hbc + $hybc*$hab) / ($hxab*$hbc + $hxbc*$hab);
70 70         115 my $sc = ($hybc*$hcd + $hycd*$hbc) / ($hxbc*$hcd + $hxcd*$hbc);
71 70         141 my $y0 = $yb + ($x - $xb) * ($hybc / $hxbc);
72 70         99 my $dyb = $yb + $sb * ($x - $xb) - $y0;
73 70         96 my $dyc = $yc + $sc * ($x - $xc) - $y0;
74 70         72 my $pdy = $dyb * $dyc;
75 70 100       171 if($pdy == 0) {
    100          
76 4         41 return $y0;
77             } elsif($pdy > 0) {
78 38         385 return $y0 + $pdy/($dyb + $dyc);
79             } else {
80 28         345 return $y0 + $pdy * (($x - $xb) + ($x - $xc)) /
81             (($dyb - $dyc) * $hxbc);
82             }
83             }
84              
85             sub y {
86 72     72 1 34473 my($self, $x) = @_;
87 72         163 return $self->_conv("x", "y", $x);
88             }
89              
90             sub x {
91 0     0 1   my($self, $y) = @_;
92 0           return $self->_conv("y", "x", $y);
93             }
94              
95             =back
96              
97             =head1 SEE ALSO
98              
99             L,
100             L
101              
102             =head1 AUTHOR
103              
104             Andrew Main (Zefram)
105              
106             =head1 COPYRIGHT
107              
108             Copyright (C) 2006, 2007, 2009, 2010, 2012
109             Andrew Main (Zefram)
110              
111             =head1 LICENSE
112              
113             This module is free software; you can redistribute it and/or modify it
114             under the same terms as Perl itself.
115              
116             =cut
117              
118             1;