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*/