1use crate::{Shape, Stride, Unbind};
2use core::marker::PhantomData;
3use core::ptr::NonNull;
4use faer_traits::{ComplexField, Conjugate};
5use reborrow::*;
6
7pub(crate) struct MatView<T: ?Sized, Rows, Cols, RStride, CStride> {
8 ptr: NonNull<T>,
9 nrows: Rows,
10 ncols: Cols,
11 row_stride: RStride,
12 col_stride: CStride,
13}
14pub trait MatIndex<RowRange, ColRange> {
17 type Target;
19 fn get(this: Self, row: RowRange, col: ColRange) -> Self::Target;
21 unsafe fn get_unchecked(
23 this: Self,
24 row: RowRange,
25 col: ColRange,
26 ) -> Self::Target;
27}
28impl<T: ?Sized, Rows: Copy, Cols: Copy, RStride: Copy, CStride: Copy> Copy
29 for MatView<T, Rows, Cols, RStride, CStride>
30{
31}
32impl<T: ?Sized, Rows: Copy, Cols: Copy, RStride: Copy, CStride: Copy> Clone
33 for MatView<T, Rows, Cols, RStride, CStride>
34{
35 #[inline]
36 fn clone(&self) -> Self {
37 *self
38 }
39}
40#[inline]
41#[track_caller]
42fn from_slice_assert(nrows: usize, ncols: usize, len: usize) {
43 let size = usize::checked_mul(nrows, ncols);
44 assert!(size == Some(len));
45}
46mod mat_index;
47pub(crate) mod matmut;
48pub(crate) mod matown;
49pub(crate) mod matref;
50pub use matmut::Mut;
51pub use matmut::UninitMut;
52pub use matown::Own;
53pub use matref::Ref;
54pub type Mat<T, Rows = usize, Cols = usize> = generic::Mat<Own<T, Rows, Cols>>;
85
86pub type MatRef<
97 'a,
98 T,
99 Rows = usize,
100 Cols = usize,
101 RStride = isize,
102 CStride = isize,
103> = generic::Mat<Ref<'a, T, Rows, Cols, RStride, CStride>>;
104pub type MatMut<
151 'a,
152 T,
153 Rows = usize,
154 Cols = usize,
155 RStride = isize,
156 CStride = isize,
157> = generic::Mat<Mut<'a, T, Rows, Cols, RStride, CStride>>;
158
159pub type MatUninitMut<
167 'a,
168 T,
169 Rows = usize,
170 Cols = usize,
171 RStride = isize,
172 CStride = isize,
173> = generic::Mat<UninitMut<'a, T, Rows, Cols, RStride, CStride>>;
174
175#[doc(hidden)]
176pub mod generic {
178 use crate::{Idx, Shape, Stride};
179 use core::fmt::Debug;
180 use core::ops::{Index, IndexMut};
181 use reborrow::*;
182
183 #[derive(Copy, Clone)]
185 #[repr(transparent)]
186 pub struct Mat<Inner>(pub Inner);
187
188 impl<Inner: Debug> Debug for Mat<Inner> {
189 #[inline(always)]
190 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
191 self.0.fmt(f)
192 }
193 }
194 impl<Inner> Mat<Inner> {
195 #[inline(always)]
197 pub fn from_inner_ref(inner: &Inner) -> &Self {
198 unsafe { &*(inner as *const Inner as *const Self) }
199 }
200
201 #[inline(always)]
203 pub fn from_inner_mut(inner: &mut Inner) -> &mut Self {
204 unsafe { &mut *(inner as *mut Inner as *mut Self) }
205 }
206 }
207 impl<Inner> core::ops::Deref for Mat<Inner> {
208 type Target = Inner;
209
210 #[inline(always)]
211 fn deref(&self) -> &Self::Target {
212 &self.0
213 }
214 }
215 impl<Inner> core::ops::DerefMut for Mat<Inner> {
216 #[inline(always)]
217 fn deref_mut(&mut self) -> &mut Self::Target {
218 &mut self.0
219 }
220 }
221 impl<'short, Inner: Reborrow<'short>> Reborrow<'short> for Mat<Inner> {
222 type Target = Mat<Inner::Target>;
223
224 #[inline(always)]
225 fn rb(&'short self) -> Self::Target {
226 Mat(self.0.rb())
227 }
228 }
229 impl<'short, Inner: ReborrowMut<'short>> ReborrowMut<'short> for Mat<Inner> {
230 type Target = Mat<Inner::Target>;
231
232 #[inline(always)]
233 fn rb_mut(&'short mut self) -> Self::Target {
234 Mat(self.0.rb_mut())
235 }
236 }
237 impl<Inner: IntoConst> IntoConst for Mat<Inner> {
238 type Target = Mat<Inner::Target>;
239
240 #[inline(always)]
241 fn into_const(self) -> Self::Target {
242 Mat(self.0.into_const())
243 }
244 }
245 impl<
246 T,
247 Rows: Shape,
248 Cols: Shape,
249 RStride: Stride,
250 CStride: Stride,
251 Inner: for<'short> Reborrow<
252 'short,
253 Target = super::Ref<'short, T, Rows, Cols, RStride, CStride>,
254 >,
255 > Index<(Idx<Rows>, Idx<Cols>)> for Mat<Inner>
256 {
257 type Output = T;
258
259 #[inline]
260 #[track_caller]
261 fn index(&self, (row, col): (Idx<Rows>, Idx<Cols>)) -> &Self::Output {
262 self.rb().at(row, col)
263 }
264 }
265 impl<
266 T,
267 Rows: Shape,
268 Cols: Shape,
269 RStride: Stride,
270 CStride: Stride,
271 Inner: for<'short> Reborrow<
272 'short,
273 Target = super::Ref<'short, T, Rows, Cols, RStride, CStride>,
274 > + for<'short> ReborrowMut<
275 'short,
276 Target = super::Mut<'short, T, Rows, Cols, RStride, CStride>,
277 >,
278 > IndexMut<(Idx<Rows>, Idx<Cols>)> for Mat<Inner>
279 {
280 #[inline]
281 #[track_caller]
282 fn index_mut(
283 &mut self,
284 (row, col): (Idx<Rows>, Idx<Cols>),
285 ) -> &mut Self::Output {
286 self.rb_mut().at_mut(row, col)
287 }
288 }
289}
290pub trait AsMatRef {
292 type T;
294 type Rows: Shape;
296 type Cols: Shape;
298 type Owned: AsMat<
300 Self::T,
301 T = Self::T,
302 Rows = Self::Rows,
303 Cols = Self::Cols,
304 Owned = Self::Owned,
305 >;
306 fn as_mat_ref(&self) -> MatRef<'_, Self::T, Self::Rows, Self::Cols>;
308}
309pub trait AsMatMut: AsMatRef {
311 fn as_mat_mut(&mut self) -> MatMut<'_, Self::T, Self::Rows, Self::Cols>;
313}
314pub trait AsMat<T>: AsMatMut {
316 fn zeros(rows: Self::Rows, cols: Self::Cols) -> Self
318 where
319 T: ComplexField;
320 fn truncate(&mut self, rows: Self::Rows, cols: Self::Cols);
322}
323impl<M: AsMatRef> AsMatRef for &M {
324 type Cols = M::Cols;
325 type Owned = M::Owned;
326 type Rows = M::Rows;
327 type T = M::T;
328
329 #[inline]
330 fn as_mat_ref(&self) -> MatRef<'_, Self::T, Self::Rows, Self::Cols> {
331 (**self).as_mat_ref()
332 }
333}
334impl<M: AsMatRef> AsMatRef for &mut M {
335 type Cols = M::Cols;
336 type Owned = M::Owned;
337 type Rows = M::Rows;
338 type T = M::T;
339
340 #[inline]
341 fn as_mat_ref(&self) -> MatRef<'_, Self::T, Self::Rows, Self::Cols> {
342 (**self).as_mat_ref()
343 }
344}
345impl<M: AsMatMut> AsMatMut for &mut M {
346 #[inline]
347 fn as_mat_mut(&mut self) -> MatMut<'_, Self::T, Self::Rows, Self::Cols> {
348 (**self).as_mat_mut()
349 }
350}
351impl<T, Rows: Shape, Cols: Shape, RStride: Stride, CStride: Stride> AsMatRef
352 for MatRef<'_, T, Rows, Cols, RStride, CStride>
353{
354 type Cols = Cols;
355 type Owned = Mat<T, Rows, Cols>;
356 type Rows = Rows;
357 type T = T;
358
359 #[inline]
360 fn as_mat_ref(&self) -> MatRef<'_, T, Rows, Cols> {
361 self.as_dyn_stride()
362 }
363}
364impl<T, Rows: Shape, Cols: Shape, RStride: Stride, CStride: Stride> AsMatRef
365 for MatMut<'_, T, Rows, Cols, RStride, CStride>
366{
367 type Cols = Cols;
368 type Owned = Mat<T, Rows, Cols>;
369 type Rows = Rows;
370 type T = T;
371
372 #[inline]
373 fn as_mat_ref(&self) -> MatRef<'_, T, Rows, Cols> {
374 self.rb().as_dyn_stride()
375 }
376}
377impl<T, Rows: Shape, Cols: Shape, RStride: Stride, CStride: Stride> AsMatMut
378 for MatMut<'_, T, Rows, Cols, RStride, CStride>
379{
380 #[inline]
381 fn as_mat_mut(&mut self) -> MatMut<'_, T, Rows, Cols> {
382 self.rb_mut().as_dyn_stride_mut()
383 }
384}
385impl<T, Rows: Shape, Cols: Shape> AsMatRef for Mat<T, Rows, Cols> {
386 type Cols = Cols;
387 type Owned = Mat<T, Rows, Cols>;
388 type Rows = Rows;
389 type T = T;
390
391 #[inline]
392 fn as_mat_ref(&self) -> MatRef<'_, T, Rows, Cols> {
393 self.as_dyn_stride()
394 }
395}
396impl<T, Rows: Shape, Cols: Shape> AsMat<T> for Mat<T, Rows, Cols> {
397 #[inline]
398 fn zeros(rows: Rows, cols: Cols) -> Self
399 where
400 T: ComplexField,
401 {
402 Mat::zeros(rows, cols)
403 }
404
405 #[track_caller]
406 #[inline]
407 fn truncate(&mut self, rows: Self::Rows, cols: Self::Cols) {
408 self.truncate(rows, cols)
409 }
410}
411impl<T, Rows: Shape, Cols: Shape> AsMatMut for Mat<T, Rows, Cols> {
412 #[inline]
413 fn as_mat_mut(&mut self) -> MatMut<'_, T, Rows, Cols> {
414 self.as_dyn_stride_mut()
415 }
416}
417#[cfg(test)]
418mod tests {
419 use super::*;
420 use crate::prelude::*;
421 #[test]
422 fn test_mat() {
423 let _x = crate::mat![[0.0, 1.0]];
424 let mat = Mat::from_fn(3, 4, |i, j| i as f64 + j as f64);
425 let mat = mat.as_ref().cloned();
426 let mat = mat.as_ref();
427 for i in 0..3 {
428 for j in 0..4 {
429 zip!(&mat).map(|x| x).as_ref().at(i, j);
430 }
431 }
432 }
433 #[test]
434 fn test_mat_complex() {
435 let _x = mat![[c64::new(0.0, 0.0), c64::new(1.0, 0.0)]];
436 let mat = Mat::from_fn(3, 4, |i, j| c64::new(i as f64 + j as f64, 0.0));
437 {
438 let _conj = mat.as_ref().conjugate();
439 }
440 let mat = mat.as_ref().cloned();
441 let mat = mat.as_ref();
442 for i in 0..3 {
443 for j in 0..4 {
444 zip!(&mat).map(|x| x).as_ref().at(i, j);
445 }
446 }
447 }
448}