-
Notifications
You must be signed in to change notification settings - Fork 690
Interpolation
breeze.interpolation
module currently supports interpolation facilities
for data in one dimension (univariate interpolation). At this moment, there
is only linear and cubic univariate interpolation available, but you are
encouraged to contribute to Breeze and write other interpolators like
quadratic, nearest and zero interpolators, as well as multivariate interpolation.
All examples in this document assumes that you've imported necessary modules:
scala> import breeze.interpolation._
1D (univariate) interpolators gets the coordinates of nodes. One vector for each coordinate is required:
scala> val x = DenseVector(0.0, 1.0, 2.0, 3.0)
scala> val y = DenseVector(2.0, 4.0, 8.0, 5.0)
scala> val f = LinearInterpolator(x, y)
The interpolator returns an interpolating function. You can ask for the value at given point:
scala> f(2.5)
6.5
If the coordinate is not in the interpolation range, the result will be extrapolated.
The function is an universal function, so you can also pass an vector or matrix or any other iterable object:
scala> f(DenseVector(1.0, 1.25, 1.5))
DenseVector(4.0, 5.0, 6.0)
There is also CubicInterpolator
implementing spline interpolation of third
order. It doesn't support extrapolation and throws an
OutOfTheBoundsException
if you pass an argument that is not in the
interpolation range.
There are two ways to write your own univariate interpolator. The simpler but
more rigid one is to extend the HandyUnivariateInterpolator
and pass it
vector of x and y coordinates. You need to implement only interpolate(x)
method where you can assume that the argument x
is in the interpolation
range (so it's between the minimum and maximum of x coordinates):
class MyInterpolator (x_coords: Vector[Double],
y_coords: Vector[Double])
extends HandyUnivariateInterpolator(x_coords, y_coords) {
override protected def interpolate(x: Double): Double = ...
}
HandyUnivariateInterpolator
validates x_coords
and y_coords
coordinates
and creates X
and Y
arrays sorted by X
coordinate. You can access this
members inside interpolate
method or anywhere inside the class.
You can also override extrapolate
method that is called when the argument is
not in the range. By default, this method raises an OutOfTheBoundsException
.
If you don't want to distinguish between interpolation and extrapolation, you
can override the public apply
method. The default implementation is:
def apply(x: T): T = {
if (x < X(0) || x > X(X.size - 1))
extrapolate(x)
else
interpolate(x)
}
The second way is more flexible. You only need to extend
UnivariateInterpolator
trait and implement apply(x)
method. You are on
your own to validate the x
argument.
class DummyInterpolator() extends UnivariateInterpolator {
def apply(x: Double): Double = 0
}
No matter which way you implement your interpolator, it's always an universal function and, therefore, it automatically plays well when you pass an vector or matrix instead of a plain double.
Breeze is a numerical processing library for Scala. http://www.scalanlp.org