NAME
Math::InterpolationCompiler - Compile interpolations into perl coderefs
VERSION
version 0.001000
SYNOPSIS
my $fn= Math::InterpolationCompiler->new(
domain => [ 1, 2, 3, 4, 5 ],
range => [ 1.9, 1.3, 1.2, 1.1, 1.05 ],
algorithm => 'linear',
beyond_domain => 'die',
)->fn;
print $fn->(3); # 1.2
print $fn->(3.5); # 1.15
print $fn->(9); # throws exception
DESCRIPTION
This module is much the same theme as Math::Interpolate and Math::Interpolator::Linear but it compiles the interpolations into actual Perl code, and pre-calculates all the numbers so that the end result is Log2(N) comparisons and a multiply and an add, all done at the interpreter level. This makes it very fast for repeated calls.
Use this module if you have a few smallish data plots which you want to evaluate very quickly over and over again.
DO NOT use this module if you have an extremely large data array that changes frequently, if your data points are not plain scalars, or if you are extremely worried about code-injection attacks. (this module sanitizes the numbers you give it, but it is still generating perl code and in security-critical environments with un-trusted input your best bet is to just avoid all string evals).
This generator is written as a Perl object which produces a coderef. This makes the generator easy to extend and re-use pieces for various goals. However the OO design is somewhat unnecessary, and really just a convenient implementation thanks to Moo. In other words, the object doesn't have much use other than performing a one-time job.
ATTRIBUTES
domain
The input values ('x') of the function. Domain must be sorted in non-decreasing order.
range
The output values ('y') of the function.
algorithm
The name of the algorithm to create:
- linear
-
Create a linear interpolation, where an input ('x') is matched to the interval containing that value, and the return value is
y = x * (y_next - y_prev) / (x_next - x_prev)
If a zero-width segment is encountered (a discontinuity in the line) the 'x' values less than the discontinuity use the left-hand segment, and the 'x' values equal to or to the right of the discontinuity use the right-hand segment.
Example:
# domain => [ 1, 2, 2, 3 ], # range => [ 0, 0, 1, 2 ], $fn->(1); # equals 0 $fn->(1.9); # equals 0 $fn->(2); # equals 1 #fn->(3); # equals 2
When beyond_domain is 'extrapolate' and a discontinuity occurs at the end of the domain, the interval beyond the domain gets a slope of 0.
Example: # points => [[0,0], [0,1]] # beyond_domain => 'extrapolate' $fn->(x) # equals 0 for x < 0 and 1 for x >= 0
beyond_domain
The behavior of the generated function when an input value ('x') lies outside the domain of the function.
- clamp
-
Constrain 'x' to the valid domain of the function.
- extrapolate
-
Extrapolate the curve at the nearest edge of the domain. Details of the extrapolation depend on the 'algorithm' being used.
- undef
-
Return undef for any 'x' outside the domain of the function.
- die
-
Die with an error for any 'x' outside of the domain of the function.
perl_code
Lazy-build the perl code for this function using the other attributes. Returns a string of perl code.
fn
Lazy-build the perl coderef for the perl_code attribute.
sanitize
Boolean. Whether or not to sanitize the domain and range with a 'number' regex during the constructor. Defaults to true.
Setting this to false leaves you open to code injection attacks, but you might choose to do that if you trust your input and you need a little performance boost on constructing this object.
METHODS
new
Standard object constructor accepting any of the above attributes, but also accepting:
- points
-
->new( points => [ [1,1], [2,2], [3,2], ... ] );
For convenience, you can specify your domain and range as an arrayref of (x,y) pairs. During BUILDARGS, this will get separated into the domain and range attributes.
AUTHOR
Michael Conrad <mike@nrdvana.net>
COPYRIGHT AND LICENSE
This software is copyright (c) 2015 by Michael Conrad.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.