ospf_rust_math/algebra/concept/
scalar.rs1use num::complex::ComplexFloat;
2
3use super::{
4 Arithmetic, Bits, Bounded, Invariant, NumberField, PlusSemiGroup, Precision, Signed,
5 TimesGroup, Unsigned,
6};
7
8pub trait Scalar: Arithmetic + Bounded {}
9
10impl<T: Arithmetic + Bounded> Scalar for T {}
11
12pub enum RealNumberCategory {
13 Nan,
14 Infinite,
15 NegativeInfinite,
16 Zero,
17 Subnormal,
18 Normal,
19}
20
21pub trait RealNumber: Scalar + Precision + Invariant {
22 const TWO: &'static Self;
23 const THREE: &'static Self;
24 const FIVE: &'static Self;
25 const TEN: &'static Self;
26
27 const NAN: &'static Option<Self> = &None;
28 const INF: &'static Option<Self> = &None;
29 const NEG_INF: &'static Option<Self> = &None;
30
31 fn is_nan(&self) -> bool {
34 Self::NAN
35 .as_ref()
36 .is_some_and(|nan_value| self == nan_value)
37 }
38
39 fn is_inf(&self) -> bool {
40 Self::INF
41 .as_ref()
42 .is_some_and(|inf_value| self == inf_value)
43 }
44
45 fn is_neg_inf(&self) -> bool {
46 Self::NEG_INF
47 .as_ref()
48 .is_some_and(|inf_value| self == inf_value)
49 }
50
51 fn is_finite(&self) -> bool {
52 !self.is_inf() && !self.is_inf() && !self.is_neg_inf()
53 }
54}
55
56pub trait Integer: RealNumber + Bits + Ord + Eq {}
57
58impl<T: RealNumber + Bits + Ord + Eq> Integer for T {}
59
60pub trait IntegerNumber: Integer + NumberField + Signed {}
61
62impl<T: Integer + NumberField + Signed> IntegerNumber for T {}
63
64pub trait UIntegerNumber: Integer + PlusSemiGroup + TimesGroup + Unsigned {}
65
66impl<T: Integer + PlusSemiGroup + TimesGroup + Unsigned> UIntegerNumber for T {}
67
68pub trait RationalNumber<I: Integer>: RealNumber + NumberField + Ord + Eq {
69 fn num(&self) -> &I;
70 fn den(&self) -> &I;
71}
72
73pub trait FloatingNumber: RealNumber + NumberField + Signed {
74 const PI: &'static Self;
75 const E: &'static Self;
76
77 fn floor(&self) -> Self;
78 fn ceil(&self) -> Self;
79 fn round(&self) -> Self;
80 fn trunc(&self) -> Self;
81 fn fract(&self) -> Self;
82}
83
84pub trait NumericIntegerNumber<I: IntegerNumber>: Integer + Signed + Ord + Eq {}
85
86pub trait NumericUIntegerNumber<I: UIntegerNumber>: Integer + Unsigned + Ord + Eq {}
87
88macro_rules! int_real_number_template {
89 ($($type:ident)*) => ($(
90 impl RealNumber for $type {
91 const TWO: &'static Self = &2;
92 const THREE: &'static Self = &3;
93 const FIVE: &'static Self = &5;
94 const TEN: &'static Self = &10;
95 }
96 )*)
97}
98int_real_number_template! { i8 i16 i32 i64 i128 isize }
99
100macro_rules! uint_real_number_template {
101 ($($type:ident)*) => ($(
102 impl RealNumber for $type {
103 const TWO: &'static Self = &2;
104 const THREE: &'static Self = &3;
105 const FIVE: &'static Self = &5;
106 const TEN: &'static Self = &10;
107 }
108 )*)
109}
110uint_real_number_template! { u8 u16 u32 u64 u128 usize }
111
112macro_rules! floating_real_number_template {
113 ($($type:ident)*) => ($(
114 impl RealNumber for $type {
115 const TWO: &'static Self = &2.;
116 const THREE: &'static Self = &3.;
117 const FIVE: &'static Self = &5.;
118 const TEN: &'static Self = &10.;
119
120 const NAN: &'static Option<Self> = &Some(<$type>::NAN);
121 const INF: &'static Option<Self> = &Some(<$type>::INFINITY);
122 const NEG_INF: &'static Option<Self> = &Some(<$type>::NEG_INFINITY);
123
124 fn is_nan(&self) -> bool {
125 <$type>::is_nan(*self)
126 }
127
128 fn is_inf(&self) -> bool {
129 <$type>::is_infinite(*self) && <$type>::is_sign_positive(*self)
130 }
131
132 fn is_neg_inf(&self) -> bool {
133 <$type>::is_infinite(*self) && <$type>::is_sign_negative(*self)
134 }
135 }
136
137 impl FloatingNumber for $type {
138 const PI: &'static Self = &std::$type::consts::PI;
139 const E: &'static Self = &std::$type::consts::E;
140
141 fn floor(&self) -> Self {
142 <$type>::floor(*self)
143 }
144
145 fn ceil(&self) -> Self {
146 <$type>::ceil(*self)
147 }
148
149 fn round(&self) -> Self {
150 <$type>::round(*self)
151 }
152
153 fn trunc(&self) -> Self {
154 <$type>::trunc(*self)
155 }
156
157 fn fract(&self) -> Self {
158 <$type>::fract(*self)
159 }
160 }
161 )*)
162}
163floating_real_number_template! { f32 f64 }