Crate polycal

Source
Expand description

polycal is a library for fitting, and using, polynomial calibration functions.

It’s goal is to offer a simple, application agnostic, interface allowing for easy integration into code bases in many fields.

The implementation follows the ISO/TS 28038 standard where possible.

To use the library, we first create a Problem using some known calibration data. Calibration data is composed of independent, or stimulus variables. These describe the inputs to the measurement model. For each stimulus there is an associated response, or dependent variable. A calibration problem can be constructed from known stimulus and response data. Currently the inputs must be provided as ndarray::ArrayView1.

use ndarray::Array1;
use polycal::ProblemBuilder;

let a = 1.;
let b = 2.;
let stimulus: Array1<f64> = Array1::range(0., 10., 0.5);
let num_data_points = stimulus.len();
let response: Array1<f64> = stimulus
    .iter()
    .map(|x| a + b * x)
    .collect();

let problem = ProblemBuilder::new(stimulus.view(), response.view())
    .unwrap()
    .build();

let maximum_degree = 5;

let best_fit = problem.solve(maximum_degree).unwrap();

for (expected, actual) in response.into_iter().zip(stimulus.into_iter().map(|x|
best_fit.certain_response(x).unwrap())).skip(1).take(num_data_points-2) {
    assert!((expected - actual).abs() < 1e-5);;
    }

We can account for uncertainties in the response variables at present. These can be attached to a ProblemBuilder as:

use ndarray::Array1;
use polycal::ProblemBuilder;

let a = 1.;
let b = 2.;
let stimulus: Array1<f64> = Array1::range(0., 10., 0.5);
let num_data_points = stimulus.len();
let response: Array1<f64> = stimulus
    .iter()
    .map(|x| a + b * x)
    .collect();
let dependent_uncertainty: Array1<f64> = response
    .iter()
    .map(|x| x / 1000.0)
    .collect();

let problem = ProblemBuilder::new(stimulus.view(), response.view())
    .unwrap()
    .with_dependent_variance(dependent_uncertainty.view())
    .unwrap()
    .build();

Note that all methods with panic if the provided stimulus, response and uncertainties contain unequal numbers of elements.

§Reconstruction

Given a Fit we can reconstruct unknown response from known stimulus values. This uses the calculated polynomial series directly.

use polycal::{AbsUncertainty, Uncertainty};
use ndarray::Array1;
use polycal::ProblemBuilder;

let a = 1.;
let b = 2.;
let stimulus: Array1<f64> = Array1::range(0., 10., 0.5);
let num_data_points = stimulus.len();
let response: Array1<f64> = stimulus
    .iter()
    .map(|x| a + b * x)
    .collect();
let dependent_uncertainty: Array1<f64> = response
    .iter()
    .map(|x| x / 1000.0)
    .collect();

let problem = ProblemBuilder::new(stimulus.view(), response.view())
    .unwrap()
    .with_dependent_variance(dependent_uncertainty.view())
    .unwrap()
    .build();

let maximum_degree = 5;
let best_fit = problem.solve(maximum_degree).unwrap();

let known_stimulus = AbsUncertainty::new(1.0, 0.01);
let estimated_response = best_fit.response(known_stimulus);

Alternatively we can calculate unknown stimulus values from known response values. This numerically minimises the residual of the fit. An initial guess and maximum iteration count can be provided.

use polycal::{AbsUncertainty, Uncertainty};
use ndarray::Array1;
use polycal::ProblemBuilder;

let a = 1.;
let b = 2.;
let stimulus: Array1<f64> = Array1::range(0., 10., 0.5);
let num_data_points = stimulus.len();
let response: Array1<f64> = stimulus
    .iter()
    .map(|x| a + b * x)
    .collect();
let dependent_uncertainty: Array1<f64> = response
    .iter()
    .map(|x| x / 1000.0)
    .collect();

let problem = ProblemBuilder::new(stimulus.view(), response.view())
    .unwrap()
    .with_dependent_variance(dependent_uncertainty.view())
    .unwrap()
    .build();

let maximum_degree = 5;
let best_fit = problem.solve(maximum_degree).unwrap();

let known_response = AbsUncertainty::new(1.0, 0.01);
let initial_guess = None;
let max_iter = Some(100);
let estimated_stimulus = best_fit.stimulus(
    known_response,
    initial_guess,
    max_iter
    );

Structs§

AbsUncertainty
An absolute uncertainty.
ChebyshevBuilder
Constraint
A constraint.
Fit
The results of a polynomial fit.
Problem
Problem abstraction
ProblemBuilder
Problem builder
RelUncertainty
A relative uncertainty.
Series
A Chebyshev c-series polynomial
Set
Marker struct to indicate a field has been previously set.
Unset
Marker struct to indicate a field remains unset

Enums§

PolyCalError
ScoringStrategy
Different scoring strategies for fit procedure

Traits§

ArgminAdd
Add a T to self
ArgminConj
Return the conjugate
ArgminDot
Dot/scalar product of T and self
ArgminFloat
An alias for float types (f32, f64) which combines multiple commonly needed traits from num_traits, std::fmt and for serialization/deserialization (the latter only if the serde1 feature is enabled). It is automatically implemented for all types which fulfill the trait bounds.
ArgminL2Norm
Compute the l2-norm (U) of self
ArgminMul
(Pointwise) Multiply a T with self
ArgminSub
Subtract a T from self
ArgminZeroLike
Zero for dynamically sized objects
PolynomialSeries
All the necessary methods for a polynomial series
Uncertainty
Used to define behaviour for values which have associated uncertainty.

Type Aliases§

PolyCalResult