differential_equations/
traits.rs

1//! Defines Generics for the library. Includes generics for the floating point numbers.
2
3use std::ops::{Add, AddAssign, Div, Mul, Sub};
4use nalgebra::{SMatrix, RealField};
5use num_complex::Complex;
6
7/// Real Number Trait
8///
9/// This trait specifies the acceptable types for real numbers.
10/// Currently implemented for:
11/// * `f32` - 32-bit floating point
12/// * `f64` - 64-bit floating point
13///
14/// Provides additional functionality required for ODE solvers beyond
15/// what's provided by nalgebra's RealField trait.
16///
17pub trait Real: Copy + RealField {
18    fn infinity() -> Self;
19    fn to_f64(self) -> f64;
20}
21
22impl Real for f32 {
23    fn infinity() -> Self {
24        std::f32::INFINITY
25    }
26
27    fn to_f64(self) -> f64 {
28        f64::from(self)
29    }
30}
31
32impl Real for f64 {
33    fn infinity() -> Self {
34        std::f64::INFINITY
35    }
36
37    fn to_f64(self) -> f64 {
38        self
39    }
40}
41
42/// State vector trait
43pub trait State<T>:
44    Clone +
45    Copy +
46    Add<Output = Self> +
47    Sub<Output = Self> +
48    AddAssign +
49    Mul<T, Output = Self> +
50    Div<T, Output = Self> +
51{
52    fn len(&self) -> usize;
53
54    fn get(&self, i: usize) -> T; 
55
56    fn zeros() -> Self;
57}
58
59impl<T: Real> State<T> for T
60{
61    fn len(&self) -> usize {
62        1
63    }
64
65    fn get(&self, i: usize) -> T {
66        if i == 0 {
67            *self
68        } else {
69            panic!("Index out of bounds")
70        }
71    }
72
73    fn zeros() -> Self {
74        T::zero()
75    }
76}
77
78impl<T, const R: usize, const C: usize> State<T> for SMatrix<T, R, C>
79where
80    T: Real,
81{
82    fn len(&self) -> usize {
83        R * C
84    }
85
86    fn get(&self, i: usize) -> T {
87        if i < self.len() {
88            self[(i / C, i % C)]
89        } else {
90            panic!("Index out of bounds")
91        }
92    }
93
94    fn zeros() -> Self {
95        SMatrix::<T, R, C>::zeros()
96    }
97}
98
99impl<T> State<T> for Complex<T>
100where
101    T: Real,
102{
103    fn len(&self) -> usize {
104        2
105    }
106
107    fn get(&self, i: usize) -> T {
108        if i == 0 {
109            self.re
110        } else if i == 1 {
111            self.im
112        } else {
113            panic!("Index out of bounds")
114        }
115    }
116
117    fn zeros() -> Self {
118        Complex::new(T::zero(), T::zero())
119    }
120}
121
122/// Callback data trait
123///
124/// This trait represents data that can be returned from functions
125/// that are used to control the solver's execution flow. The
126/// Clone and Debug traits are required for internal use but anything
127/// that implements this trait can be used as callback data.
128/// For example, this can be a string, a number, or any other type
129/// that implements the Clone and Debug traits.
130///
131pub trait CallBackData: Clone + std::fmt::Debug {}
132
133// Implement for any type that already satisfies the bounds
134impl<T: Clone + std::fmt::Debug> CallBackData for T {}