1#![warn(missing_debug_implementations, missing_docs)]
9#![cfg_attr(docsrs, feature(doc_cfg))]
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
13pub enum Layout {
14 RowMajor,
16 ColMajor,
18}
19
20#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
23pub enum Trans {
24 No,
26 T,
28 C,
30}
31
32#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
34pub enum Uplo {
35 Upper,
37 Lower,
39}
40
41#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
43pub enum Diag {
44 NonUnit,
46 Unit,
48}
49
50#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
52pub enum Side {
53 Left,
55 Right,
57}
58
59#[repr(C)]
63#[derive(Debug, Clone, Copy, PartialEq)]
64pub struct Complex32 {
65 pub re: f32,
67 pub im: f32,
69}
70
71impl Complex32 {
72 #[inline]
74 pub const fn new(re: f32, im: f32) -> Self {
75 Self { re, im }
76 }
77
78 pub const ZERO: Self = Self::new(0.0, 0.0);
80 pub const ONE: Self = Self::new(1.0, 0.0);
82 pub const I: Self = Self::new(0.0, 1.0);
84
85 #[inline]
87 pub fn norm_sqr(&self) -> f32 {
88 self.re * self.re + self.im * self.im
89 }
90
91 #[inline]
93 pub fn abs(&self) -> f32 {
94 self.norm_sqr().sqrt()
95 }
96
97 #[inline]
99 pub fn conj(&self) -> Self {
100 Self::new(self.re, -self.im)
101 }
102}
103
104impl From<(f32, f32)> for Complex32 {
105 #[inline]
106 fn from((re, im): (f32, f32)) -> Self {
107 Self::new(re, im)
108 }
109}
110
111impl From<[f32; 2]> for Complex32 {
112 #[inline]
113 fn from(a: [f32; 2]) -> Self {
114 Self::new(a[0], a[1])
115 }
116}
117
118impl From<Complex32> for [f32; 2] {
119 #[inline]
120 fn from(c: Complex32) -> Self {
121 [c.re, c.im]
122 }
123}
124
125impl From<f32> for Complex32 {
126 #[inline]
127 fn from(re: f32) -> Self {
128 Self::new(re, 0.0)
129 }
130}
131
132#[repr(C)]
136#[derive(Debug, Clone, Copy, PartialEq)]
137pub struct Complex64 {
138 pub re: f64,
140 pub im: f64,
142}
143
144impl Complex64 {
145 #[inline]
147 pub const fn new(re: f64, im: f64) -> Self {
148 Self { re, im }
149 }
150
151 pub const ZERO: Self = Self::new(0.0, 0.0);
153 pub const ONE: Self = Self::new(1.0, 0.0);
155 pub const I: Self = Self::new(0.0, 1.0);
157
158 #[inline]
160 pub fn norm_sqr(&self) -> f64 {
161 self.re * self.re + self.im * self.im
162 }
163
164 #[inline]
166 pub fn abs(&self) -> f64 {
167 self.norm_sqr().sqrt()
168 }
169
170 #[inline]
172 pub fn conj(&self) -> Self {
173 Self::new(self.re, -self.im)
174 }
175}
176
177impl From<(f64, f64)> for Complex64 {
178 #[inline]
179 fn from((re, im): (f64, f64)) -> Self {
180 Self::new(re, im)
181 }
182}
183
184impl From<[f64; 2]> for Complex64 {
185 #[inline]
186 fn from(a: [f64; 2]) -> Self {
187 Self::new(a[0], a[1])
188 }
189}
190
191impl From<Complex64> for [f64; 2] {
192 #[inline]
193 fn from(c: Complex64) -> Self {
194 [c.re, c.im]
195 }
196}
197
198impl From<f64> for Complex64 {
199 #[inline]
200 fn from(re: f64) -> Self {
201 Self::new(re, 0.0)
202 }
203}
204
205pub mod sealed {
212 use super::{Complex32, Complex64};
213
214 pub trait Sealed {}
217
218 impl Sealed for f32 {}
219 impl Sealed for f64 {}
220 impl Sealed for Complex32 {}
221 impl Sealed for Complex64 {}
222}
223
224#[cfg(test)]
225mod tests {
226 use super::*;
227
228 #[test]
229 fn complex32_layout_matches_array() {
230 assert_eq!(std::mem::size_of::<Complex32>(), 8);
233 assert_eq!(
234 std::mem::align_of::<Complex32>(),
235 std::mem::align_of::<f32>()
236 );
237 let c = Complex32::new(1.5, -2.0);
238 let arr: [f32; 2] = c.into();
239 assert_eq!(arr, [1.5, -2.0]);
240 }
241
242 #[test]
243 fn complex64_layout_matches_array() {
244 assert_eq!(std::mem::size_of::<Complex64>(), 16);
245 assert_eq!(
246 std::mem::align_of::<Complex64>(),
247 std::mem::align_of::<f64>()
248 );
249 let c = Complex64::new(3.0, 4.0);
250 assert_eq!(c.abs(), 5.0);
251 assert_eq!(c.norm_sqr(), 25.0);
252 assert_eq!(c.conj(), Complex64::new(3.0, -4.0));
253 }
254
255 #[test]
256 fn complex_constants() {
257 assert_eq!(Complex32::ZERO, Complex32::new(0.0, 0.0));
258 assert_eq!(Complex32::ONE, Complex32::new(1.0, 0.0));
259 assert_eq!(Complex32::I, Complex32::new(0.0, 1.0));
260 assert_eq!(Complex64::ZERO, Complex64::new(0.0, 0.0));
261 }
262}