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 matown::Own;
52pub use matref::Ref;
53pub type Mat<T, Rows = usize, Cols = usize> = generic::Mat<Own<T, Rows, Cols>>;
84
85pub type MatRef<
96 'a,
97 T,
98 Rows = usize,
99 Cols = usize,
100 RStride = isize,
101 CStride = isize,
102> = generic::Mat<Ref<'a, T, Rows, Cols, RStride, CStride>>;
103pub type MatMut<
148 'a,
149 T,
150 Rows = usize,
151 Cols = usize,
152 RStride = isize,
153 CStride = isize,
154> = generic::Mat<Mut<'a, T, Rows, Cols, RStride, CStride>>;
155
156#[doc(hidden)]
157pub mod generic {
159 use crate::{Idx, Shape, Stride};
160 use core::fmt::Debug;
161 use core::ops::{Index, IndexMut};
162 use reborrow::*;
163
164 #[derive(Copy, Clone)]
166 #[repr(transparent)]
167 pub struct Mat<Inner>(pub Inner);
168
169 impl<Inner: Debug> Debug for Mat<Inner> {
170 #[inline(always)]
171 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
172 self.0.fmt(f)
173 }
174 }
175 impl<Inner> Mat<Inner> {
176 #[inline(always)]
178 pub fn from_inner_ref(inner: &Inner) -> &Self {
179 unsafe { &*(inner as *const Inner as *const Self) }
180 }
181
182 #[inline(always)]
184 pub fn from_inner_mut(inner: &mut Inner) -> &mut Self {
185 unsafe { &mut *(inner as *mut Inner as *mut Self) }
186 }
187 }
188 impl<Inner> core::ops::Deref for Mat<Inner> {
189 type Target = Inner;
190
191 #[inline(always)]
192 fn deref(&self) -> &Self::Target {
193 &self.0
194 }
195 }
196 impl<Inner> core::ops::DerefMut for Mat<Inner> {
197 #[inline(always)]
198 fn deref_mut(&mut self) -> &mut Self::Target {
199 &mut self.0
200 }
201 }
202 impl<'short, Inner: Reborrow<'short>> Reborrow<'short> for Mat<Inner> {
203 type Target = Mat<Inner::Target>;
204
205 #[inline(always)]
206 fn rb(&'short self) -> Self::Target {
207 Mat(self.0.rb())
208 }
209 }
210 impl<'short, Inner: ReborrowMut<'short>> ReborrowMut<'short> for Mat<Inner> {
211 type Target = Mat<Inner::Target>;
212
213 #[inline(always)]
214 fn rb_mut(&'short mut self) -> Self::Target {
215 Mat(self.0.rb_mut())
216 }
217 }
218 impl<Inner: IntoConst> IntoConst for Mat<Inner> {
219 type Target = Mat<Inner::Target>;
220
221 #[inline(always)]
222 fn into_const(self) -> Self::Target {
223 Mat(self.0.into_const())
224 }
225 }
226 impl<
227 T,
228 Rows: Shape,
229 Cols: Shape,
230 RStride: Stride,
231 CStride: Stride,
232 Inner: for<'short> Reborrow<
233 'short,
234 Target = super::Ref<'short, T, Rows, Cols, RStride, CStride>,
235 >,
236 > Index<(Idx<Rows>, Idx<Cols>)> for Mat<Inner>
237 {
238 type Output = T;
239
240 #[inline]
241 #[track_caller]
242 fn index(&self, (row, col): (Idx<Rows>, Idx<Cols>)) -> &Self::Output {
243 self.rb().at(row, col)
244 }
245 }
246 impl<
247 T,
248 Rows: Shape,
249 Cols: Shape,
250 RStride: Stride,
251 CStride: Stride,
252 Inner: for<'short> Reborrow<
253 'short,
254 Target = super::Ref<'short, T, Rows, Cols, RStride, CStride>,
255 > + for<'short> ReborrowMut<
256 'short,
257 Target = super::Mut<'short, T, Rows, Cols, RStride, CStride>,
258 >,
259 > IndexMut<(Idx<Rows>, Idx<Cols>)> for Mat<Inner>
260 {
261 #[inline]
262 #[track_caller]
263 fn index_mut(
264 &mut self,
265 (row, col): (Idx<Rows>, Idx<Cols>),
266 ) -> &mut Self::Output {
267 self.rb_mut().at_mut(row, col)
268 }
269 }
270}
271pub trait AsMatRef {
273 type T;
275 type Rows: Shape;
277 type Cols: Shape;
279 type Owned: AsMat<
281 Self::T,
282 T = Self::T,
283 Rows = Self::Rows,
284 Cols = Self::Cols,
285 Owned = Self::Owned,
286 >;
287 fn as_mat_ref(&self) -> MatRef<'_, Self::T, Self::Rows, Self::Cols>;
289}
290pub trait AsMatMut: AsMatRef {
292 fn as_mat_mut(&mut self) -> MatMut<'_, Self::T, Self::Rows, Self::Cols>;
294}
295pub trait AsMat<T>: AsMatMut {
297 fn zeros(rows: Self::Rows, cols: Self::Cols) -> Self
299 where
300 T: ComplexField;
301 fn truncate(&mut self, rows: Self::Rows, cols: Self::Cols);
303}
304impl<M: AsMatRef> AsMatRef for &M {
305 type Cols = M::Cols;
306 type Owned = M::Owned;
307 type Rows = M::Rows;
308 type T = M::T;
309
310 #[inline]
311 fn as_mat_ref(&self) -> MatRef<'_, Self::T, Self::Rows, Self::Cols> {
312 (**self).as_mat_ref()
313 }
314}
315impl<M: AsMatRef> AsMatRef for &mut M {
316 type Cols = M::Cols;
317 type Owned = M::Owned;
318 type Rows = M::Rows;
319 type T = M::T;
320
321 #[inline]
322 fn as_mat_ref(&self) -> MatRef<'_, Self::T, Self::Rows, Self::Cols> {
323 (**self).as_mat_ref()
324 }
325}
326impl<M: AsMatMut> AsMatMut for &mut M {
327 #[inline]
328 fn as_mat_mut(&mut self) -> MatMut<'_, Self::T, Self::Rows, Self::Cols> {
329 (**self).as_mat_mut()
330 }
331}
332impl<T, Rows: Shape, Cols: Shape, RStride: Stride, CStride: Stride> AsMatRef
333 for MatRef<'_, T, Rows, Cols, RStride, CStride>
334{
335 type Cols = Cols;
336 type Owned = Mat<T, Rows, Cols>;
337 type Rows = Rows;
338 type T = T;
339
340 #[inline]
341 fn as_mat_ref(&self) -> MatRef<'_, T, Rows, Cols> {
342 self.as_dyn_stride()
343 }
344}
345impl<T, Rows: Shape, Cols: Shape, RStride: Stride, CStride: Stride> AsMatRef
346 for MatMut<'_, T, Rows, Cols, RStride, CStride>
347{
348 type Cols = Cols;
349 type Owned = Mat<T, Rows, Cols>;
350 type Rows = Rows;
351 type T = T;
352
353 #[inline]
354 fn as_mat_ref(&self) -> MatRef<'_, T, Rows, Cols> {
355 self.rb().as_dyn_stride()
356 }
357}
358impl<T, Rows: Shape, Cols: Shape, RStride: Stride, CStride: Stride> AsMatMut
359 for MatMut<'_, T, Rows, Cols, RStride, CStride>
360{
361 #[inline]
362 fn as_mat_mut(&mut self) -> MatMut<'_, T, Rows, Cols> {
363 self.rb_mut().as_dyn_stride_mut()
364 }
365}
366impl<T, Rows: Shape, Cols: Shape> AsMatRef for Mat<T, Rows, Cols> {
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.as_dyn_stride()
375 }
376}
377impl<T, Rows: Shape, Cols: Shape> AsMat<T> for Mat<T, Rows, Cols> {
378 #[inline]
379 fn zeros(rows: Rows, cols: Cols) -> Self
380 where
381 T: ComplexField,
382 {
383 Mat::zeros(rows, cols)
384 }
385
386 #[track_caller]
387 #[inline]
388 fn truncate(&mut self, rows: Self::Rows, cols: Self::Cols) {
389 self.truncate(rows, cols)
390 }
391}
392impl<T, Rows: Shape, Cols: Shape> AsMatMut for Mat<T, Rows, Cols> {
393 #[inline]
394 fn as_mat_mut(&mut self) -> MatMut<'_, T, Rows, Cols> {
395 self.as_dyn_stride_mut()
396 }
397}
398#[cfg(test)]
399mod tests {
400 use super::*;
401 use crate::prelude::*;
402 #[test]
403 fn test_mat() {
404 let _x = crate::mat![[0.0, 1.0]];
405 let mat = Mat::from_fn(3, 4, |i, j| i as f64 + j as f64);
406 let mat = mat.as_ref().cloned();
407 let mat = mat.as_ref();
408 for i in 0..3 {
409 for j in 0..4 {
410 zip!(&mat).map(|x| x).as_ref().at(i, j);
411 }
412 }
413 }
414 #[test]
415 fn test_mat_complex() {
416 let _x = mat![[c64::new(0.0, 0.0), c64::new(1.0, 0.0)]];
417 let mat = Mat::from_fn(3, 4, |i, j| c64::new(i as f64 + j as f64, 0.0));
418 {
419 let _conj = mat.as_ref().conjugate();
420 }
421 let mat = mat.as_ref().cloned();
422 let mat = mat.as_ref();
423 for i in 0..3 {
424 for j in 0..4 {
425 zip!(&mat).map(|x| x).as_ref().at(i, j);
426 }
427 }
428 }
429}