Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions Makefile.PL
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ WriteMakefile(
'Test::More' => 0,
'Test::FailWarnings' => 0,
'Test::Exception' => 0,
'Module::Runtime' => 0,
'Module::Pluggable' => 0,
'Carp' => 0,
'List::MoreUtils' => 0,
'List::Util' => 0,
Expand Down
68 changes: 33 additions & 35 deletions lib/Math/Function/Interpolator.pm
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,17 @@ use Number::Closest::XS qw(find_closest_numbers_around);
use List::MoreUtils qw(pairwise indexes);
use List::Util qw(min max);

use Math::Function::Interpolator::Linear;
use Math::Function::Interpolator::Quadratic;
use Math::Function::Interpolator::Cubic;

=head1 NAME

Math::Function::Interpolator - Interpolation made easy

=head1 VERSION

Version 0.08
Version 0.09

=head1 SYNOPSIS

Expand Down Expand Up @@ -45,7 +49,7 @@ HashRef of points for interpolations

=cut

our $VERSION = '0.08';
our $VERSION = '0.09';

=head1 METHODS

Expand All @@ -72,36 +76,15 @@ sub new {

my $self = {
_points => $params_ref{'points'},
_classes_loaded => 0
_linear_obj => 0,
_cubic_obj => 0,
_quadratic_obj => 0
};
my $obj = bless $self, $class;

if ( $class =~/Interpolator$/i ){
# Load all interpolator classes when only made object from main
# Interpolator classes
$obj->_load_interpolator_classes();
}

return $obj;
}

sub _load_interpolator_classes {
my ( $self ) = @_;

use Module::Runtime;
use Module::Pluggable
sub_name => 'interpolate_methods',
search_path => ['Math::Function::Interpolator'],
;

my @modules = $self->interpolate_methods();
foreach my $module (@modules) {
Module::Runtime::require_module($module);
}
$self->{'_classes_loaded'} = 1;
return 1;
}

=head2 points

points
Expand All @@ -121,9 +104,14 @@ This method do the linear interpolation. It solves for point_y linearly given po

sub linear {
my ( $self, $x ) = @_;
return Math::Function::Interpolator::Linear->new(
points => $self->points
)->linear( $x );
my $linear_obj = $self->{'_linear_obj'};
if ( !$linear_obj ){
$linear_obj = Math::Function::Interpolator::Linear->new(
points => $self->points
);
$self->{'_linear_obj'} = $linear_obj;
}
return $linear_obj->linear( $x );
}

=head2 quadratic
Expand All @@ -134,9 +122,14 @@ This method do the quadratic interpolation. It solves the interpolated_y value g

sub quadratic {
my ( $self, $x ) = @_;
return Math::Function::Interpolator::Quadratic->new(
points => $self->points
)->quadratic( $x );
my $quadratic_obj = $self->{'_quadratic_obj'};
if ( !$quadratic_obj ) {
$quadratic_obj = Math::Function::Interpolator::Quadratic->new(
points => $self->points
);
$self->{'_quadratic_obj'} = $quadratic_obj;
}
return $quadratic_obj->quadratic( $x );
}

=head2 cubic
Expand All @@ -147,9 +140,14 @@ This method do the cubic interpolation. It solves the interpolated_y given point

sub cubic {
my ( $self, $x ) = @_;
return Math::Function::Interpolator::Cubic->new(
points => $self->points
)->cubic( $x );
my $cubic_obj = $self->{'_cubic_obj'};
if ( !$cubic_obj ) {
$cubic_obj = Math::Function::Interpolator::Cubic->new(
points => $self->points
);
$self->{'_cubic_obj'} = $cubic_obj;
}
return $cubic_obj->cubic( $x );
}

=head2 closest_three_points
Expand Down
16 changes: 11 additions & 5 deletions lib/Math/Function/Interpolator/Cubic.pm
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ use 5.006;
use strict;
use warnings FATAL => 'all';

our $VERSION = '0.03';
our $VERSION = '0.04';

use parent 'Math::Function::Interpolator';
our @ISA = qw(Math::Function::Interpolator);

use Carp qw(confess);
use List::MoreUtils qw(pairwise indexes);
Expand Down Expand Up @@ -41,13 +41,17 @@ HashRef of points for interpolations
=cut

sub _sorted_Xs {
my ($self) = @_;
return [ sort { $a <=> $b } keys %{ $self->points } ];
my ( $self ) = @_;
return $self->{'_sorted_Xs'} if $self->{'_sorted_Xs'};
$self->{'_sorted_Xs'} = [ sort { $a <=> $b } keys %{ $self->points } ];
return $self->{'_sorted_Xs'};
}

sub _spline_points {
my ($self) = @_;

return $self->{'_spline_points'} if $self->{'_spline_points'};

my $points_ref = $self->points;
my $Xs = $self->_sorted_Xs;
my @Ys = map { $points_ref->{$_} } @$Xs;
Expand Down Expand Up @@ -81,7 +85,9 @@ sub _spline_points {

my %y_2derivative_combined = pairwise { $a => $b } @$Xs, @y_2derivative;

return \%y_2derivative_combined;
$self->{'_spline_points'} = \%y_2derivative_combined;

return $self->{'_spline_points'};
}

sub _extrapolate_spline {
Expand Down
4 changes: 2 additions & 2 deletions lib/Math/Function/Interpolator/Linear.pm
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ use 5.006;
use strict;
use warnings FATAL => 'all';

use parent 'Math::Function::Interpolator';
our @ISA = qw(Math::Function::Interpolator);

our $VERSION = '0.03';
our $VERSION = '0.04';

use Carp qw(confess);
use Number::Closest::XS qw(find_closest_numbers_around);
Expand Down
9 changes: 4 additions & 5 deletions lib/Math/Function/Interpolator/Quadratic.pm
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,13 @@ use 5.006;
use strict;
use warnings FATAL => 'all';

our $VERSION = '0.04';
our $VERSION = '0.05';

use parent 'Math::Function::Interpolator';
our @ISA = qw(Math::Function::Interpolator);

use Carp qw(confess);
use Math::Cephes::Matrix qw(mat);
use Scalar::Util qw(looks_like_number);
use Try::Tiny;

=head1 NAME

Expand Down Expand Up @@ -66,8 +65,8 @@ sub quadratic {
my $y = [ map { $ap->{$_} } @points ];

my $solution;
try { $solution = $abc->simq($y) }
catch { confess 'Insoluble matrix: ' . $_; };
eval { $solution = $abc->simq($y) };
confess 'Insoluble matrix: ' . $_ if $@;
my ( $a, $b, $c ) = @$solution;

return ( $a * ( $x**2 ) + $b * $x + $c );
Expand Down