rateslib/dual/dual_ops/
from.rs

1use crate::dual::dual::{Dual, Dual2};
2use crate::dual::enums::Number;
3use ndarray::{Array2, Axis};
4
5impl From<Dual> for f64 {
6    fn from(value: Dual) -> Self {
7        value.real
8    }
9}
10
11impl From<Dual2> for f64 {
12    fn from(value: Dual2) -> Self {
13        value.real
14    }
15}
16
17impl From<&Dual> for f64 {
18    fn from(value: &Dual) -> Self {
19        value.real
20    }
21}
22
23impl From<&Dual2> for f64 {
24    fn from(value: &Dual2) -> Self {
25        value.real
26    }
27}
28
29impl From<f64> for Dual {
30    fn from(value: f64) -> Self {
31        Self::new(value, vec![])
32    }
33}
34
35// impl From<Dual> for Dual {
36//     fn from(value: Dual) -> Self {
37//         value.clone()
38//     }
39// }
40
41impl From<Dual2> for Dual {
42    fn from(value: Dual2) -> Self {
43        Dual {
44            real: value.real,
45            vars: value.vars.clone(),
46            dual: value.dual,
47        }
48    }
49}
50
51impl From<&Dual2> for Dual {
52    fn from(value: &Dual2) -> Self {
53        Dual {
54            real: value.real,
55            vars: value.vars.clone(),
56            dual: value.dual.clone(),
57        }
58    }
59}
60
61impl From<f64> for Dual2 {
62    fn from(value: f64) -> Self {
63        Self::new(value, vec![])
64    }
65}
66
67impl From<Dual> for Dual2 {
68    fn from(value: Dual) -> Self {
69        let n = value.dual.len_of(Axis(0));
70        Dual2 {
71            real: value.real,
72            vars: value.vars.clone(),
73            dual: value.dual,
74            dual2: Array2::zeros((n, n)),
75        }
76    }
77}
78
79impl From<&Dual> for Dual2 {
80    fn from(value: &Dual) -> Self {
81        let n = value.dual.len_of(Axis(0));
82        Dual2 {
83            real: value.real,
84            vars: value.vars.clone(),
85            dual: value.dual.clone(),
86            dual2: Array2::zeros((n, n)),
87        }
88    }
89}
90
91impl From<Number> for f64 {
92    fn from(value: Number) -> Self {
93        match value {
94            Number::F64(f) => f,
95            Number::Dual(d) => d.real,
96            Number::Dual2(d) => d.real,
97        }
98    }
99}
100
101impl From<Number> for Dual {
102    fn from(value: Number) -> Self {
103        match value {
104            Number::F64(f) => Dual::new(f, vec![]),
105            Number::Dual(d) => d,
106            Number::Dual2(d) => Dual::from(d),
107        }
108    }
109}
110
111impl From<Number> for Dual2 {
112    fn from(value: Number) -> Self {
113        match value {
114            Number::F64(f) => Dual2::new(f, vec![]),
115            Number::Dual(d) => Dual2::from(d),
116            Number::Dual2(d) => d,
117        }
118    }
119}
120
121impl From<&Number> for f64 {
122    fn from(value: &Number) -> Self {
123        match value {
124            Number::F64(f) => *f,
125            Number::Dual(d) => d.real,
126            Number::Dual2(d) => d.real,
127        }
128    }
129}
130
131impl From<&Number> for Dual {
132    fn from(value: &Number) -> Self {
133        match value {
134            Number::F64(f) => Dual::new(*f, vec![]),
135            Number::Dual(d) => d.clone(),
136            Number::Dual2(d) => Dual::from(d),
137        }
138    }
139}
140
141impl From<&Number> for Dual2 {
142    fn from(value: &Number) -> Self {
143        match value {
144            Number::F64(f) => Dual2::new(*f, vec![]),
145            Number::Dual(d) => Dual2::from(d),
146            Number::Dual2(d) => d.clone(),
147        }
148    }
149}
150
151impl From<&f64> for Number {
152    fn from(value: &f64) -> Self {
153        Number::F64(*value)
154    }
155}
156
157impl From<f64> for Number {
158    fn from(value: f64) -> Self {
159        Number::F64(value)
160    }
161}
162
163impl From<&Dual> for Number {
164    fn from(value: &Dual) -> Self {
165        Number::Dual(value.clone())
166    }
167}
168
169impl From<Dual> for Number {
170    fn from(value: Dual) -> Self {
171        Number::Dual(value)
172    }
173}
174
175impl From<&Dual2> for Number {
176    fn from(value: &Dual2) -> Self {
177        Number::Dual2(value.clone())
178    }
179}
180
181impl From<Dual2> for Number {
182    fn from(value: Dual2) -> Self {
183        Number::Dual2(value)
184    }
185}
186
187#[cfg(test)]
188mod tests {
189    use super::*;
190
191    #[test]
192    fn from_dual_into_dual2() {
193        let d1 = Dual::new(2.5, vec!["x".to_string(), "y".to_string()]);
194        let d2: Dual2 = d1.into();
195        let result = Dual2::new(2.5, vec!["x".to_string(), "y".to_string()]);
196        assert_eq!(d2, result);
197    }
198
199    #[test]
200    fn from_dual_into_f64() {
201        let d1 = Dual::new(2.5, vec!["x".to_string(), "y".to_string()]);
202        let d2: f64 = d1.into();
203        let result = 2.5_f64;
204        assert_eq!(d2, result);
205    }
206
207    // #[test]
208    // fn from_dual_to_dual_unchanged() {
209    //     let d1 = Dual::new(2.5, vec!["x".to_string(), "y".to_string()]);
210    //     let d2: Dual = Dual::from(d1);
211    //     assert_eq!(d2, d1);
212    // }
213
214    #[test]
215    fn from_f64_into_dual() {
216        let d = Dual::from(4.0_f64);
217        assert_eq!(d, Dual::new(4.0_f64, vec![]));
218    }
219
220    #[test]
221    fn from_dual2_into_dual() {
222        let d2: Dual2 = Dual2::new(2.0, vec!["x".to_string(), "y".to_string()]);
223        let d1: Dual = d2.into();
224        let result = Dual::new(2.0, vec!["x".to_string(), "y".to_string()]);
225        assert_eq!(d1, result);
226    }
227}