raddy/scalar/
operator_traits_impl.rs1#![allow(unused)]
9
10use crate::Ad;
11use std::ops::{
12 Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Rem, RemAssign, Sub, SubAssign,
13};
14
15impl<const N: usize> Neg for &Ad<N> {
16 type Output = Ad<N>;
17
18 fn neg(self) -> Ad<N> {
19 let mut res = Ad::<N>::_zeroed();
20 res.value = -self.value;
21 res.grad = -self.grad;
22 res.hess = -self.hess;
23
24 res
25 }
26}
27
28impl<const N: usize> Neg for Ad<N> {
29 type Output = Ad<N>;
30
31 fn neg(self) -> Ad<N> {
32 let mut res = Ad::<N>::_zeroed();
33 res.value = -self.value;
34 res.grad = -self.grad;
35 res.hess = -self.hess;
36
37 res
38 }
39}
40
41impl<const N: usize> Add<&Ad<N>> for &Ad<N> {
43 type Output = Ad<N>;
44
45 fn add(self, rhs: &Ad<N>) -> Self::Output {
46 let mut res = Ad::<N>::_zeroed();
47 res.value = self.value + rhs.value;
48 res.grad = self.grad + rhs.grad;
49 res.hess = self.hess + rhs.hess;
50
51 res
52 }
53}
54
55impl<const N: usize> Add<Ad<N>> for &Ad<N> {
57 type Output = Ad<N>;
58
59 fn add(self, rhs: Ad<N>) -> Self::Output {
60 let mut res = Ad::<N>::_zeroed();
61 res.value = self.value + rhs.value;
62 res.grad = self.grad + rhs.grad;
63 res.hess = self.hess + rhs.hess;
64
65 res
66 }
67}
68
69impl<const N: usize> Add<&Ad<N>> for Ad<N> {
71 type Output = Ad<N>;
72
73 fn add(self, rhs: &Ad<N>) -> Self::Output {
74 let mut res = Ad::<N>::_zeroed();
75 res.value = self.value + rhs.value;
76 res.grad = self.grad + rhs.grad;
77 res.hess = self.hess + rhs.hess;
78
79 res
80 }
81}
82
83impl<const N: usize> Add<Ad<N>> for Ad<N> {
85 type Output = Ad<N>;
86
87 fn add(self, rhs: Ad<N>) -> Self::Output {
88 let mut res = Ad::<N>::_zeroed();
89 res.value = self.value + rhs.value;
90 res.grad = self.grad + rhs.grad;
91 res.hess = self.hess + rhs.hess;
92
93 res
94 }
95}
96
97impl<const N: usize> Sub<&Ad<N>> for &Ad<N> {
99 type Output = Ad<N>;
100
101 fn sub(self, rhs: &Ad<N>) -> Self::Output {
102 let mut res = Ad::<N>::_zeroed();
103 res.value = self.value - rhs.value;
104 res.grad = self.grad - rhs.grad;
105 res.hess = self.hess - rhs.hess;
106
107 res
108 }
109}
110
111impl<const N: usize> Sub<Ad<N>> for &Ad<N> {
113 type Output = Ad<N>;
114
115 fn sub(self, rhs: Ad<N>) -> Self::Output {
116 let mut res = Ad::<N>::_zeroed();
117 res.value = self.value - rhs.value;
118 res.grad = self.grad - rhs.grad;
119 res.hess = self.hess - rhs.hess;
120
121 res
122 }
123}
124
125impl<const N: usize> Sub<&Ad<N>> for Ad<N> {
127 type Output = Ad<N>;
128
129 fn sub(self, rhs: &Ad<N>) -> Self::Output {
130 let mut res = Ad::<N>::_zeroed();
131 res.value = self.value - rhs.value;
132 res.grad = self.grad - rhs.grad;
133 res.hess = self.hess - rhs.hess;
134
135 res
136 }
137}
138
139impl<const N: usize> Sub<Ad<N>> for Ad<N> {
141 type Output = Ad<N>;
142
143 fn sub(self, rhs: Ad<N>) -> Self::Output {
144 let mut res = Ad::<N>::_zeroed();
145 res.value = self.value - rhs.value;
146 res.grad = self.grad - rhs.grad;
147 res.hess = self.hess - rhs.hess;
148
149 res
150 }
151}
152
153impl<const N: usize> Mul<&Ad<N>> for &Ad<N> {
155 type Output = Ad<N>;
156
157 fn mul(self, rhs: &Ad<N>) -> Self::Output {
158 let mut res = Ad::<N>::_zeroed();
159
160 res.value = self.value * rhs.value;
161 res.grad = self.grad * rhs.value + self.value * rhs.grad;
162 res.hess = rhs.value * self.hess
163 + self.value * rhs.hess
164 + self.grad * rhs.grad.transpose()
165 + rhs.grad * self.grad.transpose();
166
167 res
168 }
169}
170
171impl<const N: usize> Mul<Ad<N>> for &Ad<N> {
173 type Output = Ad<N>;
174
175 fn mul(self, rhs: Ad<N>) -> Self::Output {
176 let mut res = Ad::<N>::_zeroed();
177
178 res.value = self.value * rhs.value;
179 res.grad = self.grad * rhs.value + self.value * rhs.grad;
180 res.hess = rhs.value * self.hess
181 + self.value * rhs.hess
182 + self.grad * rhs.grad.transpose()
183 + rhs.grad * self.grad.transpose();
184
185 res
186 }
187}
188
189impl<const N: usize> Mul<&Ad<N>> for Ad<N> {
191 type Output = Ad<N>;
192
193 fn mul(self, rhs: &Ad<N>) -> Self::Output {
194 let mut res = Ad::<N>::_zeroed();
195
196 res.value = self.value * rhs.value;
197 res.grad = self.grad * rhs.value + self.value * rhs.grad;
198 res.hess = rhs.value * self.hess
199 + self.value * rhs.hess
200 + self.grad * rhs.grad.transpose()
201 + rhs.grad * self.grad.transpose();
202
203 res
204 }
205}
206
207impl<const N: usize> Mul<Ad<N>> for Ad<N> {
209 type Output = Ad<N>;
210
211 fn mul(self, rhs: Ad<N>) -> Self::Output {
212 let mut res = Ad::<N>::_zeroed();
213
214 res.value = self.value * rhs.value;
215 res.grad = self.grad * rhs.value + self.value * rhs.grad;
216 res.hess = rhs.value * self.hess
217 + self.value * rhs.hess
218 + self.grad * rhs.grad.transpose()
219 + rhs.grad * self.grad.transpose();
220
221 res
222 }
223}
224
225impl<const N: usize> Div<&Ad<N>> for &Ad<N> {
227 type Output = Ad<N>;
228
229 fn div(self, rhs: &Ad<N>) -> Self::Output {
230 if rhs.value.abs() == 0.0 {
231 panic!("Division By Zero!");
233 }
234
235 let mut res = Ad::<N>::_zeroed();
236 res.value = self.value / rhs.value;
237 res.grad = (rhs.value * self.grad - self.value * rhs.grad) / (rhs.value * rhs.value);
238 res.hess = (self.hess
239 - res.grad * rhs.grad.transpose()
240 - rhs.grad * res.grad.transpose()
241 - res.value * rhs.hess)
242 / rhs.value;
243
244 res
245 }
246}
247
248impl<const N: usize> Div<Ad<N>> for &Ad<N> {
250 type Output = Ad<N>;
251
252 fn div(self, rhs: Ad<N>) -> Self::Output {
253 if rhs.value.abs() == 0.0 {
254 panic!("Division By Zero!");
256 }
257
258 let mut res = Ad::<N>::_zeroed();
259 res.value = self.value / rhs.value;
260 res.grad = (rhs.value * self.grad - self.value * rhs.grad) / (rhs.value * rhs.value);
261 res.hess = (self.hess
262 - res.grad * rhs.grad.transpose()
263 - rhs.grad * res.grad.transpose()
264 - res.value * rhs.hess)
265 / rhs.value;
266
267 res
268 }
269}
270
271impl<const N: usize> Div<&Ad<N>> for Ad<N> {
273 type Output = Ad<N>;
274
275 fn div(self, rhs: &Ad<N>) -> Self::Output {
276 if rhs.value.abs() == 0.0 {
277 panic!("Division By Zero!");
279 }
280
281 let mut res = Ad::<N>::_zeroed();
282 res.value = self.value / rhs.value;
283 res.grad = (rhs.value * self.grad - self.value * rhs.grad) / (rhs.value * rhs.value);
284 res.hess = (self.hess
285 - res.grad * rhs.grad.transpose()
286 - rhs.grad * res.grad.transpose()
287 - res.value * rhs.hess)
288 / rhs.value;
289
290 res
291 }
292}
293
294impl<const N: usize> Div<Ad<N>> for Ad<N> {
296 type Output = Ad<N>;
297
298 fn div(self, rhs: Ad<N>) -> Self::Output {
299 if rhs.value.abs() == 0.0 {
300 panic!("Division By Zero!");
302 }
303
304 let mut res = Ad::<N>::_zeroed();
305 res.value = self.value / rhs.value;
306 res.grad = (rhs.value * self.grad - self.value * rhs.grad) / (rhs.value * rhs.value);
307 res.hess = (self.hess
308 - res.grad * rhs.grad.transpose()
309 - rhs.grad * res.grad.transpose()
310 - res.value * rhs.hess)
311 / rhs.value;
312
313 res
314 }
315}
316
317impl<const N: usize> Rem<&Ad<N>> for &Ad<N> {
319 type Output = Ad<N>;
320
321 fn rem(self, rhs: &Ad<N>) -> Self::Output {
322 unimplemented!();
323 }
324}
325
326impl<const N: usize> Rem<Ad<N>> for &Ad<N> {
328 type Output = Ad<N>;
329
330 fn rem(self, rhs: Ad<N>) -> Self::Output {
331 unimplemented!();
332 }
333}
334
335impl<const N: usize> Rem<&Ad<N>> for Ad<N> {
337 type Output = Ad<N>;
338
339 fn rem(self, rhs: &Ad<N>) -> Self::Output {
340 unimplemented!();
341 }
342}
343
344impl<const N: usize> Rem<Ad<N>> for Ad<N> {
346 type Output = Ad<N>;
347
348 fn rem(self, rhs: Ad<N>) -> Self::Output {
349 unimplemented!();
350 }
351}
352
353impl<const N: usize> AddAssign<&Ad<N>> for Ad<N> {
355 fn add_assign(&mut self, rhs: &Ad<N>) {
356 *self = &*self + rhs;
357 }
358}
359
360impl<const N: usize> AddAssign<Ad<N>> for Ad<N> {
362 fn add_assign(&mut self, rhs: Ad<N>) {
363 *self = &*self + rhs;
364 }
365}
366
367impl<const N: usize> SubAssign<&Ad<N>> for Ad<N> {
369 fn sub_assign(&mut self, rhs: &Ad<N>) {
370 *self = &*self - rhs;
371 }
372}
373
374impl<const N: usize> SubAssign<Ad<N>> for Ad<N> {
376 fn sub_assign(&mut self, rhs: Ad<N>) {
377 *self = &*self - rhs;
378 }
379}
380
381impl<const N: usize> MulAssign<&Ad<N>> for Ad<N> {
383 fn mul_assign(&mut self, rhs: &Ad<N>) {
384 *self = &*self * rhs;
385 }
386}
387
388impl<const N: usize> MulAssign<Ad<N>> for Ad<N> {
390 fn mul_assign(&mut self, rhs: Ad<N>) {
391 *self = &*self * rhs;
392 }
393}
394
395impl<const N: usize> DivAssign<&Ad<N>> for Ad<N> {
397 fn div_assign(&mut self, rhs: &Ad<N>) {
398 *self = &*self / rhs;
399 }
400}
401
402impl<const N: usize> DivAssign<Ad<N>> for Ad<N> {
404 fn div_assign(&mut self, rhs: Ad<N>) {
405 *self = &*self / rhs;
406 }
407}
408
409impl<const N: usize> RemAssign<&Ad<N>> for Ad<N> {
411 fn rem_assign(&mut self, rhs: &Ad<N>) {
412 unimplemented!();
413 }
414}
415
416impl<const N: usize> RemAssign<Ad<N>> for Ad<N> {
418 fn rem_assign(&mut self, rhs: Ad<N>) {
419 unimplemented!();
420 }
421}