rustiq_core/structures/
parameter.rs1use 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}