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