Skip to main content

geop_core_math/scalars/
number.rs

1//! What a residual of the constraint solvers is written in.
2
3use core::fmt::{Debug, Display};
4
5use super::Scalar;
6use crate::geop_error::GeopResult;
7
8/// A number a residual computes with: a [`Scalar`], giving the residual's
9/// value, or a [`crate::dual::Dual`] of one, giving its value and its
10/// derivatives by the variables it depends on. Every residual is written
11/// once, over `T: Number`, and evaluated with either. The comparisons act
12/// on the value alone.
13pub trait Number: Copy + Clone + Debug + Display + Default + Send + Sync + 'static {
14    const ZERO: Self;
15    const ONE: Self;
16    const TWO: Self;
17    const PI: Self;
18
19    fn from_i64(v: i64) -> Self;
20    fn from_f64(v: f64) -> Self;
21    /// The scalar `s` as a constant: depending on no variable.
22    fn from_scalar(s: Scalar) -> Self;
23    fn from_ratio(num: i64, den: i64) -> GeopResult<Self>;
24    /// The value's midpoint, for rendering and debugging.
25    fn to_f64(self) -> f64;
26
27    fn add(self, other: Self) -> Self;
28    fn sub(self, other: Self) -> Self;
29    fn mul(self, other: Self) -> Self;
30    fn neg(self) -> Self;
31    /// Fails where the divisor could be zero.
32    fn div(self, other: Self) -> GeopResult<Self>;
33
34    fn abs(self) -> Self;
35    fn sqrt(self) -> GeopResult<Self>;
36    fn sin(self) -> Self;
37    fn cos(self) -> Self;
38    fn acos(self) -> GeopResult<Self>;
39
40    /// The angle `self`, given in degrees, in radians.
41    fn degrees_to_radians(self) -> GeopResult<Self> {
42        self.mul(Self::PI).div(Self::from_i64(180))
43    }
44
45    fn could_be_equal(self, other: Self) -> bool;
46    fn definitely_not_equal(self, other: Self) -> bool;
47    fn could_be_greater(self, other: Self) -> bool;
48    fn definitely_greater(self, other: Self) -> bool;
49    fn could_be_less(self, other: Self) -> bool;
50    fn definitely_less(self, other: Self) -> bool;
51
52    /// Whether it is a single, exactly known point: a value that depends
53    /// on no variable, and carries no width.
54    fn is_sharp(self) -> bool;
55    /// Whether its value is exactly `other`'s, as a set (see
56    /// [`Scalar::is_exactly`]).
57    fn is_exactly(self, other: Self) -> bool;
58    /// The smallest value containing both (see [`Scalar::union`]).
59    fn union(self, other: Self) -> Self;
60}
61
62impl Number for Scalar {
63    const ZERO: Self = Scalar::ZERO;
64    const ONE: Self = Scalar::ONE;
65    const TWO: Self = Scalar::TWO;
66    const PI: Self = Scalar::PI;
67
68    fn from_i64(v: i64) -> Self {
69        Scalar::from_i64(v)
70    }
71    fn from_f64(v: f64) -> Self {
72        Scalar::from_f64(v)
73    }
74    fn from_scalar(s: Scalar) -> Self {
75        s
76    }
77    fn from_ratio(num: i64, den: i64) -> GeopResult<Self> {
78        Scalar::from_ratio(num, den)
79    }
80    fn to_f64(self) -> f64 {
81        Scalar::to_f64(self)
82    }
83
84    fn add(self, other: Self) -> Self {
85        Scalar::add(self, other)
86    }
87    fn sub(self, other: Self) -> Self {
88        Scalar::sub(self, other)
89    }
90    fn mul(self, other: Self) -> Self {
91        Scalar::mul(self, other)
92    }
93    fn neg(self) -> Self {
94        Scalar::neg(self)
95    }
96    fn div(self, other: Self) -> GeopResult<Self> {
97        Scalar::div(self, other)
98    }
99
100    fn abs(self) -> Self {
101        Scalar::abs(self)
102    }
103    fn sqrt(self) -> GeopResult<Self> {
104        Scalar::sqrt(self)
105    }
106    fn sin(self) -> Self {
107        Scalar::sin(self)
108    }
109    fn cos(self) -> Self {
110        Scalar::cos(self)
111    }
112    fn acos(self) -> GeopResult<Self> {
113        Scalar::acos(self)
114    }
115    fn degrees_to_radians(self) -> GeopResult<Self> {
116        Scalar::degrees_to_radians(self)
117    }
118
119    fn could_be_equal(self, other: Self) -> bool {
120        Scalar::could_be_equal(self, other)
121    }
122    fn definitely_not_equal(self, other: Self) -> bool {
123        Scalar::definitely_not_equal(self, other)
124    }
125    fn could_be_greater(self, other: Self) -> bool {
126        Scalar::could_be_greater(self, other)
127    }
128    fn definitely_greater(self, other: Self) -> bool {
129        Scalar::definitely_greater(self, other)
130    }
131    fn could_be_less(self, other: Self) -> bool {
132        Scalar::could_be_less(self, other)
133    }
134    fn definitely_less(self, other: Self) -> bool {
135        Scalar::definitely_less(self, other)
136    }
137
138    fn is_sharp(self) -> bool {
139        Scalar::is_sharp(self)
140    }
141    fn is_exactly(self, other: Self) -> bool {
142        Scalar::is_exactly(self, other)
143    }
144    fn union(self, other: Self) -> Self {
145        Scalar::union(self, other)
146    }
147}