1 use num::{Bounded, Signed}; 2 use std::{f32, f64}; 3 4 use approx::{RelativeEq, UlpsEq}; 5 6 use crate::general::{ComplexField, Lattice}; 7 8 #[cfg(not(feature = "std"))] 9 use num::Float; 10 //#[cfg(feature = "decimal")] 11 //use decimal::d128; 12 13 #[allow(missing_docs)] 14 15 /// Trait shared by all reals. 16 /// 17 /// Reals are equipped with functions that are commonly used on reals. The results of those 18 /// functions only have to be approximately equal to the actual theoretical values. 19 // FIXME: SubsetOf should be removed when specialization will be supported by rustc. This will 20 // allow a blanket impl: impl<T: Clone> SubsetOf<T> for T { ... } 21 // NOTE: make all types debuggable/'static/Any ? This seems essential for any kind of generic programming. 22 pub trait RealField: 23 ComplexField<RealField = Self> 24 + RelativeEq<Epsilon = Self> 25 + UlpsEq<Epsilon = Self> 26 + Lattice 27 + Signed 28 + Bounded 29 { 30 // NOTE: a real must be bounded because, no matter the chosen representation, being `Copy` implies that it occupies a statically-known size, meaning that it must have min/max values. 31 is_sign_positive(self) -> bool32 fn is_sign_positive(self) -> bool; is_sign_negative(self) -> bool33 fn is_sign_negative(self) -> bool; max(self, other: Self) -> Self34 fn max(self, other: Self) -> Self; min(self, other: Self) -> Self35 fn min(self, other: Self) -> Self; atan2(self, other: Self) -> Self36 fn atan2(self, other: Self) -> Self; 37 pi() -> Self38 fn pi() -> Self; two_pi() -> Self39 fn two_pi() -> Self; frac_pi_2() -> Self40 fn frac_pi_2() -> Self; frac_pi_3() -> Self41 fn frac_pi_3() -> Self; frac_pi_4() -> Self42 fn frac_pi_4() -> Self; frac_pi_6() -> Self43 fn frac_pi_6() -> Self; frac_pi_8() -> Self44 fn frac_pi_8() -> Self; frac_1_pi() -> Self45 fn frac_1_pi() -> Self; frac_2_pi() -> Self46 fn frac_2_pi() -> Self; frac_2_sqrt_pi() -> Self47 fn frac_2_sqrt_pi() -> Self; 48 e() -> Self49 fn e() -> Self; log2_e() -> Self50 fn log2_e() -> Self; log10_e() -> Self51 fn log10_e() -> Self; ln_2() -> Self52 fn ln_2() -> Self; ln_10() -> Self53 fn ln_10() -> Self; 54 } 55 56 macro_rules! impl_real( 57 ($($T:ty, $M:ident, $libm: ident);*) => ($( 58 impl RealField for $T { 59 #[inline] 60 fn is_sign_positive(self) -> bool { 61 $M::is_sign_positive(self) 62 } 63 64 #[inline] 65 fn is_sign_negative(self) -> bool { 66 $M::is_sign_negative(self) 67 } 68 69 #[inline] 70 fn max(self, other: Self) -> Self { 71 $M::max(self, other) 72 } 73 74 #[inline] 75 fn min(self, other: Self) -> Self { 76 $M::min(self, other) 77 } 78 79 #[inline] 80 fn atan2(self, other: Self) -> Self { 81 $libm::atan2(self, other) 82 } 83 84 /// Archimedes' constant. 85 #[inline] 86 fn pi() -> Self { 87 $M::consts::PI 88 } 89 90 /// 2.0 * pi. 91 #[inline] 92 fn two_pi() -> Self { 93 $M::consts::PI + $M::consts::PI 94 } 95 96 /// pi / 2.0. 97 #[inline] 98 fn frac_pi_2() -> Self { 99 $M::consts::FRAC_PI_2 100 } 101 102 /// pi / 3.0. 103 #[inline] 104 fn frac_pi_3() -> Self { 105 $M::consts::FRAC_PI_3 106 } 107 108 /// pi / 4.0. 109 #[inline] 110 fn frac_pi_4() -> Self { 111 $M::consts::FRAC_PI_4 112 } 113 114 /// pi / 6.0. 115 #[inline] 116 fn frac_pi_6() -> Self { 117 $M::consts::FRAC_PI_6 118 } 119 120 /// pi / 8.0. 121 #[inline] 122 fn frac_pi_8() -> Self { 123 $M::consts::FRAC_PI_8 124 } 125 126 /// 1.0 / pi. 127 #[inline] 128 fn frac_1_pi() -> Self { 129 $M::consts::FRAC_1_PI 130 } 131 132 /// 2.0 / pi. 133 #[inline] 134 fn frac_2_pi() -> Self { 135 $M::consts::FRAC_2_PI 136 } 137 138 /// 2.0 / sqrt(pi). 139 #[inline] 140 fn frac_2_sqrt_pi() -> Self { 141 $M::consts::FRAC_2_SQRT_PI 142 } 143 144 145 /// Euler's number. 146 #[inline] 147 fn e() -> Self { 148 $M::consts::E 149 } 150 151 /// log2(e). 152 #[inline] 153 fn log2_e() -> Self { 154 $M::consts::LOG2_E 155 } 156 157 /// log10(e). 158 #[inline] 159 fn log10_e() -> Self { 160 $M::consts::LOG10_E 161 } 162 163 /// ln(2.0). 164 #[inline] 165 fn ln_2() -> Self { 166 $M::consts::LN_2 167 } 168 169 /// ln(10.0). 170 #[inline] 171 fn ln_10() -> Self { 172 $M::consts::LN_10 173 } 174 } 175 )*) 176 ); 177 178 #[cfg(not(feature = "std"))] 179 impl_real!(f32,f32,Float; f64,f64,Float); 180 #[cfg(feature = "std")] 181 impl_real!(f32,f32,f32; f64,f64,f64); 182 //#[cfg(feature = "decimal")] 183 //impl_real!(d128, d128, d128); 184