use crate::scalar::Scalar;
use std::fmt;
use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
#[derive(Clone)]
pub struct FReal<T: Scalar> {
value: T,
derivative: T,
}
impl<T: Scalar> FReal<T> {
pub fn new(value: T, derivative: T) -> Self {
FReal { value, derivative }
}
pub fn constant(value: T) -> Self {
FReal {
value,
derivative: T::zero(),
}
}
#[inline]
pub fn value(&self) -> T {
self.value
}
#[inline]
pub fn set_value(&mut self, v: T) {
self.value = v;
}
#[inline]
pub fn derivative(&self) -> T {
self.derivative
}
#[inline]
pub fn set_derivative(&mut self, d: T) {
self.derivative = d;
}
}
impl<T: Scalar> From<T> for FReal<T> {
fn from(value: T) -> Self {
FReal::constant(value)
}
}
impl From<i32> for FReal<f64> {
fn from(value: i32) -> Self {
FReal::constant(value as f64)
}
}
impl From<i32> for FReal<f32> {
fn from(value: i32) -> Self {
FReal::constant(value as f32)
}
}
impl<T: Scalar> Add for FReal<T> {
type Output = FReal<T>;
#[inline]
fn add(self, rhs: FReal<T>) -> FReal<T> {
FReal {
value: self.value + rhs.value,
derivative: self.derivative + rhs.derivative,
}
}
}
impl<T: Scalar> Add for &FReal<T> {
type Output = FReal<T>;
#[inline]
fn add(self, rhs: &FReal<T>) -> FReal<T> {
FReal {
value: self.value + rhs.value,
derivative: self.derivative + rhs.derivative,
}
}
}
impl<T: Scalar> Add<&FReal<T>> for FReal<T> {
type Output = FReal<T>;
#[inline]
fn add(self, rhs: &FReal<T>) -> FReal<T> {
FReal {
value: self.value + rhs.value,
derivative: self.derivative + rhs.derivative,
}
}
}
impl<T: Scalar> Add<FReal<T>> for &FReal<T> {
type Output = FReal<T>;
#[inline]
fn add(self, rhs: FReal<T>) -> FReal<T> {
FReal {
value: self.value + rhs.value,
derivative: self.derivative + rhs.derivative,
}
}
}
impl<T: Scalar> Add<T> for FReal<T> {
type Output = FReal<T>;
#[inline]
fn add(self, rhs: T) -> FReal<T> {
FReal {
value: self.value + rhs,
derivative: self.derivative,
}
}
}
impl<T: Scalar> Add<T> for &FReal<T> {
type Output = FReal<T>;
#[inline]
fn add(self, rhs: T) -> FReal<T> {
FReal {
value: self.value + rhs,
derivative: self.derivative,
}
}
}
impl Add<FReal<f64>> for f64 {
type Output = FReal<f64>;
#[inline]
fn add(self, rhs: FReal<f64>) -> FReal<f64> {
FReal {
value: self + rhs.value,
derivative: rhs.derivative,
}
}
}
impl Add<&FReal<f64>> for f64 {
type Output = FReal<f64>;
#[inline]
fn add(self, rhs: &FReal<f64>) -> FReal<f64> {
FReal {
value: self + rhs.value,
derivative: rhs.derivative,
}
}
}
impl Add<FReal<f32>> for f32 {
type Output = FReal<f32>;
#[inline]
fn add(self, rhs: FReal<f32>) -> FReal<f32> {
FReal {
value: self + rhs.value,
derivative: rhs.derivative,
}
}
}
impl Add<&FReal<f32>> for f32 {
type Output = FReal<f32>;
#[inline]
fn add(self, rhs: &FReal<f32>) -> FReal<f32> {
FReal {
value: self + rhs.value,
derivative: rhs.derivative,
}
}
}
impl<T: Scalar> Sub for FReal<T> {
type Output = FReal<T>;
#[inline]
fn sub(self, rhs: FReal<T>) -> FReal<T> {
FReal {
value: self.value - rhs.value,
derivative: self.derivative - rhs.derivative,
}
}
}
impl<T: Scalar> Sub for &FReal<T> {
type Output = FReal<T>;
#[inline]
fn sub(self, rhs: &FReal<T>) -> FReal<T> {
FReal {
value: self.value - rhs.value,
derivative: self.derivative - rhs.derivative,
}
}
}
impl<T: Scalar> Sub<&FReal<T>> for FReal<T> {
type Output = FReal<T>;
#[inline]
fn sub(self, rhs: &FReal<T>) -> FReal<T> {
FReal {
value: self.value - rhs.value,
derivative: self.derivative - rhs.derivative,
}
}
}
impl<T: Scalar> Sub<FReal<T>> for &FReal<T> {
type Output = FReal<T>;
#[inline]
fn sub(self, rhs: FReal<T>) -> FReal<T> {
FReal {
value: self.value - rhs.value,
derivative: self.derivative - rhs.derivative,
}
}
}
impl<T: Scalar> Sub<T> for FReal<T> {
type Output = FReal<T>;
#[inline]
fn sub(self, rhs: T) -> FReal<T> {
FReal {
value: self.value - rhs,
derivative: self.derivative,
}
}
}
impl<T: Scalar> Sub<T> for &FReal<T> {
type Output = FReal<T>;
#[inline]
fn sub(self, rhs: T) -> FReal<T> {
FReal {
value: self.value - rhs,
derivative: self.derivative,
}
}
}
impl Sub<FReal<f64>> for f64 {
type Output = FReal<f64>;
#[inline]
fn sub(self, rhs: FReal<f64>) -> FReal<f64> {
FReal {
value: self - rhs.value,
derivative: -rhs.derivative,
}
}
}
impl Sub<&FReal<f64>> for f64 {
type Output = FReal<f64>;
#[inline]
fn sub(self, rhs: &FReal<f64>) -> FReal<f64> {
FReal {
value: self - rhs.value,
derivative: -rhs.derivative,
}
}
}
impl Sub<FReal<f32>> for f32 {
type Output = FReal<f32>;
#[inline]
fn sub(self, rhs: FReal<f32>) -> FReal<f32> {
FReal {
value: self - rhs.value,
derivative: -rhs.derivative,
}
}
}
impl Sub<&FReal<f32>> for f32 {
type Output = FReal<f32>;
#[inline]
fn sub(self, rhs: &FReal<f32>) -> FReal<f32> {
FReal {
value: self - rhs.value,
derivative: -rhs.derivative,
}
}
}
impl<T: Scalar> Mul for FReal<T> {
type Output = FReal<T>;
#[inline]
fn mul(self, rhs: FReal<T>) -> FReal<T> {
FReal {
value: self.value * rhs.value,
derivative: self.derivative * rhs.value + self.value * rhs.derivative,
}
}
}
impl<T: Scalar> Mul for &FReal<T> {
type Output = FReal<T>;
#[inline]
fn mul(self, rhs: &FReal<T>) -> FReal<T> {
FReal {
value: self.value * rhs.value,
derivative: self.derivative * rhs.value + self.value * rhs.derivative,
}
}
}
impl<T: Scalar> Mul<&FReal<T>> for FReal<T> {
type Output = FReal<T>;
#[inline]
fn mul(self, rhs: &FReal<T>) -> FReal<T> {
FReal {
value: self.value * rhs.value,
derivative: self.derivative * rhs.value + self.value * rhs.derivative,
}
}
}
impl<T: Scalar> Mul<FReal<T>> for &FReal<T> {
type Output = FReal<T>;
#[inline]
fn mul(self, rhs: FReal<T>) -> FReal<T> {
FReal {
value: self.value * rhs.value,
derivative: self.derivative * rhs.value + self.value * rhs.derivative,
}
}
}
impl<T: Scalar> Mul<T> for FReal<T> {
type Output = FReal<T>;
#[inline]
fn mul(self, rhs: T) -> FReal<T> {
FReal {
value: self.value * rhs,
derivative: self.derivative * rhs,
}
}
}
impl<T: Scalar> Mul<T> for &FReal<T> {
type Output = FReal<T>;
#[inline]
fn mul(self, rhs: T) -> FReal<T> {
FReal {
value: self.value * rhs,
derivative: self.derivative * rhs,
}
}
}
impl Mul<FReal<f64>> for f64 {
type Output = FReal<f64>;
#[inline]
fn mul(self, rhs: FReal<f64>) -> FReal<f64> {
FReal {
value: self * rhs.value,
derivative: self * rhs.derivative,
}
}
}
impl Mul<&FReal<f64>> for f64 {
type Output = FReal<f64>;
#[inline]
fn mul(self, rhs: &FReal<f64>) -> FReal<f64> {
FReal {
value: self * rhs.value,
derivative: self * rhs.derivative,
}
}
}
impl Mul<FReal<f32>> for f32 {
type Output = FReal<f32>;
#[inline]
fn mul(self, rhs: FReal<f32>) -> FReal<f32> {
FReal {
value: self * rhs.value,
derivative: self * rhs.derivative,
}
}
}
impl Mul<&FReal<f32>> for f32 {
type Output = FReal<f32>;
#[inline]
fn mul(self, rhs: &FReal<f32>) -> FReal<f32> {
FReal {
value: self * rhs.value,
derivative: self * rhs.derivative,
}
}
}
impl<T: Scalar> Div for FReal<T> {
type Output = FReal<T>;
#[inline]
fn div(self, rhs: FReal<T>) -> FReal<T> {
let inv_b = T::one() / rhs.value;
FReal {
value: self.value * inv_b,
derivative: (self.derivative * rhs.value - self.value * rhs.derivative) * inv_b * inv_b,
}
}
}
impl<T: Scalar> Div for &FReal<T> {
type Output = FReal<T>;
#[inline]
fn div(self, rhs: &FReal<T>) -> FReal<T> {
let inv_b = T::one() / rhs.value;
FReal {
value: self.value * inv_b,
derivative: (self.derivative * rhs.value - self.value * rhs.derivative) * inv_b * inv_b,
}
}
}
impl<T: Scalar> Div<&FReal<T>> for FReal<T> {
type Output = FReal<T>;
#[inline]
fn div(self, rhs: &FReal<T>) -> FReal<T> {
let inv_b = T::one() / rhs.value;
FReal {
value: self.value * inv_b,
derivative: (self.derivative * rhs.value - self.value * rhs.derivative) * inv_b * inv_b,
}
}
}
impl<T: Scalar> Div<FReal<T>> for &FReal<T> {
type Output = FReal<T>;
#[inline]
fn div(self, rhs: FReal<T>) -> FReal<T> {
let inv_b = T::one() / rhs.value;
FReal {
value: self.value * inv_b,
derivative: (self.derivative * rhs.value - self.value * rhs.derivative) * inv_b * inv_b,
}
}
}
impl<T: Scalar> Div<T> for FReal<T> {
type Output = FReal<T>;
#[inline]
fn div(self, rhs: T) -> FReal<T> {
let inv = T::one() / rhs;
FReal {
value: self.value * inv,
derivative: self.derivative * inv,
}
}
}
impl<T: Scalar> Div<T> for &FReal<T> {
type Output = FReal<T>;
#[inline]
fn div(self, rhs: T) -> FReal<T> {
let inv = T::one() / rhs;
FReal {
value: self.value * inv,
derivative: self.derivative * inv,
}
}
}
impl Div<FReal<f64>> for f64 {
type Output = FReal<f64>;
#[inline]
fn div(self, rhs: FReal<f64>) -> FReal<f64> {
let inv = 1.0 / rhs.value;
FReal {
value: self * inv,
derivative: -self * rhs.derivative * inv * inv,
}
}
}
impl Div<&FReal<f64>> for f64 {
type Output = FReal<f64>;
#[inline]
fn div(self, rhs: &FReal<f64>) -> FReal<f64> {
let inv = 1.0 / rhs.value;
FReal {
value: self * inv,
derivative: -self * rhs.derivative * inv * inv,
}
}
}
impl Div<FReal<f32>> for f32 {
type Output = FReal<f32>;
#[inline]
fn div(self, rhs: FReal<f32>) -> FReal<f32> {
let inv = 1.0 / rhs.value;
FReal {
value: self * inv,
derivative: -self * rhs.derivative * inv * inv,
}
}
}
impl Div<&FReal<f32>> for f32 {
type Output = FReal<f32>;
#[inline]
fn div(self, rhs: &FReal<f32>) -> FReal<f32> {
let inv = 1.0 / rhs.value;
FReal {
value: self * inv,
derivative: -self * rhs.derivative * inv * inv,
}
}
}
impl<T: Scalar> Neg for FReal<T> {
type Output = FReal<T>;
#[inline]
fn neg(self) -> FReal<T> {
FReal {
value: -self.value,
derivative: -self.derivative,
}
}
}
impl<T: Scalar> Neg for &FReal<T> {
type Output = FReal<T>;
#[inline]
fn neg(self) -> FReal<T> {
FReal {
value: -self.value,
derivative: -self.derivative,
}
}
}
impl<T: Scalar> AddAssign for FReal<T> {
fn add_assign(&mut self, rhs: FReal<T>) {
self.value = self.value + rhs.value;
self.derivative = self.derivative + rhs.derivative;
}
}
impl<T: Scalar> AddAssign<&FReal<T>> for FReal<T> {
fn add_assign(&mut self, rhs: &FReal<T>) {
self.value = self.value + rhs.value;
self.derivative = self.derivative + rhs.derivative;
}
}
impl<T: Scalar> AddAssign<T> for FReal<T> {
fn add_assign(&mut self, rhs: T) {
self.value = self.value + rhs;
}
}
impl<T: Scalar> SubAssign for FReal<T> {
fn sub_assign(&mut self, rhs: FReal<T>) {
self.value = self.value - rhs.value;
self.derivative = self.derivative - rhs.derivative;
}
}
impl<T: Scalar> SubAssign<&FReal<T>> for FReal<T> {
fn sub_assign(&mut self, rhs: &FReal<T>) {
self.value = self.value - rhs.value;
self.derivative = self.derivative - rhs.derivative;
}
}
impl<T: Scalar> SubAssign<T> for FReal<T> {
fn sub_assign(&mut self, rhs: T) {
self.value = self.value - rhs;
}
}
impl<T: Scalar> MulAssign for FReal<T> {
fn mul_assign(&mut self, rhs: FReal<T>) {
let new_deriv = self.derivative * rhs.value + self.value * rhs.derivative;
self.value = self.value * rhs.value;
self.derivative = new_deriv;
}
}
impl<T: Scalar> MulAssign<&FReal<T>> for FReal<T> {
fn mul_assign(&mut self, rhs: &FReal<T>) {
let new_deriv = self.derivative * rhs.value + self.value * rhs.derivative;
self.value = self.value * rhs.value;
self.derivative = new_deriv;
}
}
impl<T: Scalar> MulAssign<T> for FReal<T> {
fn mul_assign(&mut self, rhs: T) {
self.value = self.value * rhs;
self.derivative = self.derivative * rhs;
}
}
impl<T: Scalar> DivAssign for FReal<T> {
fn div_assign(&mut self, rhs: FReal<T>) {
let inv_b = T::one() / rhs.value;
self.derivative =
(self.derivative * rhs.value - self.value * rhs.derivative) * inv_b * inv_b;
self.value *= inv_b;
}
}
impl<T: Scalar> DivAssign<&FReal<T>> for FReal<T> {
fn div_assign(&mut self, rhs: &FReal<T>) {
let inv_b = T::one() / rhs.value;
self.derivative =
(self.derivative * rhs.value - self.value * rhs.derivative) * inv_b * inv_b;
self.value *= inv_b;
}
}
impl<T: Scalar> DivAssign<T> for FReal<T> {
fn div_assign(&mut self, rhs: T) {
let inv = T::one() / rhs;
self.value *= inv;
self.derivative *= inv;
}
}
impl<T: Scalar> PartialEq for FReal<T> {
fn eq(&self, other: &Self) -> bool {
self.value == other.value
}
}
impl<T: Scalar> PartialEq<T> for FReal<T> {
fn eq(&self, other: &T) -> bool {
self.value == *other
}
}
impl<T: Scalar> PartialOrd for FReal<T> {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
self.value.partial_cmp(&other.value)
}
}
impl<T: Scalar> PartialOrd<T> for FReal<T> {
fn partial_cmp(&self, other: &T) -> Option<std::cmp::Ordering> {
self.value.partial_cmp(other)
}
}
impl<T: Scalar> fmt::Display for FReal<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.value)
}
}
impl<T: Scalar> fmt::Debug for FReal<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "FReal({}, deriv={})", self.value, self.derivative)
}
}
impl<T: Scalar> Default for FReal<T> {
fn default() -> Self {
FReal::constant(T::zero())
}
}
use crate::math;
#[derive(Clone)]
pub struct NamedFReal<T: Scalar> {
pub(crate) inner: FReal<T>,
#[cfg(debug_assertions)]
pub(crate) gen_id: u64,
}
impl<T: Scalar> NamedFReal<T> {
#[inline]
pub(crate) fn __from_inner(inner: FReal<T>) -> Self {
Self {
inner,
#[cfg(debug_assertions)]
gen_id: crate::forward_tape::current_gen(),
}
}
#[inline]
pub fn value(&self) -> T {
self.inner.value()
}
#[inline]
pub fn derivative(&self, _name: &str) -> T {
self.inner.derivative()
}
#[inline]
pub fn inner(&self) -> &FReal<T> {
&self.inner
}
#[inline]
pub fn exp(&self) -> Self {
Self {
inner: math::fwd::exp(&self.inner),
#[cfg(debug_assertions)]
gen_id: self.gen_id,
}
}
#[inline]
pub fn ln(&self) -> Self {
Self {
inner: math::fwd::ln(&self.inner),
#[cfg(debug_assertions)]
gen_id: self.gen_id,
}
}
#[inline]
pub fn sqrt(&self) -> Self {
Self {
inner: math::fwd::sqrt(&self.inner),
#[cfg(debug_assertions)]
gen_id: self.gen_id,
}
}
#[inline]
pub fn sin(&self) -> Self {
Self {
inner: math::fwd::sin(&self.inner),
#[cfg(debug_assertions)]
gen_id: self.gen_id,
}
}
#[inline]
pub fn cos(&self) -> Self {
Self {
inner: math::fwd::cos(&self.inner),
#[cfg(debug_assertions)]
gen_id: self.gen_id,
}
}
#[inline]
pub fn tan(&self) -> Self {
Self {
inner: math::fwd::tan(&self.inner),
#[cfg(debug_assertions)]
gen_id: self.gen_id,
}
}
#[inline]
pub fn norm_cdf(&self) -> Self {
Self {
inner: math::fwd::norm_cdf(&self.inner),
#[cfg(debug_assertions)]
gen_id: self.gen_id,
}
}
#[inline]
pub fn inv_norm_cdf(&self) -> Self {
Self {
inner: math::fwd::inv_norm_cdf(&self.inner),
#[cfg(debug_assertions)]
gen_id: self.gen_id,
}
}
}
impl<T: Scalar> fmt::Debug for NamedFReal<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("NamedFReal")
.field("value", &self.inner.value())
.field("derivative", &self.inner.derivative())
.finish()
}
}
impl<T: Scalar> fmt::Display for NamedFReal<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "NamedFReal({})", self.inner.value())
}
}
macro_rules! __named_freal_binop {
($trait:ident, $method:ident, $op:tt) => {
impl<T: Scalar> ::core::ops::$trait<NamedFReal<T>> for NamedFReal<T> {
type Output = NamedFReal<T>;
#[inline]
fn $method(self, rhs: NamedFReal<T>) -> NamedFReal<T> {
#[cfg(debug_assertions)]
crate::forward_tape::check_gen(self.gen_id, rhs.gen_id);
NamedFReal {
inner: self.inner $op rhs.inner,
#[cfg(debug_assertions)]
gen_id: self.gen_id,
}
}
}
impl<T: Scalar> ::core::ops::$trait<&NamedFReal<T>> for &NamedFReal<T> {
type Output = NamedFReal<T>;
#[inline]
fn $method(self, rhs: &NamedFReal<T>) -> NamedFReal<T> {
#[cfg(debug_assertions)]
crate::forward_tape::check_gen(self.gen_id, rhs.gen_id);
NamedFReal {
inner: &self.inner $op &rhs.inner,
#[cfg(debug_assertions)]
gen_id: self.gen_id,
}
}
}
impl<T: Scalar> ::core::ops::$trait<&NamedFReal<T>> for NamedFReal<T> {
type Output = NamedFReal<T>;
#[inline]
fn $method(self, rhs: &NamedFReal<T>) -> NamedFReal<T> {
#[cfg(debug_assertions)]
crate::forward_tape::check_gen(self.gen_id, rhs.gen_id);
NamedFReal {
inner: self.inner $op &rhs.inner,
#[cfg(debug_assertions)]
gen_id: self.gen_id,
}
}
}
impl<T: Scalar> ::core::ops::$trait<NamedFReal<T>> for &NamedFReal<T> {
type Output = NamedFReal<T>;
#[inline]
fn $method(self, rhs: NamedFReal<T>) -> NamedFReal<T> {
#[cfg(debug_assertions)]
crate::forward_tape::check_gen(self.gen_id, rhs.gen_id);
NamedFReal {
inner: &self.inner $op rhs.inner,
#[cfg(debug_assertions)]
gen_id: self.gen_id,
}
}
}
impl<T: Scalar> ::core::ops::$trait<T> for NamedFReal<T> {
type Output = NamedFReal<T>;
#[inline]
fn $method(self, rhs: T) -> NamedFReal<T> {
NamedFReal {
inner: self.inner $op rhs,
#[cfg(debug_assertions)]
gen_id: self.gen_id,
}
}
}
impl<T: Scalar> ::core::ops::$trait<T> for &NamedFReal<T> {
type Output = NamedFReal<T>;
#[inline]
fn $method(self, rhs: T) -> NamedFReal<T> {
NamedFReal {
inner: &self.inner $op rhs,
#[cfg(debug_assertions)]
gen_id: self.gen_id,
}
}
}
};
}
__named_freal_binop!(Add, add, +);
__named_freal_binop!(Sub, sub, -);
__named_freal_binop!(Mul, mul, *);
__named_freal_binop!(Div, div, /);
impl<T: Scalar> ::core::ops::Neg for NamedFReal<T> {
type Output = NamedFReal<T>;
#[inline]
fn neg(self) -> NamedFReal<T> {
NamedFReal {
inner: -self.inner,
#[cfg(debug_assertions)]
gen_id: self.gen_id,
}
}
}
impl<T: Scalar> ::core::ops::Neg for &NamedFReal<T> {
type Output = NamedFReal<T>;
#[inline]
fn neg(self) -> NamedFReal<T> {
NamedFReal {
inner: -&self.inner,
#[cfg(debug_assertions)]
gen_id: self.gen_id,
}
}
}
macro_rules! __named_freal_scalar_lhs {
($scalar:ty) => {
impl ::core::ops::Add<NamedFReal<$scalar>> for $scalar {
type Output = NamedFReal<$scalar>;
#[inline]
fn add(self, rhs: NamedFReal<$scalar>) -> NamedFReal<$scalar> {
NamedFReal {
inner: self + rhs.inner,
#[cfg(debug_assertions)]
gen_id: rhs.gen_id,
}
}
}
impl ::core::ops::Add<&NamedFReal<$scalar>> for $scalar {
type Output = NamedFReal<$scalar>;
#[inline]
fn add(self, rhs: &NamedFReal<$scalar>) -> NamedFReal<$scalar> {
NamedFReal {
inner: self + &rhs.inner,
#[cfg(debug_assertions)]
gen_id: rhs.gen_id,
}
}
}
impl ::core::ops::Sub<NamedFReal<$scalar>> for $scalar {
type Output = NamedFReal<$scalar>;
#[inline]
fn sub(self, rhs: NamedFReal<$scalar>) -> NamedFReal<$scalar> {
NamedFReal {
inner: self - rhs.inner,
#[cfg(debug_assertions)]
gen_id: rhs.gen_id,
}
}
}
impl ::core::ops::Sub<&NamedFReal<$scalar>> for $scalar {
type Output = NamedFReal<$scalar>;
#[inline]
fn sub(self, rhs: &NamedFReal<$scalar>) -> NamedFReal<$scalar> {
NamedFReal {
inner: self - &rhs.inner,
#[cfg(debug_assertions)]
gen_id: rhs.gen_id,
}
}
}
impl ::core::ops::Mul<NamedFReal<$scalar>> for $scalar {
type Output = NamedFReal<$scalar>;
#[inline]
fn mul(self, rhs: NamedFReal<$scalar>) -> NamedFReal<$scalar> {
NamedFReal {
inner: self * rhs.inner,
#[cfg(debug_assertions)]
gen_id: rhs.gen_id,
}
}
}
impl ::core::ops::Mul<&NamedFReal<$scalar>> for $scalar {
type Output = NamedFReal<$scalar>;
#[inline]
fn mul(self, rhs: &NamedFReal<$scalar>) -> NamedFReal<$scalar> {
NamedFReal {
inner: self * &rhs.inner,
#[cfg(debug_assertions)]
gen_id: rhs.gen_id,
}
}
}
impl ::core::ops::Div<NamedFReal<$scalar>> for $scalar {
type Output = NamedFReal<$scalar>;
#[inline]
fn div(self, rhs: NamedFReal<$scalar>) -> NamedFReal<$scalar> {
NamedFReal {
inner: self / rhs.inner,
#[cfg(debug_assertions)]
gen_id: rhs.gen_id,
}
}
}
impl ::core::ops::Div<&NamedFReal<$scalar>> for $scalar {
type Output = NamedFReal<$scalar>;
#[inline]
fn div(self, rhs: &NamedFReal<$scalar>) -> NamedFReal<$scalar> {
NamedFReal {
inner: self / &rhs.inner,
#[cfg(debug_assertions)]
gen_id: rhs.gen_id,
}
}
}
};
}
__named_freal_scalar_lhs!(f64);
__named_freal_scalar_lhs!(f32);