differential_equations/
traits.rs1use nalgebra::{RealField, SMatrix};
4use num_complex::Complex;
5use std::ops::{Add, AddAssign, Div, Mul, Sub};
6
7pub 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
42pub trait State<T>:
54 Clone
55 + Copy
56 + Add<Output = Self>
57 + Sub<Output = Self>
58 + AddAssign
59 + Mul<T, Output = Self>
60 + Div<T, Output = Self>
61{
62 fn len(&self) -> usize;
63
64 fn get(&self, i: usize) -> T;
65
66 fn set(&mut self, i: usize, value: T);
67
68 fn zeros() -> Self;
69}
70
71impl<T: Real> State<T> for T {
72 fn len(&self) -> usize {
73 1
74 }
75
76 fn get(&self, i: usize) -> T {
77 if i == 0 {
78 *self
79 } else {
80 panic!("Index out of bounds")
81 }
82 }
83
84 fn set(&mut self, i: usize, value: T) {
85 if i == 0 {
86 *self = value;
87 } else {
88 panic!("Index out of bounds")
89 }
90 }
91
92 fn zeros() -> Self {
93 T::zero()
94 }
95}
96
97impl<T, const R: usize, const C: usize> State<T> for SMatrix<T, R, C>
98where
99 T: Real,
100{
101 fn len(&self) -> usize {
102 R * C
103 }
104
105 fn get(&self, i: usize) -> T {
106 if i < self.len() {
107 self[(i / C, i % C)]
108 } else {
109 panic!("Index out of bounds")
110 }
111 }
112
113 fn set(&mut self, i: usize, value: T) {
114 if i < self.len() {
115 self[(i / C, i % C)] = value;
116 } else {
117 panic!("Index out of bounds")
118 }
119 }
120
121 fn zeros() -> Self {
122 SMatrix::<T, R, C>::zeros()
123 }
124}
125
126impl<T> State<T> for Complex<T>
127where
128 T: Real,
129{
130 fn len(&self) -> usize {
131 2
132 }
133
134 fn get(&self, i: usize) -> T {
135 if i == 0 {
136 self.re
137 } else if i == 1 {
138 self.im
139 } else {
140 panic!("Index out of bounds")
141 }
142 }
143
144 fn set(&mut self, i: usize, value: T) {
145 if i == 0 {
146 self.re = value;
147 } else if i == 1 {
148 self.im = value;
149 } else {
150 panic!("Index out of bounds")
151 }
152 }
153
154 fn zeros() -> Self {
155 Complex::new(T::zero(), T::zero())
156 }
157}
158
159pub trait CallBackData: Clone + std::fmt::Debug {}
169
170impl<T: Clone + std::fmt::Debug> CallBackData for T {}