1use crate::kernel::{Border, Interpolant, Kernel};
2use aeon_macros::{derivative, second_derivative};
3
4#[derive(Clone)]
6pub struct Unimplemented(pub usize);
7
8impl Kernel for Unimplemented {
9 fn border_width(&self) -> usize {
10 unimplemented!("Kernel is unimplemented for order {}", self.0)
11 }
12
13 fn interior(&self) -> &[f64] {
14 unimplemented!("Kernel is unimplemented for order {}", self.0)
15 }
16
17 fn free(&self, _border: Border) -> &[f64] {
18 unimplemented!("Kernel is unimplemented for order {}", self.0)
19 }
20
21 fn scale(&self, _spacing: f64) -> f64 {
22 unimplemented!("Kernel is unimplemented for order {}", self.0)
23 }
24}
25
26impl Interpolant for Unimplemented {
27 fn border_width(&self) -> usize {
28 unimplemented!("Kernel is unimplemented for order {}", self.0)
29 }
30
31 fn interior(&self) -> &[f64] {
32 unimplemented!("Kernel is unimplemented for order {}", self.0)
33 }
34
35 fn free(&self, _border: Border) -> &[f64] {
36 unimplemented!("Kernel is unimplemented for order {}", self.0)
37 }
38
39 fn scale(&self) -> f64 {
40 unimplemented!("Kernel is unimplemented for order {}", self.0)
41 }
42}
43
44#[derive(Clone)]
46pub struct Value;
47
48impl Kernel for Value {
49 fn border_width(&self) -> usize {
50 0
51 }
52
53 fn interior(&self) -> &[f64] {
54 &[1.0]
55 }
56
57 fn free(&self, _border: Border) -> &[f64] {
58 &[1.0]
59 }
60
61 fn scale(&self, _spacing: f64) -> f64 {
62 1.0
63 }
64}
65
66#[derive(Clone)]
68pub struct Derivative<const ORDER: usize>;
69
70impl<const ORDER: usize> Kernel for Derivative<ORDER> {
71 fn border_width(&self) -> usize {
72 ORDER / 2
73 }
74
75 fn interior(&self) -> &[f64] {
76 match ORDER {
77 2 => &derivative!(1, 1, 0),
78 4 => &derivative!(2, 2, 0),
79 6 => &derivative!(3, 3, 0),
80 _ => unimplemented!("Kernel is unimplemented for order {}", ORDER),
81 }
82 }
83
84 fn free(&self, border: Border) -> &[f64] {
85 match ORDER {
86 2 => match border {
87 Border::Negative(_) => &derivative!(0, 2, 0),
88 Border::Positive(_) => &derivative!(2, 0, 0),
89 },
90 4 => match border {
91 Border::Negative(0) => &derivative!(0, 4, 0),
92 Border::Negative(_) => &derivative!(0, 4, 1),
93 Border::Positive(0) => &derivative!(4, 0, 0),
94 Border::Positive(_) => &derivative!(4, 0, -1),
95 },
96 6 => match border {
97 Border::Negative(0) => &derivative!(0, 6, 0),
98 Border::Negative(1) => &derivative!(0, 6, 1),
99 Border::Negative(_) => &derivative!(0, 6, 2),
100 Border::Positive(0) => &derivative!(6, 0, 0),
101 Border::Positive(1) => &derivative!(6, 0, -1),
102 Border::Positive(_) => &derivative!(6, 0, -2),
103 },
104 _ => unimplemented!("Kernel is unimplemented for order {}", ORDER),
105 }
106 }
107
108 fn scale(&self, spacing: f64) -> f64 {
109 1.0 / spacing
110 }
111}
112
113#[derive(Clone)]
115pub struct SecondDerivative<const ORDER: usize>;
116
117impl<const ORDER: usize> Kernel for SecondDerivative<ORDER> {
118 fn border_width(&self) -> usize {
119 ORDER / 2
120 }
121
122 fn interior(&self) -> &[f64] {
123 match ORDER {
124 2 => &second_derivative!(1, 1, 0),
125 4 => &second_derivative!(2, 2, 0),
126 6 => &second_derivative!(3, 3, 0),
127 _ => unimplemented!("Kernel is unimplemented for order {}", ORDER),
128 }
129 }
130
131 fn free(&self, border: Border) -> &[f64] {
132 match ORDER {
133 2 => match border {
134 Border::Negative(_) => &second_derivative!(0, 3, 0),
135 Border::Positive(_) => &second_derivative!(3, 0, 0),
136 },
137 4 => match border {
138 Border::Negative(0) => &second_derivative!(0, 5, 0),
139 Border::Negative(_) => &second_derivative!(0, 5, 1),
140 Border::Positive(0) => &second_derivative!(5, 0, 0),
141 Border::Positive(_) => &second_derivative!(5, 0, -1),
142 },
143 6 => match border {
144 Border::Negative(0) => &second_derivative!(0, 7, 0),
145 Border::Negative(1) => &second_derivative!(0, 7, 1),
146 Border::Negative(_) => &second_derivative!(0, 7, 2),
147 Border::Positive(0) => &second_derivative!(7, 0, 0),
148 Border::Positive(1) => &second_derivative!(7, 0, -1),
149 Border::Positive(_) => &second_derivative!(7, 0, -2),
150 },
151 _ => unimplemented!("Kernel is unimplemented for order {}", ORDER),
152 }
153 }
154
155 fn scale(&self, spacing: f64) -> f64 {
156 1.0 / (spacing * spacing)
157 }
158}
159
160#[derive(Clone)]
162pub struct Dissipation<const ORDER: usize>;
163
164impl<const ORDER: usize> Kernel for Dissipation<ORDER> {
165 fn border_width(&self) -> usize {
166 ORDER / 2
167 }
168
169 fn interior(&self) -> &[f64] {
170 match ORDER {
171 4 => &[1.0, -4.0, 6.0, -4.0, 1.0],
172 6 => &[1.0, -6.0, 15.0, -20.0, 15.0, -6.0, 1.0],
173 _ => unimplemented!("Kernel is unimplemented for order {}", ORDER),
174 }
175 }
176
177 fn free(&self, border: Border) -> &[f64] {
178 match ORDER {
179 4 => match border {
180 Border::Negative(0) => &[3.0, -14.0, 26.0, -24.0, 11.0, -2.0],
181 Border::Negative(_) => &[2.0, -9.0, 16.0, -14.0, 6.0, -1.0],
182 Border::Positive(0) => &[-2.0, 11.0, -24.0, 26.0, -14.0, 3.0],
183 Border::Positive(_) => &[-1.0, 6.0, -14.0, 16.0, -9.0, 2.0],
184 },
185 6 => match border {
186 Border::Negative(0) => &[4.0, -27.0, 78.0, -125.0, 120.0, -69.0, 22.0, -3.0],
187 Border::Negative(1) => &[3.0, -20.0, 57.0, -90.0, 85.0, -48.0, 15.0, -2.0],
188 Border::Negative(_) => &[2.0, -13.0, 36.0, -55.0, 50.0, -27.0, 8.0, -1.0],
189 Border::Positive(0) => &[-3.0, 22.0, -69.0, 120.0, -125.0, 78.0, -27.0, 4.0],
190 Border::Positive(1) => &[-2.0, 15.0, -48.0, 85.0, -90.0, 57.0, -20.0, 3.0],
191 Border::Positive(_) => &[-1.0, 8.0, -27.0, 50.0, -55.0, 36.0, -13.0, 2.0],
192 },
193 _ => unimplemented!("Kernel is unimplemented for order {}", ORDER),
194 }
195 }
196
197 fn scale(&self, _spacing: f64) -> f64 {
198 match ORDER {
199 4 => -1.0 / 16.0,
200 6 => 1.0 / 64.0,
201 _ => unimplemented!("Kernel is unimplemented for order {}", ORDER),
202 }
203 }
204}
205
206#[derive(Clone)]
207pub struct Interpolation<const ORDER: usize>;
208
209impl<const ORDER: usize> Interpolant for Interpolation<ORDER> {
210 fn border_width(&self) -> usize {
211 ORDER / 2
212 }
213
214 fn interior(&self) -> &[f64] {
215 match ORDER {
216 2 => &[-1.0, 9.0, 9.0, -1.0],
217 4 => &[3.0, -25.0, 150.0, 150.0, -25.0, 3.0],
218 _ => unimplemented!("Kernel is unimplemented for order {}", ORDER),
219 }
220 }
221
222 fn free(&self, border: Border) -> &[f64] {
223 match ORDER {
224 2 => match border {
225 Border::Positive(_) => &[1.0, -5.0, 15.0, 5.0],
226 Border::Negative(_) => &[5.0, 15.0, -5.0, 1.0],
227 },
228 4 => match border {
229 Border::Negative(0) => &[63.0, 315.0, -210.0, 126.0, -45.0, 7.0],
230 Border::Negative(_) => &[-7.0, 105.0, 210.0, -70.0, 21.0, -3.0],
231 Border::Positive(0) => &[7.0, -45.0, 126.0, -210.0, 315.0, 63.0],
232 Border::Positive(_) => &[-3.0, 21.0, -70.0, 210.0, 105.0, -7.0],
233 },
234 _ => unimplemented!("Kernel is unimplemented for order {}", ORDER),
235 }
236 }
237
238 fn scale(&self) -> f64 {
239 match ORDER {
240 2 => 1.0 / 16.0,
241 4 => 1.0 / 256.0,
242 _ => unimplemented!("Kernel is unimplemented for order {}", ORDER),
243 }
244 }
245}