oxiblas_core/scalar/traits.rs
1//! Core scalar trait definitions: Scalar, Real, ComplexScalar, and Field.
2
3use core::fmt::{Debug, Display};
4use core::iter::Sum;
5use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
6use num_traits::{FromPrimitive, NumAssign, One, Zero};
7
8/// Base trait for all scalar types used in OxiBLAS.
9///
10/// This trait provides the fundamental requirements for any numeric type
11/// that can be used in matrix operations.
12pub trait Scalar:
13 Copy
14 + Clone
15 + Debug
16 + Display
17 + Default
18 + Send
19 + Sync
20 + PartialEq
21 + Zero
22 + One
23 + Add<Output = Self>
24 + Sub<Output = Self>
25 + Mul<Output = Self>
26 + Div<Output = Self>
27 + AddAssign
28 + SubAssign
29 + MulAssign
30 + DivAssign
31 + Neg<Output = Self>
32 + Sum
33 + NumAssign
34 + FromPrimitive
35 + 'static
36{
37 /// The real component type (for complex numbers, this is the component type).
38 type Real: Real;
39
40 /// Returns the absolute value (modulus for complex numbers).
41 fn abs(self) -> Self::Real;
42
43 /// Returns the complex conjugate. For real numbers, returns self.
44 fn conj(self) -> Self;
45
46 /// Returns true if this is a real type (not complex).
47 fn is_real() -> bool;
48
49 /// Returns the real part.
50 fn real(self) -> Self::Real;
51
52 /// Returns the imaginary part (zero for real types).
53 fn imag(self) -> Self::Real;
54
55 /// Creates a scalar from real and imaginary parts.
56 fn from_real_imag(re: Self::Real, im: Self::Real) -> Self;
57
58 /// Creates a scalar from just the real part (imaginary = 0).
59 fn from_real(re: Self::Real) -> Self {
60 Self::from_real_imag(re, Self::Real::zero())
61 }
62
63 /// Square of the absolute value (more efficient than abs().powi(2)).
64 fn abs_sq(self) -> Self::Real {
65 let re = self.real();
66 let im = self.imag();
67 re * re + im * im
68 }
69
70 /// Machine epsilon for this type.
71 fn epsilon() -> Self::Real;
72
73 /// Smallest positive normal value.
74 fn min_positive() -> Self::Real;
75
76 /// Largest finite value.
77 fn max_value() -> Self::Real;
78
79 /// Size of the type in bytes.
80 const SIZE: usize = core::mem::size_of::<Self>();
81
82 /// Alignment requirement.
83 const ALIGN: usize = core::mem::align_of::<Self>();
84}
85
86/// Trait for real number types (f32, f64).
87pub trait Real: Scalar<Real = Self> + num_traits::Float + PartialOrd {
88 /// Square root.
89 fn sqrt(self) -> Self;
90
91 /// Natural logarithm.
92 fn ln(self) -> Self;
93
94 /// Exponential function.
95 fn exp(self) -> Self;
96
97 /// Sine.
98 fn sin(self) -> Self;
99
100 /// Cosine.
101 fn cos(self) -> Self;
102
103 /// Arctangent of y/x with correct quadrant.
104 fn atan2(self, other: Self) -> Self;
105
106 /// Power function.
107 fn powf(self, n: Self) -> Self;
108
109 /// Sign function: 1.0 if positive, -1.0 if negative, 0.0 if zero.
110 fn signum(self) -> Self;
111
112 /// Fused multiply-add: self * a + b
113 fn mul_add(self, a: Self, b: Self) -> Self;
114
115 /// Floor function.
116 fn floor(self) -> Self;
117
118 /// Ceiling function.
119 fn ceil(self) -> Self;
120
121 /// Round to nearest integer.
122 fn round(self) -> Self;
123
124 /// Truncate toward zero.
125 fn trunc(self) -> Self;
126
127 /// Safe reciprocal (returns None if self is zero or would overflow).
128 fn safe_recip(self) -> Option<Self> {
129 if Scalar::abs(self) < Self::min_positive() {
130 None
131 } else {
132 Some(Self::one() / self)
133 }
134 }
135
136 /// Hypot: sqrt(self^2 + other^2) computed without overflow.
137 fn hypot(self, other: Self) -> Self;
138}
139
140/// Trait for complex scalar types.
141pub trait ComplexScalar: Scalar {
142 /// Creates a complex number from real and imaginary parts.
143 fn new(re: Self::Real, im: Self::Real) -> Self;
144
145 /// Returns the argument (phase angle) of the complex number.
146 fn arg(self) -> Self::Real;
147
148 /// Returns the polar form (r, theta) where self = r * e^(i*theta).
149 fn to_polar(self) -> (Self::Real, Self::Real) {
150 (self.abs(), self.arg())
151 }
152
153 /// Creates a complex number from polar form.
154 fn from_polar(r: Self::Real, theta: Self::Real) -> Self;
155
156 /// Complex exponential.
157 fn cexp(self) -> Self;
158
159 /// Complex logarithm (principal branch).
160 fn cln(self) -> Self;
161
162 /// Complex square root (principal branch).
163 fn csqrt(self) -> Self;
164}
165
166/// Field trait - complete algebraic structure with all operations.
167///
168/// This is the main trait used throughout OxiBLAS for generic programming
169/// over numeric types.
170pub trait Field: Scalar {
171 /// Computes self * alpha + other * beta
172 #[inline]
173 fn scale_add(self, alpha: Self, other: Self, beta: Self) -> Self {
174 self * alpha + other * beta
175 }
176
177 /// Computes self * conj(other) for complex, self * other for real.
178 fn mul_conj(self, other: Self) -> Self;
179
180 /// Computes conj(self) * other for complex, self * other for real.
181 fn conj_mul(self, other: Self) -> Self;
182
183 /// Reciprocal (1/self).
184 fn recip(self) -> Self;
185
186 /// Integer power.
187 fn powi(self, n: i32) -> Self;
188}