pub trait PolyTraits {
type Coeff;
type SparseInterpEval: EvalTypes<Coeff = Self::Coeff>;
type SparseInterpInfo;
// Required methods
fn slice_mul(
out: &mut [Self::Coeff],
lhs: &[Self::Coeff],
rhs: &[Self::Coeff],
);
fn sparse_interp_prep(
sparsity: usize,
expons: impl Iterator<Item = usize>,
max_coeff: &Self::Coeff,
) -> (<Self::SparseInterpEval as EvalTypes>::EvalInfo, Self::SparseInterpInfo);
fn sparse_interp_slice(
evals: &[<Self::SparseInterpEval as EvalTypes>::Eval],
info: &Self::SparseInterpInfo,
) -> Result<Vec<(usize, Self::Coeff)>>;
// Provided methods
fn mp_eval_prep<U>(
pts: impl Iterator<Item = U>,
) -> <EvalTrait<Self, U> as EvalTypes>::EvalInfo
where EvalTrait<Self, U>: EvalTypes<Coeff = Self::Coeff, Eval = U> { ... }
fn mp_eval_slice<U>(
out: &mut impl Extend<U>,
coeffs: &[Self::Coeff],
info: &<EvalTrait<Self, U> as EvalTypes>::EvalInfo,
) -> Result<()>
where EvalTrait<Self, U>: EvalTypes<Coeff = Self::Coeff, Eval = U> { ... }
}
Expand description
Algorithms to enable polynomial arithmetic.
Generally, PolyTraits
methods should not be used directly, but only
within the various method impls for Poly
.
This is implemented as a separate, possibly stateless traits object in order to allow selecting different underlying algorithms separately from the overall representation.
The methods here generally work on slice references so as to be representation-agnostic.
So far the only implementation is ClassicalTraits
.
Required Associated Types§
Sourcetype SparseInterpEval: EvalTypes<Coeff = Self::Coeff>
type SparseInterpEval: EvalTypes<Coeff = Self::Coeff>
The evaluation needed for sparse interpolation.
Sourcetype SparseInterpInfo
type SparseInterpInfo
An opaque type returned by the pre-processing method Self::sparse_interp_prep()
.
Required Methods§
Sourcefn slice_mul(out: &mut [Self::Coeff], lhs: &[Self::Coeff], rhs: &[Self::Coeff])
fn slice_mul(out: &mut [Self::Coeff], lhs: &[Self::Coeff], rhs: &[Self::Coeff])
Multiplies two polynomails (represented by slices) and stores the result in another slice.
Implementations may assume that all slices are non-empty, and that
out.len() == lhs.len() + rhs.len() - 1
.
let a = [1., 2., 3.];
let b = [4., 5.];
let mut c = [0.; 4];
TraitImpl::slice_mul(&mut c[..], &a[..], &b[..]);
assert_eq!(c, [1.*4., 1.*5. + 2.*4., 2.*5. + 3.*4., 3.*5.]);
Sourcefn sparse_interp_prep(
sparsity: usize,
expons: impl Iterator<Item = usize>,
max_coeff: &Self::Coeff,
) -> (<Self::SparseInterpEval as EvalTypes>::EvalInfo, Self::SparseInterpInfo)
fn sparse_interp_prep( sparsity: usize, expons: impl Iterator<Item = usize>, max_coeff: &Self::Coeff, ) -> (<Self::SparseInterpEval as EvalTypes>::EvalInfo, Self::SparseInterpInfo)
Pre-processing for sparse interpolation.
This method must be called prior to
calling Self::sparse_interp_slice()
.
A later call to sparse interpolation is guaranteed to succeed only when, for some
unknown polynomial f
, the following are all true:
f
has at mostsparsity
non-zero terms- The exponents of all non-zero terms of
f
appear inexpons
- The coefficients of
f
are bounded bymax_coeff
in magnitude.
The list expons
must be sorted in ascending order.
The same pre-processed output can be used repeatedly to interpolate possibly different polynomials under the same settings.
Sourcefn sparse_interp_slice(
evals: &[<Self::SparseInterpEval as EvalTypes>::Eval],
info: &Self::SparseInterpInfo,
) -> Result<Vec<(usize, Self::Coeff)>>
fn sparse_interp_slice( evals: &[<Self::SparseInterpEval as EvalTypes>::Eval], info: &Self::SparseInterpInfo, ) -> Result<Vec<(usize, Self::Coeff)>>
Sparse interpolation following evaluation.
The evaluations in eval
should correspond to what was specified by
Self::sparse_interp_prep()
.
If those requirements are met, the function will return Some(..) containing a list of exponent-coefficient pairs, sorted in ascending order of exponents.
Otherwise, for example if the evaluated function has more non-zero terms than the pre-specified limit, this function may return None or may return Some(..) with incorrect values.
Provided Methods§
Sourcefn mp_eval_prep<U>(
pts: impl Iterator<Item = U>,
) -> <EvalTrait<Self, U> as EvalTypes>::EvalInfo
fn mp_eval_prep<U>( pts: impl Iterator<Item = U>, ) -> <EvalTrait<Self, U> as EvalTypes>::EvalInfo
Pre-processing for multi-point evaluation.
This method must be called to specify the evaluation points prior to
calling Self::mp_eval_slice()
.
The same pre-processed output can be used repeatedly to evaluate possibly different polynomials at the same points.
The default implementation should be used; it relies on the EvalTypes::prep()
trait method specialized for the coefficient and evaluation types.
Sourcefn mp_eval_slice<U>(
out: &mut impl Extend<U>,
coeffs: &[Self::Coeff],
info: &<EvalTrait<Self, U> as EvalTypes>::EvalInfo,
) -> Result<()>
fn mp_eval_slice<U>( out: &mut impl Extend<U>, coeffs: &[Self::Coeff], info: &<EvalTrait<Self, U> as EvalTypes>::EvalInfo, ) -> Result<()>
Multi-point evaluation.
Evaluates the polynomial (given by a slice of coefficients) at all points
specified in a previous call to Self::mp_eval_prep()
.
let pts = [10., -5.];
let preprocess = TraitImpl::mp_eval_prep(pts.iter().copied());
let f = [1., 2., 3.];
let mut evals = Vec::new();
TraitImpl::mp_eval_slice(&mut evals, &f[..], &preprocess);
assert_eq!(evals, vec![321., 66.]);
let g = [4., 5., 6., 7.];
TraitImpl::mp_eval_slice(&mut evals, &g[..], &preprocess);
assert_eq!(evals, vec![321., 66., 7654., 4. - 5.*5. + 6.*25. - 7.*125.]);
The provided implementation should generally be used; it relies on the
EvalTypes::post()
trait method specialized for the coefficient and
evaluation types.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.