Do you have a feel for what result you expect for your example? Does 0.75515 sound right?
This won't win any awards for speed, but it might serve as a starting point for something quicker (assuming it is correct):
#! perl -slw
use strict;
use Data::Dump qw[ pp ];
sub cubicInterpolate {
my $x = shift;
return $_[1] + 0.5 * $x*( $_[2] - $_[0] + $x*( 2*$_[0] - 5*$_[1] +
+ 4*$_[2] - $_[3] + $x*( 3*( $_[1]-$_[2] ) + $_[3] - $_[0] ) ) );
}
sub bicubicInterpolate {
my( $x, $y, $aref ) = @_;
return cubicInterpolate( $x, map cubicInterpolate( $y, @{ $aref->[
+ $_] } ), 0 .. $#$aref );
}
sub readTable {
my $fh = shift;
my @table;
my @xs = split ' ', <DATA>;
my( @ys, @vals );
while( <$fh> ) {
my( $y, @vals ) = split;
@{ $table[ $y ] }[ @xs ] = @vals;
}
return \@table;
}
sub get4x4 {
my( $x, $y, $table ) = @_;
my @m;
$x = int( $x );
$y = int( $y );
for my $yi ( $y-1 .. $y+2 ) {
my $yt = $yi < 0 ? 0 : $yi > $#{ $table } ? $#{ $table } : $yi
+;
push @m, [];
for my $xi ( $x-1 .. $x+2 ) {
my $xt = $xi < 0 ? 0 : $xi > $#{ $table->[ $yt ] } ? $#{ $
+table->[ $yt ] } : $xi;
push @{ $m[ $#m ] }, $table->[ $yt ][ $xt ];
}
}
return \@m;
}
my $table = readTable( *DATA ); pp $table;
my $m4x4 = get4x4( 2.5, 5.8, $table ); pp $m4x4;
my $interpolated = bicubicInterpolate( 0.5, 0.8, $m4x4 );
print $interpolated;
__DATA__
1 2 3
4 0.1 0.2 0.3
5 0.4 0.5 0.6
6 0.7 0.8 0.9
Output:
C:\test>1162861.pl
[
undef,
undef,
undef,
undef,
[undef, 0.1, 0.2, 0.3],
[undef, 0.4, 0.5, 0.6],
[undef, 0.7, 0.8, 0.9],
]
[
[0.1, 0.2, 0.3, 0.3],
[0.4, 0.5, 0.6, 0.6],
[0.7, 0.8, 0.9, 0.9],
[0.7, 0.8, 0.9, 0.9],
]
0.75515
It's based upon this;
With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
In the absence of evidence, opinion is indistinguishable from prejudice.