raddy/scalar/
operator_traits_impl.rs#![allow(unused)]
use crate::Ad;
use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Rem, RemAssign, Sub, SubAssign};
impl<const N: usize> Neg for &Ad<N> {
type Output = Ad<N>;
fn neg(self) -> Ad<N> {
let mut res = Ad::<N>::_zeroed();
res.value = -self.value;
res.grad = -self.grad;
res.hess = -self.hess;
res
}
}
impl<const N: usize> Neg for Ad<N> {
type Output = Ad<N>;
fn neg(self) -> Ad<N> {
let mut res = Ad::<N>::_zeroed();
res.value = -self.value;
res.grad = -self.grad;
res.hess = -self.hess;
res
}
}
impl<const N: usize> Add<&Ad<N>> for &Ad<N> {
type Output = Ad<N>;
fn add(self, rhs: &Ad<N>) -> Self::Output {
let mut res = Ad::<N>::_zeroed();
res.value = self.value + rhs.value;
res.grad = self.grad + rhs.grad;
res.hess = self.hess + rhs.hess;
res
}
}
impl<const N: usize> Add<Ad<N>> for &Ad<N> {
type Output = Ad<N>;
fn add(self, rhs: Ad<N>) -> Self::Output {
let mut res = Ad::<N>::_zeroed();
res.value = self.value + rhs.value;
res.grad = self.grad + rhs.grad;
res.hess = self.hess + rhs.hess;
res
}
}
impl<const N: usize> Add<&Ad<N>> for Ad<N> {
type Output = Ad<N>;
fn add(self, rhs: &Ad<N>) -> Self::Output {
let mut res = Ad::<N>::_zeroed();
res.value = self.value + rhs.value;
res.grad = self.grad + rhs.grad;
res.hess = self.hess + rhs.hess;
res
}
}
impl<const N: usize> Add<Ad<N>> for Ad<N> {
type Output = Ad<N>;
fn add(self, rhs: Ad<N>) -> Self::Output {
let mut res = Ad::<N>::_zeroed();
res.value = self.value + rhs.value;
res.grad = self.grad + rhs.grad;
res.hess = self.hess + rhs.hess;
res
}
}
impl<const N: usize> Sub<&Ad<N>> for &Ad<N> {
type Output = Ad<N>;
fn sub(self, rhs: &Ad<N>) -> Self::Output {
let mut res = Ad::<N>::_zeroed();
res.value = self.value - rhs.value;
res.grad = self.grad - rhs.grad;
res.hess = self.hess - rhs.hess;
res
}
}
impl<const N: usize> Sub<Ad<N>> for &Ad<N> {
type Output = Ad<N>;
fn sub(self, rhs: Ad<N>) -> Self::Output {
let mut res = Ad::<N>::_zeroed();
res.value = self.value - rhs.value;
res.grad = self.grad - rhs.grad;
res.hess = self.hess - rhs.hess;
res
}
}
impl<const N: usize> Sub<&Ad<N>> for Ad<N> {
type Output = Ad<N>;
fn sub(self, rhs: &Ad<N>) -> Self::Output {
let mut res = Ad::<N>::_zeroed();
res.value = self.value - rhs.value;
res.grad = self.grad - rhs.grad;
res.hess = self.hess - rhs.hess;
res
}
}
impl<const N: usize> Sub<Ad<N>> for Ad<N> {
type Output = Ad<N>;
fn sub(self, rhs: Ad<N>) -> Self::Output {
let mut res = Ad::<N>::_zeroed();
res.value = self.value - rhs.value;
res.grad = self.grad - rhs.grad;
res.hess = self.hess - rhs.hess;
res
}
}
impl<const N: usize> Mul<&Ad<N>> for &Ad<N> {
type Output = Ad<N>;
fn mul(self, rhs: &Ad<N>) -> Self::Output {
let mut res = Ad::<N>::_zeroed();
res.value = self.value * rhs.value;
res.grad = self.grad * rhs.value + self.value * rhs.grad;
res.hess = rhs.value * self.hess
+ self.value * rhs.hess
+ self.grad * rhs.grad.transpose()
+ rhs.grad * self.grad.transpose();
res
}
}
impl<const N: usize> Mul<Ad<N>> for &Ad<N> {
type Output = Ad<N>;
fn mul(self, rhs: Ad<N>) -> Self::Output {
let mut res = Ad::<N>::_zeroed();
res.value = self.value * rhs.value;
res.grad = self.grad * rhs.value + self.value * rhs.grad;
res.hess = rhs.value * self.hess
+ self.value * rhs.hess
+ self.grad * rhs.grad.transpose()
+ rhs.grad * self.grad.transpose();
res
}
}
impl<const N: usize> Mul<&Ad<N>> for Ad<N> {
type Output = Ad<N>;
fn mul(self, rhs: &Ad<N>) -> Self::Output {
let mut res = Ad::<N>::_zeroed();
res.value = self.value * rhs.value;
res.grad = self.grad * rhs.value + self.value * rhs.grad;
res.hess = rhs.value * self.hess
+ self.value * rhs.hess
+ self.grad * rhs.grad.transpose()
+ rhs.grad * self.grad.transpose();
res
}
}
impl<const N: usize> Mul<Ad<N>> for Ad<N> {
type Output = Ad<N>;
fn mul(self, rhs: Ad<N>) -> Self::Output {
let mut res = Ad::<N>::_zeroed();
res.value = self.value * rhs.value;
res.grad = self.grad * rhs.value + self.value * rhs.grad;
res.hess = rhs.value * self.hess
+ self.value * rhs.hess
+ self.grad * rhs.grad.transpose()
+ rhs.grad * self.grad.transpose();
res
}
}
impl<const N: usize> Div<&Ad<N>> for &Ad<N> {
type Output = Ad<N>;
fn div(self, rhs: &Ad<N>) -> Self::Output {
if rhs.value.abs() == 0.0 {
panic!("Division By Zero!");
}
let mut res = Ad::<N>::_zeroed();
res.value = self.value / rhs.value;
res.grad = (rhs.value * self.grad - self.value * rhs.grad) / (rhs.value * rhs.value);
res.hess = (self.hess
- res.grad * rhs.grad.transpose()
- rhs.grad * res.grad.transpose()
- res.value * rhs.hess)
/ rhs.value;
res
}
}
impl<const N: usize> Div<Ad<N>> for &Ad<N> {
type Output = Ad<N>;
fn div(self, rhs: Ad<N>) -> Self::Output {
if rhs.value.abs() == 0.0 {
panic!("Division By Zero!");
}
let mut res = Ad::<N>::_zeroed();
res.value = self.value / rhs.value;
res.grad = (rhs.value * self.grad - self.value * rhs.grad) / (rhs.value * rhs.value);
res.hess = (self.hess
- res.grad * rhs.grad.transpose()
- rhs.grad * res.grad.transpose()
- res.value * rhs.hess)
/ rhs.value;
res
}
}
impl<const N: usize> Div<&Ad<N>> for Ad<N> {
type Output = Ad<N>;
fn div(self, rhs: &Ad<N>) -> Self::Output {
if rhs.value.abs() == 0.0 {
panic!("Division By Zero!");
}
let mut res = Ad::<N>::_zeroed();
res.value = self.value / rhs.value;
res.grad = (rhs.value * self.grad - self.value * rhs.grad) / (rhs.value * rhs.value);
res.hess = (self.hess
- res.grad * rhs.grad.transpose()
- rhs.grad * res.grad.transpose()
- res.value * rhs.hess)
/ rhs.value;
res
}
}
impl<const N: usize> Div<Ad<N>> for Ad<N> {
type Output = Ad<N>;
fn div(self, rhs: Ad<N>) -> Self::Output {
if rhs.value.abs() == 0.0 {
panic!("Division By Zero!");
}
let mut res = Ad::<N>::_zeroed();
res.value = self.value / rhs.value;
res.grad = (rhs.value * self.grad - self.value * rhs.grad) / (rhs.value * rhs.value);
res.hess = (self.hess
- res.grad * rhs.grad.transpose()
- rhs.grad * res.grad.transpose()
- res.value * rhs.hess)
/ rhs.value;
res
}
}
impl<const N: usize> Rem<&Ad<N>> for &Ad<N> {
type Output = Ad<N>;
fn rem(self, rhs: &Ad<N>) -> Self::Output {
unimplemented!();
}
}
impl<const N: usize> Rem<Ad<N>> for &Ad<N> {
type Output = Ad<N>;
fn rem(self, rhs: Ad<N>) -> Self::Output {
unimplemented!();
}
}
impl<const N: usize> Rem<&Ad<N>> for Ad<N> {
type Output = Ad<N>;
fn rem(self, rhs: &Ad<N>) -> Self::Output {
unimplemented!();
}
}
impl<const N: usize> Rem<Ad<N>> for Ad<N> {
type Output = Ad<N>;
fn rem(self, rhs: Ad<N>) -> Self::Output {
unimplemented!();
}
}
impl<const N: usize> AddAssign<&Ad<N>> for Ad<N> {
fn add_assign(&mut self, rhs: &Ad<N>) {
*self = self.clone() + rhs;
}
}
impl<const N: usize> AddAssign<Ad<N>> for Ad<N> {
fn add_assign(&mut self, rhs: Ad<N>) {
*self = self.clone() + rhs;
}
}
impl<const N: usize> SubAssign<&Ad<N>> for Ad<N> {
fn sub_assign(&mut self, rhs: &Ad<N>) {
*self = self.clone() - rhs;
}
}
impl<const N: usize> SubAssign<Ad<N>> for Ad<N> {
fn sub_assign(&mut self, rhs: Ad<N>) {
*self = self.clone() - rhs;
}
}
impl<const N: usize> MulAssign<&Ad<N>> for Ad<N> {
fn mul_assign(&mut self, rhs: &Ad<N>) {
*self = self.clone() * rhs;
}
}
impl<const N: usize> MulAssign<Ad<N>> for Ad<N> {
fn mul_assign(&mut self, rhs: Ad<N>) {
*self = self.clone() * rhs;
}
}
impl<const N: usize> DivAssign<&Ad<N>> for Ad<N> {
fn div_assign(&mut self, rhs: &Ad<N>) {
*self = self.clone() / rhs;
}
}
impl<const N: usize> DivAssign<Ad<N>> for Ad<N> {
fn div_assign(&mut self, rhs: Ad<N>) {
*self = self.clone() / rhs;
}
}
impl<const N: usize> RemAssign<&Ad<N>> for Ad<N> {
fn rem_assign(&mut self, rhs: &Ad<N>) {
unimplemented!();
}
}
impl<const N: usize> RemAssign<Ad<N>> for Ad<N> {
fn rem_assign(&mut self, rhs: Ad<N>) {
unimplemented!();
}
}