Skip to main content

differential_equations/
tolerance.rs

1//! Tolerance enum for adaptive step size control
2
3use crate::traits::Real;
4
5use std::{
6    convert::From,
7    ops::{Index, IndexMut},
8};
9
10#[derive(Clone)]
11pub enum Tolerance<T: Real> {
12    Scalar(T),
13    Vector(Vec<T>),
14}
15
16impl<T: Real> Tolerance<T> {
17    /// Average Tolerance
18    pub fn average(&self) -> T {
19        match self {
20            Tolerance::Scalar(val) => *val,
21            Tolerance::Vector(vec) => {
22                let mut sum = T::zero();
23                for i in vec {
24                    sum += *i;
25                }
26                sum / T::from_usize(vec.len()).unwrap()
27            }
28        }
29    }
30}
31
32impl<T: Real> Index<usize> for Tolerance<T> {
33    type Output = T;
34
35    fn index(&self, i: usize) -> &T {
36        match self {
37            Tolerance::Scalar(val) => val,
38            Tolerance::Vector(vec) => &vec[i],
39        }
40    }
41}
42
43impl<T: Real> IndexMut<usize> for Tolerance<T> {
44    fn index_mut(&mut self, i: usize) -> &mut T {
45        match self {
46            Tolerance::Scalar(val) => val,
47            Tolerance::Vector(vec) => &mut vec[i],
48        }
49    }
50}
51
52impl<T: Real> From<T> for Tolerance<T> {
53    fn from(v: T) -> Self {
54        Tolerance::Scalar(v)
55    }
56}
57
58impl<T: Real> From<Vec<T>> for Tolerance<T> {
59    fn from(v: Vec<T>) -> Self {
60        Tolerance::Vector(v)
61    }
62}
63
64impl<const N: usize, T: Real> From<[T; N]> for Tolerance<T> {
65    fn from(v: [T; N]) -> Self {
66        Tolerance::Vector(v.to_vec())
67    }
68}