raddy/scalar/
num_traits_impl.rs

1#![allow(unused)]
2use crate::Ad;
3use na::SMatrix;
4use num_traits::{Num, One, Signed, Zero};
5use std::{
6    fmt::Display,
7    mem::zeroed,
8    ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Rem, RemAssign, Sub, SubAssign},
9};
10
11impl<const N: usize> Display for Ad<N> {
12    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13        write!(f, "Ad[{}]", self.value)
14    }
15}
16
17impl<const N: usize> Zero for Ad<N> {
18    fn zero() -> Self {
19        Ad::_zeroed()
20    }
21
22    fn is_zero(&self) -> bool {
23        self.value.abs() == 0.0
24            && self.grad.as_slice().into_iter().all(|&x| x.abs() == 0.0)
25            && self.hess.as_slice().into_iter().all(|&x| x.abs() == 0.0)
26    }
27}
28
29impl<const N: usize> One for Ad<N> {
30    fn one() -> Self {
31        let mut res = Ad::_zeroed();
32        res.value = 1.0;
33        res
34    }
35}
36
37impl<const N: usize> Num for Ad<N> {
38    type FromStrRadixErr = ();
39
40    fn from_str_radix(str: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr> {
41        unimplemented!()
42    }
43}
44
45impl<const N: usize> Signed for Ad<N> {
46    fn abs(&self) -> Self {
47        let mut res = Self::_zeroed();
48        res.value = self.value.abs();
49        let sign = if self.value >= 0.0 { 1.0 } else { -1.0 };
50        res.grad = sign * self.grad;
51        res.hess = sign * self.hess;
52
53        res
54    }
55
56    fn abs_sub(&self, other: &Self) -> Self {
57        unimplemented!()
58    }
59
60    fn signum(&self) -> Self {
61        unimplemented!()
62    }
63
64    fn is_positive(&self) -> bool {
65        self.value > 0.0
66    }
67
68    fn is_negative(&self) -> bool {
69        self.value < -0.0
70    }
71}
72
73/*
74
75
76// impl<const N: usize> Neg for Ad<N> {
77//     type Output = Ad<N>;
78
79//     fn neg(self) -> Self::Output {
80//         let mut res = Ad::<N>::_zeroed();
81//         res.value = -self.value;
82//         res.grad = -self.grad;
83//         res.hess = -self.hess;
84
85//         res
86//     }
87// }
88
89// impl<const N: usize> Neg for &Ad<N> {
90//     type Output = Ad<N>;
91
92//     fn neg(self) -> Self::Output {
93//         let mut res = Ad::<N>::_zeroed();
94//         res.value = -self.value;
95//         res.grad = -self.grad;
96//         res.hess = -self.hess;
97
98//         res
99//     }
100// }
101
102// impl<const N: usize> Add for Ad<N> {
103//     type Output = Ad<N>;
104
105//     fn add(self, rhs: Self) -> Self::Output {
106//         let mut res = Ad::<N>::_zeroed();
107//         res.value = self.value + rhs.value;
108//         res.grad = self.grad + rhs.grad;
109//         res.hess = self.hess + rhs.hess;
110
111//         res
112//     }
113// }
114
115// impl<const N: usize> Add<&Ad<N>> for Ad<N> {
116//     type Output = Ad<N>;
117
118//     fn add(self, rhs: &Ad<N>) -> Self::Output {
119//         let mut res = Ad::<N>::_zeroed();
120//         res.value = self.value + rhs.value;
121//         res.grad = self.grad + rhs.grad;
122//         res.hess = self.hess + rhs.hess;
123
124//         res
125//     }
126// }
127
128// impl<const N: usize> Add<Ad<N>> for &Ad<N> {
129//     type Output = Ad<N>;
130
131//     fn add(self, rhs: Ad<N>) -> Self::Output {
132//         let mut res = Ad::<N>::_zeroed();
133//         res.value = self.value + rhs.value;
134//         res.grad = self.grad + rhs.grad;
135//         res.hess = self.hess + rhs.hess;
136
137//         res
138//     }
139// }
140
141// impl<const N: usize> Add<&Ad<N>> for &Ad<N> {
142//     type Output = Ad<N>;
143
144//     fn add(self, rhs: &Ad<N>) -> Self::Output {
145//         let mut res = Ad::<N>::_zeroed();
146//         res.value = self.value + rhs.value;
147//         res.grad = self.grad + rhs.grad;
148//         res.hess = self.hess + rhs.hess;
149
150//         res
151//     }
152// }
153
154// impl<const N: usize> AddAssign<Ad<N>> for Ad<N> {
155//     fn add_assign(&mut self, rhs: Ad<N>) {
156//         *self = self.clone() + rhs;
157//     }
158// }
159
160// impl<const N: usize> AddAssign<&Ad<N>> for Ad<N> {
161//     fn add_assign(&mut self, rhs: &Ad<N>) {
162//         *self = self.clone() + rhs;
163//     }
164// }
165
166// impl<const N: usize> Sub for Ad<N> {
167//     type Output = Self;
168
169//     fn sub(self, rhs: Self) -> Self::Output {
170//         let mut res = Self::_zeroed();
171//         res.value = self.value - rhs.value;
172//         res.grad = self.grad - rhs.grad;
173//         res.hess = self.hess - rhs.hess;
174
175//         res
176//     }
177// }
178
179// impl<const N: usize> SubAssign for Ad<N> {
180//     fn sub_assign(&mut self, rhs: Self) {
181//         *self = self.clone() - rhs;
182//     }
183// }
184
185// impl<const N: usize> Mul for Ad<N> {
186//     type Output = Self;
187
188//     fn mul(self, rhs: Self) -> Self::Output {
189//         let mut res = Self::_zeroed();
190//         res.value = self.value * rhs.value;
191//         res.grad = self.grad * rhs.value + self.value * rhs.grad;
192//         res.hess = rhs.value * self.hess
193//             + self.value * rhs.hess
194//             + self.grad * rhs.grad.transpose()
195//             + rhs.grad * self.grad.transpose();
196
197//         res
198//     }
199// }
200
201// impl<const N: usize> MulAssign for Ad<N> {
202//     fn mul_assign(&mut self, rhs: Self) {
203//         *self = self.clone() * rhs;
204//     }
205// }
206
207// impl<const N: usize> Div for Ad<N> {
208//     type Output = Self;
209
210//     fn div(self, rhs: Self) -> Self {
211//         if rhs.value.abs() == 0.0 {
212//             // We don't want to mute this behavior or get NaN as this is fucking undebuggable.
213//             panic!("Division By Zero!");
214//         }
215
216//         let mut res = Self::_zeroed();
217//         res.value = self.value / rhs.value;
218//         res.grad = (rhs.value * self.grad - self.value * rhs.grad) / (rhs.value * rhs.value);
219//         res.hess = (self.hess
220//             - res.grad * rhs.grad.transpose()
221//             - rhs.grad * res.grad.transpose()
222//             - res.value * rhs.hess)
223//             / rhs.value;
224
225//         res
226//     }
227// }
228
229// impl<const N: usize> DivAssign for Ad<N> {
230//     fn div_assign(&mut self, rhs: Self) {
231//         *self = self.clone() / rhs;
232//     }
233// }
234
235// impl<const N: usize> Rem for Ad<N> {
236//     type Output = Self;
237
238//     fn rem(self, rhs: Self) -> Self {
239//         unimplemented!()
240//     }
241// }
242
243// impl<const N: usize> RemAssign for Ad<N> {
244//     fn rem_assign(&mut self, rhs: Self) {
245//         unimplemented!()
246//     }
247// }
248
249*/