optionstratlib_math/geometrics/interpolation/linear.rs
1use crate::error::InterpolationError;
2
3/// A trait that provides functionality for performing linear interpolation.
4///
5/// # Overview
6/// The `LinearInterpolation` trait defines the behavior for linearly interpolating
7/// values along a curve or dataset. It allows implementors to compute the interpolated
8/// point for a given input using linear methods.
9///
10/// Linear interpolation is a simple and widely-used technique in which new data points
11/// can be estimated within the range of a discrete set of known data points by connecting
12/// adjacent points with straight lines.
13///
14/// # Associated Types
15///
16/// - **`Point`**: Represents the type of the interpolated data point (e.g., coordinates,
17/// numerical values, or other types).
18/// - **`Input`**: Represents the type of the input value used to calculate the interpolation (e.g., a single
19/// number such as an `f64` or a high-precision number like `Decimal`).
20/// - **`Error`**: Defines the error type returned if interpolation cannot be performed due to invalid input
21/// or other constraints (e.g., insufficient points for interpolation).
22///
23/// # Required Method
24///
25/// ## `linear_interpolate`
26///
27/// This method calculates the interpolated value for a given input.
28///
29/// - **Input:**
30/// Requires a value of type `Input` (e.g., a numerical value or coordinate) for which
31/// the corresponding interpolated `Point` should be calculated.
32///
33/// - **Returns:**
34/// - On success, returns a `Result` containing the interpolated value of type `Point`.
35/// - On failure, returns a `Result` containing an error of type `Self::Error` that describes
36/// the reason for failure (e.g., invalid input or insufficient data points).
37///
38/// # Typical Usage
39/// This trait is abstract and should be implemented for data structures representing curves
40/// or data sets where linear interpolation is required. Examples include interpolating
41/// between points on a 2D curve, estimating values in a time series, or refining graphical
42/// data.
43///
44/// # Example Use Case (General)
45/// This trait can be used to:
46/// - Estimate missing values in a dataset.
47/// - Provide smooth transitions between adjacent points on a graph.
48/// - Implement real-time interpolations for dynamic systems, such as animations or simulations.
49///
50/// # Notes on Implementation
51/// - Implementors of this trait must ensure that the interpolation logic respects the
52/// shape and constraints of the data being used. This involves:
53/// - Validating input values.
54/// - Handling boundary conditions (e.g., extrapolation or edge points).
55///
56/// - High precision or custom input/output types (e.g., `Decimal`) can be used when necessary
57/// to avoid issues related to floating-point errors in sensitive calculations.
58///
59/// # Example Implementation Outline
60/// 1. Access two known points adjacent to the input value.
61/// 2. Compute the slope and intercept of the line between the two points.
62/// 3. Evaluate the equation of the line at the given input to determine the interpolated point.
63///
64/// # Errors
65/// When implementing this trait, common errors that may be returned include:
66/// - Insufficient data points for interpolation.
67/// - Out-of-bounds input values or indices.
68/// - Invalid data point structures or internal state errors.
69///
70/// # See Also
71/// - [`crate::geometrics::CubicInterpolation`]: An alternative interpolation method using cubic polynomials.
72/// - [`crate::geometrics::InterpolationType`]: Enum representing supported interpolation methods in the library.
73///
74/// The `LinearInterpolation` trait is part of a modular design and is often re-exported
75/// in higher-level library components for ease of use.
76///
77/// # One point per abscissa
78///
79/// Every interpolator here reads its sample as a function of the abscissa:
80/// at most one ordinate per `x`. See
81/// [`Curve::new`](crate::curves::Curve::new) for the rule and for why no
82/// constructor enforces it. A sample carrying several ordinates at one
83/// abscissa is outside the contract, and the answer is
84/// [`InterpolationError::DegenerateInterval`], never one of the stacked
85/// ordinates chosen silently: the bracket around a repeated abscissa has
86/// zero width and the slope across it is undefined. A projection of a
87/// surface is multi-valued by construction, which is why
88/// [`Surface::project_onto`](crate::surfaces::Surface::project_onto) returns a
89/// `Vec<Point2D>` and not a curve; aggregate it before interpolating.
90pub trait LinearInterpolation<Point, Input> {
91 /// Performs linear interpolation for a given input value.
92 ///
93 /// # Parameters
94 /// - `x`: The input value of type `Input` for which the interpolated point should be calculated.
95 ///
96 /// # Returns
97 /// - `Ok(Point)`: The calculated interpolated value of type `Point`.
98 /// - `Err(Self::Error)`: An error indicating the reason why interpolation failed.
99 ///
100 /// # Errors
101 ///
102 /// Returns [`InterpolationError::EmptyData`] when the sample is
103 /// empty, [`InterpolationError::OutOfRange`] when `x` falls
104 /// outside the sample domain, and
105 /// [`InterpolationError::DegenerateInterval`] when two
106 /// bracketing samples share the same `x` coordinate.
107 fn linear_interpolate(&self, x: Input) -> Result<Point, InterpolationError>;
108}