rateslib/dual/dual_ops/
ord.rs1use crate::dual::dual::{Dual, Dual2};
2use crate::dual::enums::Number;
3use std::cmp::Ordering;
4
5impl PartialOrd<Dual> for Dual {
7 fn partial_cmp(&self, other: &Dual) -> Option<Ordering> {
8 self.real.partial_cmp(&other.real)
9 }
10}
11
12impl PartialOrd<f64> for Dual {
13 fn partial_cmp(&self, other: &f64) -> Option<Ordering> {
14 self.real.partial_cmp(other)
15 }
16}
17
18impl PartialOrd<f64> for Dual2 {
19 fn partial_cmp(&self, other: &f64) -> Option<Ordering> {
20 self.real.partial_cmp(other)
21 }
22}
23
24impl PartialOrd<Dual2> for Dual2 {
25 fn partial_cmp(&self, other: &Dual2) -> Option<Ordering> {
26 self.real.partial_cmp(&other.real)
27 }
28}
29
30impl PartialOrd<Dual> for f64 {
31 fn partial_cmp(&self, other: &Dual) -> Option<Ordering> {
32 self.partial_cmp(&other.real)
33 }
34}
35
36impl PartialOrd<Dual2> for f64 {
37 fn partial_cmp(&self, other: &Dual2) -> Option<Ordering> {
38 self.partial_cmp(&other.real)
39 }
40}
41
42impl PartialOrd<Number> for Number {
43 fn partial_cmp(&self, other: &Number) -> Option<Ordering> {
44 match (self, other) {
45 (Number::F64(f), Number::F64(f2)) => f.partial_cmp(f2),
46 (Number::F64(f), Number::Dual(d2)) => f.partial_cmp(d2),
47 (Number::F64(f), Number::Dual2(d2)) => f.partial_cmp(d2),
48 (Number::Dual(d), Number::F64(f2)) => d.partial_cmp(f2),
49 (Number::Dual(d), Number::Dual(d2)) => d.partial_cmp(d2),
50 (Number::Dual(_), Number::Dual2(_)) => {
51 panic!("Cannot mix dual types: Dual compare Dual2")
52 }
53 (Number::Dual2(d), Number::F64(f2)) => d.partial_cmp(f2),
54 (Number::Dual2(_), Number::Dual(_)) => {
55 panic!("Cannot mix dual types: Dual2 compare Dual")
56 }
57 (Number::Dual2(d), Number::Dual2(d2)) => d.partial_cmp(d2),
58 }
59 }
60}
61
62impl PartialOrd<f64> for Number {
63 fn partial_cmp(&self, other: &f64) -> Option<Ordering> {
64 match self {
65 Number::F64(f) => f.partial_cmp(other),
66 Number::Dual(d) => d.partial_cmp(other),
67 Number::Dual2(d) => d.partial_cmp(other),
68 }
69 }
70}
71
72impl PartialOrd<Number> for f64 {
73 fn partial_cmp(&self, other: &Number) -> Option<Ordering> {
74 match other {
75 Number::F64(f) => self.partial_cmp(f),
76 Number::Dual(d) => self.partial_cmp(d),
77 Number::Dual2(d) => self.partial_cmp(d),
78 }
79 }
80}
81
82#[cfg(test)]
83mod tests {
84 use super::*;
85
86 #[test]
87 fn ord() {
88 let d1 = Dual::try_new(
89 1.0,
90 vec!["v0".to_string(), "v1".to_string()],
91 vec![1.0, 2.0],
92 )
93 .unwrap();
94 assert!(d1 < 2.0);
95 assert!(d1 > 0.5);
96 assert!(d1 <= 1.0);
97 assert!(d1 >= 1.0);
98 assert!(1.0 <= d1);
99 assert!(1.0 >= d1);
100 assert!(2.0 > d1);
101 assert!(0.5 < d1);
102 let d2 = Dual::try_new(
103 2.0,
104 vec!["v0".to_string(), "v2".to_string()],
105 vec![1.0, 2.0],
106 )
107 .unwrap();
108 assert!(d2 > d1);
109 assert!(d1 < d2);
110 let d3 = Dual::try_new(1.0, vec!["v3".to_string()], vec![10.0]).unwrap();
111 assert!(d1 >= d3);
112 assert!(d1 <= d3);
113 }
114
115 #[test]
116 fn ord2() {
117 let d1 = Dual2::try_new(
118 1.0,
119 vec!["v0".to_string(), "v1".to_string()],
120 vec![1.0, 2.0],
121 Vec::new(),
122 )
123 .unwrap();
124 assert!(d1 < 2.0);
125 assert!(d1 > 0.5);
126 assert!(d1 <= 1.0);
127 assert!(d1 >= 1.0);
128 assert!(1.0 <= d1);
129 assert!(1.0 >= d1);
130 assert!(2.0 > d1);
131 assert!(0.5 < d1);
132 let d2 = Dual2::try_new(
133 2.0,
134 vec!["v0".to_string(), "v2".to_string()],
135 vec![1.0, 2.0],
136 Vec::new(),
137 )
138 .unwrap();
139 assert!(d2 > d1);
140 assert!(d1 < d2);
141 let d3 = Dual2::try_new(1.0, vec!["v3".to_string()], vec![10.0], Vec::new()).unwrap();
142 assert!(d1 >= d3);
143 assert!(d1 <= d3);
144 }
145
146 #[test]
147 fn test_enum() {
148 let d = Number::Dual(Dual::new(2.0, vec!["x".to_string()]));
149 let d2 = Number::Dual(Dual::new(3.0, vec!["x".to_string()]));
150 assert!(d <= d2)
151 }
152
153 #[test]
154 fn test_cross_enum_eq() {
155 let f = Number::F64(2.5_f64);
156 let d = Number::Dual(Dual::new(3.5_f64, vec![]));
157 assert!(f <= d);
158 }
159
160 #[test]
161 #[should_panic]
162 fn test_cross_enum_eq_error() {
163 let d2 = Number::Dual2(Dual2::new(2.5_f64, vec![]));
164 let d = Number::Dual(Dual::new(2.5_f64, vec![]));
165 assert!(d <= d2);
166 }
167
168 #[test]
169 fn test_cross_enum_f64() {
170 let d2 = Number::Dual2(Dual2::new(2.5_f64, vec![]));
171 assert!(d2 <= 3.0_f64);
172 }
173}