interpolators.lib
A library to handle interpolation. Its official prefix is it
.
This library provides several basic interpolation functions as well as interpolators taking a 'gen' circuit of N outputs producing values to be interpolated, triggered by a 'idv' read index signal. Two points and four points interpolation is implemented.
The 'idv' parameter is to be used as a read index. In float (= singleprecision) mode, we use a technique with a pure integer index and a fractional part in the [0,1] range to avoid accumulating errors. In -double (= doubleprecision)/-quad (= quadprecision) modes, we use a standard implementation with a fractional index.
Use-case with waveform
. Here the signal given to interpolator_XXX
uses the idv
model.
waveform_interpolator(wf, step, interp) = interp(gen, idv)
with {
gen(idx) = wf, (idx:max(0):min(size-1)) : rdtable with { size = wf:(_,!); }; /* waveform size */
index = (+(step)~_)-step; /* starting from 0 */
idv = it.make_idv(index); /* build the signal for interpolation in a generic way */
};
waveform_linear(wf, step) = waveform_interpolator(wf, step, it.interpolator_linear);
waveform_cosine(wf, step) = waveform_interpolator(wf, step, it.interpolator_cosine);
waveform_cubic(wf, step) = waveform_interpolator(wf, step, it.interpolator_cubic);
waveform_interp(wf, step, selector) = waveform_interpolator(wf, step, interp_select(selector))
with {
/* adapts the argument order */
interp_select(sel, gen, idv) = it.interpolator_select(gen, idv, sel);
};
waveform and index
waveform_interpolator1(wf, idv, interp) = interp(gen, idv)
with {
gen(idx) = wf, (idx:max(0):min(size-1)) : rdtable with { size = wf:(_,!); }; /* waveform size */
};
waveform_linear1(wf, idv) = waveform_interpolator1(wf, idv, it.interpolator_linear);
waveform_cosine1(wf, idv) = waveform_interpolator1(wf, idv, it.interpolator_cosine);
waveform_cubic1(wf, idv) = waveform_interpolator1(wf, idv, it.interpolator_cubic);
waveform_interp1(wf, idv, selector) = waveform_interpolator1(wf, idv, interp_select(selector))
with {
/* adapts the argument order */
interp_select(sel, gen, idv) = it.interpolator_select(gen, idv, sel);
};
Tests:
wf = waveform {0.0, 10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 50.0, 40.0, 30.0, 20.0, 10.0, 0.0};
process = waveform_linear(wf, step), waveform_cosine(wf, step), waveform_cubic(wf, step) with { step = 0.25; };
process = waveform_interp(wf, 0.25, nentry("algo", 0, 0, 3, 1));
process = waveform_interp1(wf, idv, nentry("algo", 0, 0, 3, 1))
with {
step = 0.1;
idv_aux = (+(step)~_)-step; /* starting from 0 */
idv = it.make_idv(idv_aux); /* build the signal for interpolation in a generic way */
};
Test linear interpolation between 2 samples with a '(idx,dv)' signal built using a waveform
linear_test = (idx,dv), it.interpolator_linear(gen, (idx,dv))
with {
/* signal to interpolate (only 2 points here) */
gen(id) = waveform {3.0, -1.0}, (id:max(0)) : rdtable;
dv = waveform {0.0, 0.25, 0.50, 0.75, 1.0}, index : rdtable;
idx = 0;
/* test index signal */
index = (+(1)~_)-1; /* starting from 0 */
};
Test cosine interpolation between 2 samples with a '(idx,dv)' signal built using a waveform
cosine_test = (idx,dv), it.interpolator_cosine(gen, (idx,dv))
with {
/* signal to interpolate (only 2 points here) */
gen(id) = waveform {3.0, -1.0}, (id:max(0)) : rdtable;
dv = waveform {0.0, 0.25, 0.50, 0.75, 1.0}, index : rdtable;
idx = 0;
/* test index signal */
index = (+(1)~_)-1; /* starting from 0 */
};
Test cubic interpolation between 4 samples with a '(idx,dv)' signal built using a waveform
cubic_test = (idx,dv), it.interpolator_cubic(gen, (idx,dv))
with {
/* signal to interpolate (only 4 points here) */
gen(id) = waveform {-1.0, 2.0, 1.0, 4.0}, (id:max(0)) : rdtable;
dv = waveform {0.0, 0.25, 0.50, 0.75, 1.0}, index : rdtable;
idx = 0;
/* test index signal */
index = (+(1)~_)-1; /* starting from 0 */
};
Two points interpolation functions
(it.)interpolate_linear
Linear interpolation between 2 values.
Usage
interpolate_linear(dv,v0,v1) : _
Where:
dv
: in the fractional value in [0..1] rangev0
: is the first valuev1
: is the second value
Reference:
(it.)interpolate_cosine
Cosine interpolation between 2 values.
Usage
interpolate_cosine(dv,v0,v1) : _
Where:
dv
: in the fractional value in [0..1] rangev0
: is the first valuev1
: is the second value
Reference:
Four points interpolation functions
(it.)interpolate_cubic
Cubic interpolation between 4 values.
Usage
interpolate_cubic(dv,v0,v1,v2,v3) : _
Where:
dv
: in the fractional value in [0..1] rangev0
: is the first valuev1
: is the second valuev2
: is the third valuev3
: is the fourth value
Reference:
Two points interpolators
(it.)interpolator_two_points
Generic interpolator on two points (current and next index), assuming an increasing index.
Usage
interpolator_two_points(gen, idv, interpolate_two_points) : _,_... (equal to N = outputs(gen))
Where:
gen
: a circuit with an 'idv' reader input that produces N outputsidv
: a fractional read index expressed as a float value, or a (int,frac) pairinterpolate_two_points
: a two points interpolation function
(it.)interpolator_linear
Linear interpolator for a 'gen' circuit triggered by an 'idv' input to generate values.
Usage
interpolator_linear(gen, idv) : _,_... (equal to N = outputs(gen))
Where:
gen
: a circuit with an 'idv' reader input that produces N outputsidv
: a fractional read index expressed as a float value, or a (int,frac) pair
(it.)interpolator_cosine
Cosine interpolator for a 'gen' circuit triggered by an 'idv' input to generate values.
Usage
interpolator_cosine(gen, idv) : _,_... (equal to N = outputs(gen))
Where:
gen
: a circuit with an 'idv' reader input that produces N outputsidv
: a fractional read index expressed as a float value, or a (int,frac) pair
Four points interpolators
(it.)interpolator_two_points
Generic interpolator on interpolator_four_points points (previous, current and two next indexes), assuming an increasing index.
Usage
interpolator_four_points(gen, idv, interpolate_four_points) : _,_... (equal to N = outputs(gen))
Where:
gen
: a circuit with an 'idv' reader input that produces N outputsidv
: a fractional read index expressed as a float value, or a (int,frac) pairinterpolate_four_points
: a four points interpolation function
(it.)interpolator_cubic
Cubic interpolator for a 'gen' circuit triggered by an 'idv' input to generate values
Usage
interpolator_cubic(gen, idv) : _,_... (equal to N = outputs(gen))
Where:
gen
: a circuit with an 'idv' reader input that produces N outputsidv
: a fractional read index expressed as a float value, or a (int,frac) pair
(it.)interpolator_select
Generic configurable interpolator (with selector between in [0..3]). The value 3 is used for no interpolation.
Usage
interpolator_select(gen, idv, sel) : _,_... (equal to N = outputs(gen))
Where:
gen
: a circuit with an 'idv' reader input that produces N outputsidv
: a fractional read index expressed as a float value, or a (int,frac) pairsel
: an interpolation algorithm selector in [0..3] (0 = linear, 1 = cosine, 2 = cubic, 3 = nointerp)