PiecewiseLinearFunction

Struct PiecewiseLinearFunction 

Source
pub struct PiecewiseLinearFunction { /* private fields */ }
Expand description

A piecewise linear function defined by a series of connected line segments.

The function is represented by a collection of points (x, y), where consecutive points are connected by straight lines. The points are automatically sorted by their x-coordinates for efficient evaluation.

§Behavior

  • Interpolation: For x-values between defined points, the function uses linear interpolation
  • Extrapolation: For x-values outside the defined range, the function returns the y-value of the nearest endpoint
  • Duplicate x-values: Adding a point with an existing x-coordinate overwrites the previous y-value

§Examples

use piecewise_linear_function::PiecewiseLinearFunction;

let mut function = PiecewiseLinearFunction::empty();
function.add_point(0.0, 0.0).unwrap();
function.add_point(1.0, 2.0).unwrap();
function.add_point(2.0, 1.0).unwrap();

// Evaluate at defined points
assert_eq!(function.get_value(0.0).unwrap(), 0.0);
assert_eq!(function.get_value(1.0).unwrap(), 2.0);

// Interpolation between points
assert_eq!(function.get_value(0.5).unwrap(), 1.0);
assert_eq!(function.get_value(1.5).unwrap(), 1.5);

// Extrapolation beyond range
assert_eq!(function.get_value(-1.0).unwrap(), 0.0);  // Returns first point's y
assert_eq!(function.get_value(3.0).unwrap(), 1.0);   // Returns last point's y

Implementations§

Source§

impl PiecewiseLinearFunction

Source

pub fn new(points: Vec<(f32, f32)>) -> Self

Creates a new piecewise linear function from a vector of points.

The points will be automatically sorted by their x-coordinates, and any duplicate x-coordinates will result in the last y-value being kept.

§Arguments
  • points - A vector of (x, y) coordinate pairs
§Examples
use piecewise_linear_function::PiecewiseLinearFunction;

// Points can be provided in any order
let points = vec![(2.0, 4.0), (0.0, 0.0), (1.0, 2.0)];
let function = PiecewiseLinearFunction::new(points);

assert_eq!(function.len(), 3);
assert_eq!(function.get_value(0.5).unwrap(), 1.0);
Source

pub fn empty() -> Self

Creates an empty piecewise linear function with no points.

Points can be added later using add_point.

§Examples
use piecewise_linear_function::PiecewiseLinearFunction;

let mut function = PiecewiseLinearFunction::empty();
assert!(function.is_empty());

function.add_point(1.0, 1.0).unwrap();
assert!(!function.is_empty());
Source

pub fn add_point(&mut self, x: f32, y: f32) -> Result<(), PiecewiseError>

Adds a point to the function.

The point will be inserted in the correct position to maintain sorted order by x-coordinate. If a point with the same x-coordinate already exists, its y-value will be updated.

§Arguments
  • x - The x-coordinate of the point (must be finite)
  • y - The y-coordinate of the point (must be finite)
§Errors

Returns PiecewiseError::InvalidPoint if either coordinate is NaN or infinite.

§Examples
use piecewise_linear_function::PiecewiseLinearFunction;

let mut function = PiecewiseLinearFunction::empty();

// Add points in any order
function.add_point(2.0, 4.0).unwrap();
function.add_point(0.0, 0.0).unwrap();
function.add_point(1.0, 2.0).unwrap();

// Update existing point
function.add_point(1.0, 3.0).unwrap();
assert_eq!(function.get_value(1.0).unwrap(), 3.0);

// Invalid coordinates are rejected
assert!(function.add_point(f32::NAN, 1.0).is_err());
assert!(function.add_point(1.0, f32::INFINITY).is_err());
Source

pub fn len(&self) -> usize

Returns the number of points in the function.

§Examples
use piecewise_linear_function::PiecewiseLinearFunction;

let function = PiecewiseLinearFunction::new(vec![(0.0, 1.0), (1.0, 2.0)]);
assert_eq!(function.len(), 2);
Source

pub fn is_empty(&self) -> bool

Returns true if the function contains no points.

§Examples
use piecewise_linear_function::PiecewiseLinearFunction;

let empty_function = PiecewiseLinearFunction::empty();
assert!(empty_function.is_empty());

let function = PiecewiseLinearFunction::new(vec![(0.0, 1.0)]);
assert!(!function.is_empty());
Source

pub fn range(&self) -> Option<(f32, f32)>

Returns the range of y-values in the function.

This returns the minimum and maximum y-values among all defined points. Note that interpolated values between points might fall outside this range.

§Returns
  • Some((min_y, max_y)) if the function has points
  • None if the function is empty
§Examples
use piecewise_linear_function::PiecewiseLinearFunction;

let function = PiecewiseLinearFunction::new(vec![
    (0.0, 1.0),
    (1.0, 5.0),
    (2.0, 2.0)
]);

assert_eq!(function.range(), Some((1.0, 5.0)));

let empty_function = PiecewiseLinearFunction::empty();
assert_eq!(empty_function.range(), None);
Source

pub fn get_value_or_default(&self, x: f32) -> f32

Evaluates the function at the given x-coordinate, returning 0.0 for empty functions.

This is a convenience method that returns a default value instead of an error when the function is empty.

§Arguments
  • x - The x-coordinate to evaluate
§Returns

The function value at x, or 0.0 if the function is empty or x is invalid.

§Examples
use piecewise_linear_function::PiecewiseLinearFunction;

let function = PiecewiseLinearFunction::new(vec![(0.0, 1.0), (1.0, 2.0)]);
assert_eq!(function.get_value_or_default(0.5), 1.5);

let empty_function = PiecewiseLinearFunction::empty();
assert_eq!(empty_function.get_value_or_default(0.5), 0.0);
Source

pub fn get_value(&self, x: f32) -> Result<f32, PiecewiseError>

Evaluates the function at the given x-coordinate.

The function uses linear interpolation between defined points. For x-values outside the defined range, it returns the y-value of the nearest endpoint.

§Arguments
  • x - The x-coordinate to evaluate (must be finite)
§Returns
  • Ok(y) - The function value at x
  • Err(PiecewiseError::EmptyFunction) - If the function has no points
  • Err(PiecewiseError::InvalidPoint) - If x is NaN or infinite
§Examples
use piecewise_linear_function::PiecewiseLinearFunction;

let function = PiecewiseLinearFunction::new(vec![
    (0.0, 0.0),
    (2.0, 4.0),
    (4.0, 2.0)
]);

// Exact matches
assert_eq!(function.get_value(0.0).unwrap(), 0.0);
assert_eq!(function.get_value(2.0).unwrap(), 4.0);

// Linear interpolation
assert_eq!(function.get_value(1.0).unwrap(), 2.0);
assert_eq!(function.get_value(3.0).unwrap(), 3.0);

// Extrapolation (returns nearest endpoint)
assert_eq!(function.get_value(-1.0).unwrap(), 0.0);
assert_eq!(function.get_value(5.0).unwrap(), 2.0);

// Error cases
let empty = PiecewiseLinearFunction::empty();
assert!(empty.get_value(1.0).is_err());
assert!(function.get_value(f32::NAN).is_err());

Trait Implementations§

Source§

impl Debug for PiecewiseLinearFunction

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for PiecewiseLinearFunction

Source§

fn default() -> Self

Creates an empty piecewise linear function.

This is equivalent to calling PiecewiseLinearFunction::empty().

Source§

impl FromIterator<(f32, f32)> for PiecewiseLinearFunction

Source§

fn from_iter<T: IntoIterator<Item = (f32, f32)>>(iter: T) -> Self

Creates a piecewise linear function from an iterator of points.

§Examples
use piecewise_linear_function::PiecewiseLinearFunction;

let points = vec![(0.0, 1.0), (1.0, 2.0), (2.0, 1.5)];
let function: PiecewiseLinearFunction = points.into_iter().collect();

assert_eq!(function.len(), 3);
assert_eq!(function.get_value(0.5).unwrap(), 1.5);

Auto Trait Implementations§

Blanket Implementations§

§

impl<T> Any for T
where T: 'static + ?Sized,

§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<T> Borrow<T> for T
where T: ?Sized,

§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
§

impl<T> BorrowMut<T> for T
where T: ?Sized,

§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<T> From<T> for T

§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T, U> Into<U> for T
where U: From<T>,

§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.