rustiq_core/structures/
parameter.rs

1use std::ops;
2
3#[derive(Clone, Debug, PartialEq)]
4pub enum Parameter {
5    Abstract(String),
6    Concrete(f64),
7}
8
9impl std::fmt::Display for Parameter {
10    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
11        match self {
12            Self::Abstract(x) => f.write_str(x.as_str()),
13            Self::Concrete(x) => f.write_str(x.to_string().as_str()),
14        }
15    }
16}
17
18impl Parameter {
19    pub fn zero() -> Self {
20        Self::Concrete(0.0)
21    }
22    pub fn is_zero(&self) -> bool {
23        match self {
24            Self::Abstract(_) => false,
25            Self::Concrete(x) => x.abs() < 1e-6,
26        }
27    }
28    pub fn flip_sign(&mut self) {
29        match self {
30            Self::Abstract(s) => *s = "(-".to_owned() + s + ")",
31            Self::Concrete(x) => *x *= -1.,
32        }
33    }
34    pub fn simplify(&self) -> (Self, i32) {
35        match self {
36            Self::Abstract(_) => (self.clone(), 0),
37            Self::Concrete(x) => {
38                let y = x % (2. * std::f64::consts::PI);
39                let k = y.div_euclid(std::f64::consts::PI / 2.);
40                let rem = y % (std::f64::consts::PI / 2.);
41                (Self::Concrete(rem), k as i32)
42            }
43        }
44    }
45    pub fn is_zero_mod_two_pi(&self) -> bool {
46        match self {
47            Self::Abstract(_) => false,
48            Self::Concrete(x) => (x % (2. * std::f64::consts::PI)).abs() < 1e-6,
49        }
50    }
51    pub fn from_string(expr: String) -> Self {
52        let as_f64 = expr.parse::<f64>();
53        match as_f64 {
54            Ok(x) => Self::Concrete(x),
55            _ => Self::Abstract(expr),
56        }
57    }
58    pub fn to_abstract(&self) -> Self {
59        match self {
60            Self::Abstract(x) => Self::Abstract(x.clone()),
61            Self::Concrete(x) => Self::Abstract(x.to_string()),
62        }
63    }
64}
65impl ops::Add<Parameter> for Parameter {
66    type Output = Parameter;
67
68    fn add(self, _rhs: Parameter) -> Parameter {
69        match (&self, &_rhs) {
70            (Self::Concrete(v1), Self::Concrete(v2)) => {
71                Self::Concrete((v1 + v2) % (2. * std::f64::consts::PI))
72            }
73            _ => {
74                let mut new_expr = self.to_string();
75                new_expr.push('+');
76                new_expr.push_str(&_rhs.to_string());
77                Self::Abstract(new_expr)
78            }
79        }
80    }
81}
82impl ops::AddAssign<Parameter> for Parameter {
83    fn add_assign(&mut self, _rhs: Self) {
84        match (&self, &_rhs) {
85            (Self::Concrete(v1), Self::Concrete(v2)) => {
86                *self = Self::Concrete((v1 + v2) % (2. * std::f64::consts::PI));
87            }
88            _ => {
89                let mut new_expr = self.to_string();
90                new_expr.push('+');
91                new_expr.push_str(&_rhs.to_string());
92                *self = Self::Abstract(new_expr);
93            }
94        }
95    }
96}