raddy/scalar/
operator_traits_impl.rs

1/*
2
3This code is generated by meta/operators.py at 12:19:50 @ 2025.01.08
4Do not modify it directly.
5
6*/
7
8#![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
41// &T + &T
42impl<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
55// &T + T
56impl<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
69// T + &T
70impl<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
83// T + T
84impl<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
97// &T - &T
98impl<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
111// &T - T
112impl<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
125// T - &T
126impl<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
139// T - T
140impl<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
153// &T * &T
154impl<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
171// &T * T
172impl<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
189// T * &T
190impl<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
207// T * T
208impl<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
225// &T / &T
226impl<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            // We don't want to mute this behavior or get NaN as this is fucking undebuggable.
232            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
248// &T / T
249impl<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            // We don't want to mute this behavior or get NaN as this is fucking undebuggable.
255            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
271// T / &T
272impl<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            // We don't want to mute this behavior or get NaN as this is fucking undebuggable.
278            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
294// T / T
295impl<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            // We don't want to mute this behavior or get NaN as this is fucking undebuggable.
301            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
317// &T % &T
318impl<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
326// &T % T
327impl<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
335// T % &T
336impl<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
344// T % T
345impl<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
353// T += &T
354impl<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
360// T += T
361impl<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
367// T -= &T
368impl<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
374// T -= T
375impl<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
381// T *= &T
382impl<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
388// T *= T
389impl<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
395// T /= &T
396impl<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
402// T /= T
403impl<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
409// T %= &T
410impl<const N: usize> RemAssign<&Ad<N>> for Ad<N> {
411    fn rem_assign(&mut self, rhs: &Ad<N>) {
412        unimplemented!();
413    }
414}
415
416// T %= T
417impl<const N: usize> RemAssign<Ad<N>> for Ad<N> {
418    fn rem_assign(&mut self, rhs: Ad<N>) {
419        unimplemented!();
420    }
421}