1use super::{AbsUncertainty, RelUncertainty, Uncertainty};
2use num_traits::Float;
3use std::ops::{Add, Div, Mul, Neg, Sub};
4
5impl<N: Float, U: Uncertainty<Float = N>> Add<U> for RelUncertainty<N> {
6 type Output = RelUncertainty<N>;
7 fn add(self, other: U) -> Self {
8 let other: RelUncertainty<N> = other.into();
9 Self::new(
10 self.mean() + other.mean(),
11 (self.uncertainty().powi(2) + other.uncertainty().powi(2)).sqrt(),
12 )
13 }
14}
15
16impl<N: Float, U: Uncertainty<Float = N>> Add<U> for AbsUncertainty<N> {
17 type Output = AbsUncertainty<N>;
18 fn add(self, other: U) -> Self {
19 let other: AbsUncertainty<N> = other.into();
20 Self::new(
21 self.mean() + other.mean(),
22 (self.uncertainty().powi(2) + other.uncertainty().powi(2)).sqrt(),
23 )
24 }
25}
26
27impl<N: Float, U: Uncertainty<Float = N>> Sub<U> for RelUncertainty<N> {
28 type Output = RelUncertainty<N>;
29 fn sub(self, other: U) -> Self {
30 let other: RelUncertainty<N> = other.into();
31 Self::new(
32 self.mean() - other.mean(),
33 (self.uncertainty().powi(2) + other.uncertainty().powi(2)).sqrt(),
34 )
35 }
36}
37
38impl<N: Float, U: Uncertainty<Float = N>> Sub<U> for AbsUncertainty<N> {
39 type Output = AbsUncertainty<N>;
40 fn sub(self, other: U) -> Self {
41 let other: AbsUncertainty<N> = other.into();
42 Self::new(
43 self.mean() - other.mean(),
44 (self.uncertainty().powi(2) + other.uncertainty().powi(2)).sqrt(),
45 )
46 }
47}
48
49impl<N: Float, U: Uncertainty<Float = N>> Mul<U> for RelUncertainty<N> {
50 type Output = RelUncertainty<N>;
51 fn mul(self, other: U) -> Self {
52 let other: RelUncertainty<N> = other.into();
53 Self::new(
54 self.mean() * other.mean(),
55 (self.uncertainty().powi(2) * other.mean().powi(2)
56 + other.uncertainty().powi(2) * self.mean().powi(2))
57 .sqrt(),
58 )
59 }
60}
61
62impl<N: Float, U: Uncertainty<Float = N>> Mul<U> for AbsUncertainty<N> {
63 type Output = AbsUncertainty<N>;
64 fn mul(self, other: U) -> Self {
65 let other: AbsUncertainty<N> = other.into();
66 Self::new(
67 self.mean() * other.mean(),
68 (self.uncertainty().powi(2) * other.mean().powi(2)
69 + other.uncertainty().powi(2) * self.mean().powi(2))
70 .sqrt(),
71 )
72 }
73}
74
75impl<N: Float, U: Uncertainty<Float = N>> Div<U> for RelUncertainty<N> {
76 type Output = RelUncertainty<N>;
77 fn div(self, other: U) -> Self {
78 let other: RelUncertainty<N> = other.into();
79 Self::new(
80 self.mean() / other.mean(),
81 (self.uncertainty().powi(2) / other.mean().powi(2)
82 + self.mean().powi(2) * (other.uncertainty() * other.mean().powi(2)).abs().powi(2))
83 .sqrt(),
84 )
85 }
86}
87
88impl<N: Float, U: Uncertainty<Float = N>> Div<U> for AbsUncertainty<N> {
89 type Output = AbsUncertainty<N>;
90 fn div(self, other: U) -> Self {
91 let other: AbsUncertainty<N> = other.into();
92 Self::new(
93 self.mean() / other.mean(),
94 (self.uncertainty().powi(2) / other.mean().powi(2)
95 + self.mean().powi(2) * (other.uncertainty() * other.mean().powi(2)).abs().powi(2))
96 .sqrt(),
97 )
98 }
99}
100
101impl<N: Float> Neg for AbsUncertainty<N> {
102 type Output = Self;
103 fn neg(self) -> Self::Output {
104 Self::new(-self.mean(), self.uncertainty())
105 }
106}
107
108impl<N: Float> Neg for RelUncertainty<N> {
109 type Output = Self;
110 fn neg(self) -> Self::Output {
111 Self::new(-self.mean(), self.uncertainty())
112 }
113}