1#![allow(missing_docs)]
2
3use core::marker::PhantomData;
4
5use crate::col::{Col, ColMut, ColRef};
6use crate::mat::{Mat, MatMut, MatRef};
7use crate::row::{Row, RowMut, RowRef};
8use crate::{ContiguousFwd, Idx, Shape, Stride, Unbind, diag};
9use equator::{assert, debug_assert};
10use reborrow::*;
11
12pub trait IntoView {
13 type Target;
14
15 fn into_view(self) -> Self::Target;
16}
17
18impl<'a, T, Rows: Shape, Cols: Shape> IntoView for &'a mut Mat<T, Rows, Cols> {
19 type Target = MatMut<'a, T, Rows, Cols, ContiguousFwd>;
20
21 #[inline]
22 fn into_view(self) -> Self::Target {
23 self.as_mut().try_as_col_major_mut().unwrap()
24 }
25}
26impl<'a, T, Rows: Shape, Cols: Shape> IntoView for &'a Mat<T, Rows, Cols> {
27 type Target = MatRef<'a, T, Rows, Cols, ContiguousFwd>;
28
29 #[inline]
30 fn into_view(self) -> Self::Target {
31 self.as_ref().try_as_col_major().unwrap()
32 }
33}
34
35impl<'a, T, Len: Shape> IntoView for &'a mut Col<T, Len> {
36 type Target = ColMut<'a, T, Len, ContiguousFwd>;
37
38 #[inline]
39 fn into_view(self) -> Self::Target {
40 self.as_mut().try_as_col_major_mut().unwrap()
41 }
42}
43impl<'a, T, Len: Shape> IntoView for &'a Col<T, Len> {
44 type Target = ColRef<'a, T, Len, ContiguousFwd>;
45
46 #[inline]
47 fn into_view(self) -> Self::Target {
48 self.as_ref().try_as_col_major().unwrap()
49 }
50}
51
52impl<'a, T, Len: Shape> IntoView for &'a mut Row<T, Len> {
53 type Target = RowMut<'a, T, Len, ContiguousFwd>;
54
55 #[inline]
56 fn into_view(self) -> Self::Target {
57 self.as_mut().try_as_row_major_mut().unwrap()
58 }
59}
60impl<'a, T, Len: Shape> IntoView for &'a Row<T, Len> {
61 type Target = RowRef<'a, T, Len, ContiguousFwd>;
62
63 #[inline]
64 fn into_view(self) -> Self::Target {
65 self.as_ref().try_as_row_major().unwrap()
66 }
67}
68
69impl<'a, T, Len: Shape> IntoView for &'a mut diag::Diag<T, Len> {
70 type Target = diag::DiagMut<'a, T, Len, ContiguousFwd>;
71
72 #[inline]
73 fn into_view(self) -> Self::Target {
74 self.as_mut().column_vector_mut().try_as_col_major_mut().unwrap().as_diagonal_mut()
75 }
76}
77impl<'a, T, Len: Shape> IntoView for &'a diag::Diag<T, Len> {
78 type Target = diag::DiagRef<'a, T, Len, ContiguousFwd>;
79
80 #[inline]
81 fn into_view(self) -> Self::Target {
82 self.as_ref().column_vector().try_as_col_major().unwrap().as_diagonal()
83 }
84}
85
86impl<'a, T, Rows: Shape, Cols: Shape, RStride: Stride, CStride: Stride> IntoView for MatMut<'a, T, Rows, Cols, RStride, CStride> {
87 type Target = Self;
88
89 #[inline]
90 fn into_view(self) -> Self::Target {
91 self
92 }
93}
94impl<'a, T, Rows: Shape, Cols: Shape, RStride: Stride, CStride: Stride> IntoView for MatRef<'a, T, Rows, Cols, RStride, CStride> {
95 type Target = Self;
96
97 #[inline]
98 fn into_view(self) -> Self::Target {
99 self
100 }
101}
102
103impl<'a, T, Rows: Shape, Cols: Shape, RStride: Stride, CStride: Stride> IntoView for &'a MatMut<'_, T, Rows, Cols, RStride, CStride> {
104 type Target = MatRef<'a, T, Rows, Cols, RStride, CStride>;
105
106 #[inline]
107 fn into_view(self) -> Self::Target {
108 self.rb()
109 }
110}
111impl<'a, T, Rows: Shape, Cols: Shape, RStride: Stride, CStride: Stride> IntoView for &'a MatRef<'_, T, Rows, Cols, RStride, CStride> {
112 type Target = MatRef<'a, T, Rows, Cols, RStride, CStride>;
113
114 #[inline]
115 fn into_view(self) -> Self::Target {
116 *self
117 }
118}
119
120impl<'a, T, Rows: Shape, Cols: Shape, RStride: Stride, CStride: Stride> IntoView for &'a mut MatMut<'_, T, Rows, Cols, RStride, CStride> {
121 type Target = MatMut<'a, T, Rows, Cols, RStride, CStride>;
122
123 #[inline]
124 fn into_view(self) -> Self::Target {
125 self.rb_mut()
126 }
127}
128impl<'a, T, Rows: Shape, Cols: Shape, RStride: Stride, CStride: Stride> IntoView for &'a mut MatRef<'_, T, Rows, Cols, RStride, CStride> {
129 type Target = MatRef<'a, T, Rows, Cols, RStride, CStride>;
130
131 #[inline]
132 fn into_view(self) -> Self::Target {
133 *self
134 }
135}
136
137impl<'a, T, Rows: Shape, RStride: Stride> IntoView for ColMut<'a, T, Rows, RStride> {
138 type Target = Self;
139
140 #[inline]
141 fn into_view(self) -> Self::Target {
142 self
143 }
144}
145impl<'a, T, Rows: Shape, RStride: Stride> IntoView for ColRef<'a, T, Rows, RStride> {
146 type Target = Self;
147
148 #[inline]
149 fn into_view(self) -> Self::Target {
150 self
151 }
152}
153
154impl<'a, T, Rows: Shape, RStride: Stride> IntoView for &'a ColMut<'_, T, Rows, RStride> {
155 type Target = ColRef<'a, T, Rows, RStride>;
156
157 #[inline]
158 fn into_view(self) -> Self::Target {
159 self.rb()
160 }
161}
162impl<'a, T, Rows: Shape, RStride: Stride> IntoView for &'a ColRef<'_, T, Rows, RStride> {
163 type Target = ColRef<'a, T, Rows, RStride>;
164
165 #[inline]
166 fn into_view(self) -> Self::Target {
167 *self
168 }
169}
170
171impl<'a, T, Rows: Shape, RStride: Stride> IntoView for &'a mut ColMut<'_, T, Rows, RStride> {
172 type Target = ColMut<'a, T, Rows, RStride>;
173
174 #[inline]
175 fn into_view(self) -> Self::Target {
176 self.rb_mut()
177 }
178}
179impl<'a, T, Rows: Shape, RStride: Stride> IntoView for &'a mut ColRef<'_, T, Rows, RStride> {
180 type Target = ColRef<'a, T, Rows, RStride>;
181
182 #[inline]
183 fn into_view(self) -> Self::Target {
184 *self
185 }
186}
187
188impl<'a, T, Rows: Shape, DStride: Stride> IntoView for diag::DiagMut<'a, T, Rows, DStride> {
189 type Target = Self;
190
191 #[inline]
192 fn into_view(self) -> Self::Target {
193 self
194 }
195}
196impl<'a, T, Rows: Shape, DStride: Stride> IntoView for diag::DiagRef<'a, T, Rows, DStride> {
197 type Target = Self;
198
199 #[inline]
200 fn into_view(self) -> Self::Target {
201 self
202 }
203}
204
205impl<'a, T, Rows: Shape, DStride: Stride> IntoView for &'a diag::DiagMut<'_, T, Rows, DStride> {
206 type Target = diag::DiagRef<'a, T, Rows, DStride>;
207
208 #[inline]
209 fn into_view(self) -> Self::Target {
210 self.rb()
211 }
212}
213impl<'a, T, Rows: Shape, DStride: Stride> IntoView for &'a diag::DiagRef<'_, T, Rows, DStride> {
214 type Target = diag::DiagRef<'a, T, Rows, DStride>;
215
216 #[inline]
217 fn into_view(self) -> Self::Target {
218 *self
219 }
220}
221
222impl<'a, T, Rows: Shape, DStride: Stride> IntoView for &'a mut diag::DiagMut<'_, T, Rows, DStride> {
223 type Target = diag::DiagMut<'a, T, Rows, DStride>;
224
225 #[inline]
226 fn into_view(self) -> Self::Target {
227 self.rb_mut()
228 }
229}
230impl<'a, T, Rows: Shape, DStride: Stride> IntoView for &'a mut diag::DiagRef<'_, T, Rows, DStride> {
231 type Target = diag::DiagRef<'a, T, Rows, DStride>;
232
233 #[inline]
234 fn into_view(self) -> Self::Target {
235 *self
236 }
237}
238
239impl<'a, T, Cols: Shape, CStride: Stride> IntoView for RowMut<'a, T, Cols, CStride> {
240 type Target = Self;
241
242 #[inline]
243 fn into_view(self) -> Self::Target {
244 self
245 }
246}
247impl<'a, T, Cols: Shape, CStride: Stride> IntoView for RowRef<'a, T, Cols, CStride> {
248 type Target = Self;
249
250 #[inline]
251 fn into_view(self) -> Self::Target {
252 self
253 }
254}
255
256impl<'a, T, Cols: Shape, CStride: Stride> IntoView for &'a RowMut<'_, T, Cols, CStride> {
257 type Target = RowRef<'a, T, Cols, CStride>;
258
259 #[inline]
260 fn into_view(self) -> Self::Target {
261 self.rb()
262 }
263}
264impl<'a, T, Cols: Shape, CStride: Stride> IntoView for &'a RowRef<'_, T, Cols, CStride> {
265 type Target = RowRef<'a, T, Cols, CStride>;
266
267 #[inline]
268 fn into_view(self) -> Self::Target {
269 *self
270 }
271}
272
273impl<'a, T, Cols: Shape, CStride: Stride> IntoView for &'a mut RowMut<'_, T, Cols, CStride> {
274 type Target = RowMut<'a, T, Cols, CStride>;
275
276 #[inline]
277 fn into_view(self) -> Self::Target {
278 self.rb_mut()
279 }
280}
281impl<'a, T, Cols: Shape, CStride: Stride> IntoView for &'a mut RowRef<'_, T, Cols, CStride> {
282 type Target = RowRef<'a, T, Cols, CStride>;
283
284 #[inline]
285 fn into_view(self) -> Self::Target {
286 *self
287 }
288}
289
290#[derive(Copy, Clone, Debug, PartialEq, Eq)]
291pub enum Diag {
292 Skip,
293 Include,
294}
295
296#[derive(Copy, Clone)]
298pub enum MatLayoutTransform {
299 None,
301 ReverseRows,
303 Transpose,
305 TransposeReverseRows,
307}
308
309#[derive(Copy, Clone)]
311pub enum VecLayoutTransform {
312 None,
314 Reverse,
316}
317
318pub trait MatIndex {
320 type Kind;
321
322 type Rows: Copy + Eq + core::fmt::Debug;
324 type Cols: Copy + Eq + core::fmt::Debug;
326 fn nrows(this: &Self) -> Self::Rows;
328 fn ncols(this: &Self) -> Self::Cols;
330
331 type Index: Copy;
333 type LayoutTransform: Copy;
335
336 type Item;
338
339 type Dyn: MatIndex<Kind = Self::Kind, Dyn = Self::Dyn, LayoutTransform = Self::LayoutTransform, Item = Self::Item, Slice = Self::Slice>;
341
342 type Slice: for<'a> SliceFamily<'a, Self::Item>;
343
344 unsafe fn get_slice_unchecked<'a>(this: &'a mut Self, idx: Self::Index, n_elems: usize) -> <Self::Slice as SliceFamily<'a, Self::Item>>::Slice;
346
347 unsafe fn from_dyn_idx(idx: <Self::Dyn as MatIndex>::Index) -> Self::Index;
349
350 unsafe fn get_unchecked(this: &mut Self, index: Self::Index) -> Self::Item;
352 unsafe fn next_unchecked<'a>(slice: &mut <Self::Slice as SliceFamily<'a, Self::Item>>::Slice) -> Self::Item;
354
355 fn is_contiguous(this: &Self) -> bool;
357 fn preferred_layout(this: &Self) -> Self::LayoutTransform;
359 fn with_layout(this: Self, layout: Self::LayoutTransform) -> Self::Dyn;
361}
362
363pub trait SliceFamily<'a, T, Outlives = &'a Self> {
364 type Slice;
365}
366pub struct Slice<T>(pub T);
367pub struct SliceRef<'b, T>(pub &'b T);
368pub struct SliceMut<'b, T>(pub &'b mut T);
369
370impl<'a, T> SliceFamily<'a, T> for Slice<T> {
371 type Slice = &'a [T];
372}
373impl<'a, 'b, T> SliceFamily<'a, &'b T> for SliceRef<'b, T> {
374 type Slice = &'b [T];
375}
376impl<'a, 'b, T> SliceFamily<'a, &'b mut T> for SliceMut<'b, T> {
377 type Slice = &'b mut [T];
378}
379impl<'a, T, F: SliceFamily<'a, T>> SliceFamily<'a, Last<T>> for Last<F> {
380 type Slice = Last<F::Slice>;
381}
382impl<'a, T, U, F: SliceFamily<'a, T>, G: SliceFamily<'a, U>> SliceFamily<'a, Zip<T, U>> for Zip<F, G> {
383 type Slice = Zip<F::Slice, G::Slice>;
384}
385
386#[derive(Copy, Clone, Debug)]
388pub struct LastEq<Kind, Mat>(pub Mat, pub PhantomData<Kind>);
389
390#[derive(Copy, Clone, Debug)]
392pub struct Last<Mat>(pub Mat);
393
394#[derive(Copy, Clone, Debug)]
396pub struct ZipEq<Kind, Head, Tail>(pub Head, pub Tail, PhantomData<Kind>);
397
398#[derive(Copy, Clone, Debug)]
400pub struct Zip<Head, Tail>(pub Head, pub Tail);
401
402impl<
404 Kind,
405 Rows: Copy + Eq + core::fmt::Debug,
406 Cols: Copy + Eq + core::fmt::Debug,
407 Head: MatIndex<Kind = Kind, Rows = Rows, Cols = Cols>,
408 Tail: MatIndex<Kind = Kind, Rows = Rows, Cols = Cols>,
409> ZipEq<Kind, Head, Tail>
410{
411 #[inline(always)]
413 #[track_caller]
414 pub fn new(head: Head, tail: Tail) -> Self {
415 assert!(all(Head::nrows(&head) == Tail::nrows(&tail), Head::ncols(&head) == Tail::ncols(&tail),));
416 Self(head, tail, PhantomData)
417 }
418
419 #[inline(always)]
421 #[track_caller]
422 pub fn new_unchecked(head: Head, tail: Tail) -> Self {
423 debug_assert!(all(Head::nrows(&head) == Tail::nrows(&tail), Head::ncols(&head) == Tail::ncols(&tail),));
424 Self(head, tail, PhantomData)
425 }
426}
427
428impl<Kind, Rows: Copy + Eq + core::fmt::Debug, Cols: Copy + Eq + core::fmt::Debug, Mat: MatIndex<Rows = Rows, Cols = Cols, Kind = Kind>> MatIndex
429 for LastEq<Kind, Mat>
430{
431 type Cols = Mat::Cols;
432 type Dyn = LastEq<<Mat::Dyn as MatIndex>::Kind, Mat::Dyn>;
433 type Index = Mat::Index;
434 type Item = Last<Mat::Item>;
435 type Kind = Mat::Kind;
436 type LayoutTransform = Mat::LayoutTransform;
437 type Rows = Mat::Rows;
438 type Slice = Last<Mat::Slice>;
439
440 #[inline(always)]
441 fn nrows(this: &Self) -> Self::Rows {
442 Mat::nrows(&this.0)
443 }
444
445 #[inline(always)]
446 fn ncols(this: &Self) -> Self::Cols {
447 Mat::ncols(&this.0)
448 }
449
450 #[inline]
451 unsafe fn get_slice_unchecked<'a>(this: &'a mut Self, idx: Self::Index, n_elems: usize) -> <Self::Slice as SliceFamily<'a, Self::Item>>::Slice {
452 Last(Mat::get_slice_unchecked(&mut this.0, idx, n_elems))
453 }
454
455 #[inline]
456 unsafe fn from_dyn_idx(idx: <Self::Dyn as MatIndex>::Index) -> Self::Index {
457 Mat::from_dyn_idx(idx)
458 }
459
460 #[inline]
461 unsafe fn get_unchecked(this: &mut Self, index: Self::Index) -> Self::Item {
462 Last(Mat::get_unchecked(&mut this.0, index))
463 }
464
465 #[inline]
466 unsafe fn next_unchecked<'a>(slice: &mut <Self::Slice as SliceFamily<'a, Self::Item>>::Slice) -> Self::Item {
467 Last(Mat::next_unchecked(&mut slice.0))
468 }
469
470 #[inline]
471 fn is_contiguous(this: &Self) -> bool {
472 Mat::is_contiguous(&this.0)
473 }
474
475 #[inline]
476 fn preferred_layout(this: &Self) -> Self::LayoutTransform {
477 Mat::preferred_layout(&this.0)
478 }
479
480 #[inline]
481 fn with_layout(this: Self, layout: Self::LayoutTransform) -> Self::Dyn {
482 LastEq(Mat::with_layout(this.0, layout), PhantomData)
483 }
484}
485
486impl<
487 Kind,
488 Rows: Copy + Eq + core::fmt::Debug,
489 Cols: Copy + Eq + core::fmt::Debug,
490 L: MatIndex<Kind = Kind, Rows = Rows, Cols = Cols>,
491 R: MatIndex<Kind = Kind, Rows = Rows, Cols = Cols, Index = L::Index, LayoutTransform = L::LayoutTransform>,
492> MatIndex for ZipEq<Kind, L, R>
493where
494 R::Dyn: MatIndex<Rows = <L::Dyn as MatIndex>::Rows, Cols = <L::Dyn as MatIndex>::Cols, Index = <L::Dyn as MatIndex>::Index>,
495{
496 type Cols = L::Cols;
497 type Dyn = ZipEq<<L::Dyn as MatIndex>::Kind, L::Dyn, R::Dyn>;
498 type Index = L::Index;
499 type Item = Zip<L::Item, R::Item>;
500 type Kind = L::Kind;
501 type LayoutTransform = L::LayoutTransform;
502 type Rows = L::Rows;
503 type Slice = Zip<L::Slice, R::Slice>;
504
505 #[inline(always)]
506 fn nrows(this: &Self) -> Self::Rows {
507 L::nrows(&this.0)
508 }
509
510 #[inline(always)]
511 fn ncols(this: &Self) -> Self::Cols {
512 L::ncols(&this.0)
513 }
514
515 #[inline]
516 unsafe fn get_slice_unchecked<'a>(this: &'a mut Self, idx: Self::Index, n_elems: usize) -> <Self::Slice as SliceFamily<'a, Self::Item>>::Slice {
517 Zip(
518 L::get_slice_unchecked(&mut this.0, idx, n_elems),
519 R::get_slice_unchecked(&mut this.1, idx, n_elems),
520 )
521 }
522
523 #[inline]
524 unsafe fn from_dyn_idx(idx: <Self::Dyn as MatIndex>::Index) -> Self::Index {
525 L::from_dyn_idx(idx)
526 }
527
528 #[inline]
529 unsafe fn get_unchecked(this: &mut Self, index: Self::Index) -> Self::Item {
530 Zip(L::get_unchecked(&mut this.0, index), R::get_unchecked(&mut this.1, index))
531 }
532
533 #[inline]
534 unsafe fn next_unchecked<'a>(slice: &mut <Self::Slice as SliceFamily<'a, Self::Item>>::Slice) -> Self::Item {
535 Zip(L::next_unchecked(&mut slice.0), R::next_unchecked(&mut slice.1))
536 }
537
538 #[inline]
539 fn is_contiguous(this: &Self) -> bool {
540 L::is_contiguous(&this.0) && R::is_contiguous(&this.1)
541 }
542
543 #[inline]
544 fn preferred_layout(this: &Self) -> Self::LayoutTransform {
545 L::preferred_layout(&this.0)
546 }
547
548 #[inline]
549 fn with_layout(this: Self, layout: Self::LayoutTransform) -> Self::Dyn {
550 ZipEq(L::with_layout(this.0, layout), R::with_layout(this.1, layout), PhantomData)
551 }
552}
553
554impl<'b, T, Rows: Shape, Cols: Shape, RStride: Stride, CStride: Stride> MatIndex for MatMut<'b, T, Rows, Cols, RStride, CStride> {
555 type Cols = Cols;
556 type Dyn = MatMut<'b, T, usize, usize, isize, isize>;
557 type Index = (Idx<Rows>, Idx<Cols>);
558 type Item = &'b mut T;
559 type Kind = kind::Mat;
560 type LayoutTransform = MatLayoutTransform;
561 type Rows = Rows;
562 type Slice = SliceMut<'b, T>;
563
564 #[inline]
565 fn nrows(this: &Self) -> Self::Rows {
566 this.nrows()
567 }
568
569 #[inline]
570 fn ncols(this: &Self) -> Self::Cols {
571 this.ncols()
572 }
573
574 #[inline]
575 unsafe fn get_slice_unchecked<'a>(this: &'a mut Self, idx: Self::Index, n_elems: usize) -> <Self::Slice as SliceFamily<'a, Self::Item>>::Slice {
576 let ptr = this.ptr_inbounds_at_mut(idx.0, idx.1);
577 core::slice::from_raw_parts_mut(ptr, n_elems)
578 }
579
580 #[inline]
581 unsafe fn from_dyn_idx(idx: <Self::Dyn as MatIndex>::Index) -> Self::Index {
582 (Idx::<Rows>::new_unbound(idx.0), Idx::<Cols>::new_unbound(idx.1))
583 }
584
585 #[inline]
586 unsafe fn get_unchecked(this: &mut Self, (i, j): Self::Index) -> Self::Item {
587 let ptr = this.rb().ptr_inbounds_at_mut(i, j);
588 &mut *ptr
589 }
590
591 #[inline(always)]
592 unsafe fn next_unchecked<'a>(slice: &mut <Self::Slice as SliceFamily<'a, Self::Item>>::Slice) -> Self::Item {
593 let (head, tail) = core::mem::take(slice).split_first_mut().unwrap_unchecked();
594 *slice = tail;
595 head
596 }
597
598 #[inline(always)]
599 fn is_contiguous(this: &Self) -> bool {
600 this.row_stride().element_stride() == 1
601 }
602
603 #[inline(always)]
604 fn preferred_layout(this: &Self) -> Self::LayoutTransform {
605 let rs = this.row_stride().element_stride();
606 let cs = this.col_stride().element_stride();
607 let nrows = this.nrows().unbound();
608 let ncols = this.ncols().unbound();
609
610 if nrows > 1 && rs == 1 {
611 MatLayoutTransform::None
612 } else if nrows > 1 && rs == -1 {
613 MatLayoutTransform::ReverseRows
614 } else if ncols > 1 && cs == 1 {
615 MatLayoutTransform::Transpose
616 } else if ncols > 1 && cs == -1 {
617 MatLayoutTransform::TransposeReverseRows
618 } else {
619 MatLayoutTransform::None
620 }
621 }
622
623 #[inline(always)]
624 fn with_layout(this: Self, layout: Self::LayoutTransform) -> Self::Dyn {
625 use MatLayoutTransform::*;
626 let this = this.as_dyn_mut().as_dyn_stride_mut();
627 match layout {
628 None => this,
629 ReverseRows => this.reverse_rows_mut(),
630 Transpose => this.transpose_mut(),
631 TransposeReverseRows => this.transpose_mut().reverse_rows_mut(),
632 }
633 }
634}
635
636impl<'b, T, Rows: Shape, Cols: Shape, RStride: Stride, CStride: Stride> MatIndex for MatRef<'b, T, Rows, Cols, RStride, CStride> {
637 type Cols = Cols;
638 type Dyn = MatRef<'b, T, usize, usize, isize, isize>;
639 type Index = (Idx<Rows>, Idx<Cols>);
640 type Item = &'b T;
641 type Kind = kind::Mat;
642 type LayoutTransform = MatLayoutTransform;
643 type Rows = Rows;
644 type Slice = SliceRef<'b, T>;
645
646 #[inline]
647 fn nrows(this: &Self) -> Self::Rows {
648 this.nrows()
649 }
650
651 #[inline]
652 fn ncols(this: &Self) -> Self::Cols {
653 this.ncols()
654 }
655
656 #[inline]
657 unsafe fn get_slice_unchecked<'a>(this: &'a mut Self, idx: Self::Index, n_elems: usize) -> <Self::Slice as SliceFamily<'a, Self::Item>>::Slice {
658 let ptr = this.ptr_inbounds_at(idx.0, idx.1);
659 core::slice::from_raw_parts(ptr, n_elems)
660 }
661
662 #[inline]
663 unsafe fn from_dyn_idx(idx: <Self::Dyn as MatIndex>::Index) -> Self::Index {
664 (Idx::<Rows>::new_unbound(idx.0), Idx::<Cols>::new_unbound(idx.1))
665 }
666
667 #[inline]
668 unsafe fn get_unchecked(this: &mut Self, (i, j): Self::Index) -> Self::Item {
669 let ptr = this.rb().ptr_inbounds_at(i, j);
670 &*ptr
671 }
672
673 #[inline(always)]
674 unsafe fn next_unchecked<'a>(slice: &mut <Self::Slice as SliceFamily<'a, Self::Item>>::Slice) -> Self::Item {
675 let (head, tail) = core::mem::take(slice).split_first().unwrap_unchecked();
676 *slice = tail;
677 head
678 }
679
680 #[inline(always)]
681 fn is_contiguous(this: &Self) -> bool {
682 this.row_stride().element_stride() == 1
683 }
684
685 #[inline(always)]
686 fn preferred_layout(this: &Self) -> Self::LayoutTransform {
687 let rs = this.row_stride().element_stride();
688 let cs = this.col_stride().element_stride();
689 let nrows = this.nrows().unbound();
690 let ncols = this.ncols().unbound();
691
692 if nrows > 1 && rs == 1 {
693 MatLayoutTransform::None
694 } else if nrows > 1 && rs == -1 {
695 MatLayoutTransform::ReverseRows
696 } else if ncols > 1 && cs == 1 {
697 MatLayoutTransform::Transpose
698 } else if ncols > 1 && cs == -1 {
699 MatLayoutTransform::TransposeReverseRows
700 } else {
701 MatLayoutTransform::None
702 }
703 }
704
705 #[inline(always)]
706 fn with_layout(this: Self, layout: Self::LayoutTransform) -> Self::Dyn {
707 use MatLayoutTransform::*;
708 let this = this.as_dyn().as_dyn_stride();
709 match layout {
710 None => this,
711 ReverseRows => this.reverse_rows(),
712 Transpose => this.transpose(),
713 TransposeReverseRows => this.transpose().reverse_rows(),
714 }
715 }
716}
717
718impl<'b, T, Len: Shape, Strd: Stride> MatIndex for ColMut<'b, T, Len, Strd> {
719 type Cols = ();
720 type Dyn = ColMut<'b, T, usize, isize>;
721 type Index = Idx<Len>;
722 type Item = &'b mut T;
723 type Kind = kind::Col;
724 type LayoutTransform = VecLayoutTransform;
725 type Rows = Len;
726 type Slice = SliceMut<'b, T>;
727
728 #[inline]
729 fn nrows(this: &Self) -> Self::Rows {
730 this.nrows()
731 }
732
733 #[inline]
734 fn ncols(_: &Self) -> Self::Cols {
735 ()
736 }
737
738 #[inline]
739 unsafe fn get_slice_unchecked<'a>(this: &'a mut Self, idx: Self::Index, n_elems: usize) -> <Self::Slice as SliceFamily<'a, Self::Item>>::Slice {
740 let ptr = this.ptr_inbounds_at_mut(idx);
741 core::slice::from_raw_parts_mut(ptr, n_elems)
742 }
743
744 #[inline]
745 unsafe fn from_dyn_idx(idx: <Self::Dyn as MatIndex>::Index) -> Self::Index {
746 Idx::<Len>::new_unbound(idx)
747 }
748
749 #[inline]
750 unsafe fn get_unchecked(this: &mut Self, i: Self::Index) -> Self::Item {
751 let ptr = this.ptr_inbounds_at_mut(i);
752 &mut *ptr
753 }
754
755 #[inline(always)]
756 unsafe fn next_unchecked<'a>(slice: &mut <Self::Slice as SliceFamily<'a, Self::Item>>::Slice) -> Self::Item {
757 let (head, tail) = core::mem::take(slice).split_first_mut().unwrap_unchecked();
758 *slice = tail;
759 head
760 }
761
762 #[inline(always)]
763 fn is_contiguous(this: &Self) -> bool {
764 this.row_stride().element_stride() == 1
765 }
766
767 #[inline(always)]
768 fn preferred_layout(this: &Self) -> Self::LayoutTransform {
769 let strd = this.row_stride().element_stride();
770 let len = this.nrows().unbound();
771
772 if len > 1 && strd == 1 {
773 VecLayoutTransform::None
774 } else if len > 1 && strd == -1 {
775 VecLayoutTransform::Reverse
776 } else {
777 VecLayoutTransform::None
778 }
779 }
780
781 #[inline(always)]
782 fn with_layout(this: Self, layout: Self::LayoutTransform) -> Self::Dyn {
783 use VecLayoutTransform::*;
784 let this = this.as_dyn_rows_mut().as_dyn_stride_mut();
785 match layout {
786 None => this,
787 Reverse => this.reverse_rows_mut(),
788 }
789 }
790}
791
792impl<'b, T, Len: Shape, Strd: Stride> MatIndex for diag::DiagMut<'b, T, Len, Strd> {
793 type Cols = Len;
794 type Dyn = diag::DiagMut<'b, T, usize, isize>;
795 type Index = Idx<Len>;
796 type Item = &'b mut T;
797 type Kind = kind::Diag;
798 type LayoutTransform = VecLayoutTransform;
799 type Rows = Len;
800 type Slice = SliceMut<'b, T>;
801
802 #[inline]
803 fn nrows(this: &Self) -> Self::Rows {
804 this.dim()
805 }
806
807 #[inline]
808 fn ncols(this: &Self) -> Self::Cols {
809 this.dim()
810 }
811
812 #[inline]
813 unsafe fn get_slice_unchecked<'a>(this: &'a mut Self, idx: Self::Index, n_elems: usize) -> <Self::Slice as SliceFamily<'a, Self::Item>>::Slice {
814 let ptr = this.rb_mut().column_vector_mut().ptr_inbounds_at_mut(idx);
815 core::slice::from_raw_parts_mut(ptr, n_elems)
816 }
817
818 #[inline]
819 unsafe fn from_dyn_idx(idx: <Self::Dyn as MatIndex>::Index) -> Self::Index {
820 Idx::<Len>::new_unbound(idx)
821 }
822
823 #[inline]
824 unsafe fn get_unchecked(this: &mut Self, i: Self::Index) -> Self::Item {
825 let ptr = this.rb_mut().column_vector_mut().ptr_inbounds_at_mut(i);
826 &mut *ptr
827 }
828
829 #[inline(always)]
830 unsafe fn next_unchecked<'a>(slice: &mut <Self::Slice as SliceFamily<'a, Self::Item>>::Slice) -> Self::Item {
831 let (head, tail) = core::mem::take(slice).split_first_mut().unwrap_unchecked();
832 *slice = tail;
833 head
834 }
835
836 #[inline(always)]
837 fn is_contiguous(this: &Self) -> bool {
838 this.stride().element_stride() == 1
839 }
840
841 #[inline(always)]
842 fn preferred_layout(this: &Self) -> Self::LayoutTransform {
843 let strd = this.stride().element_stride();
844 let len = this.dim().unbound();
845
846 if len > 1 && strd == 1 {
847 VecLayoutTransform::None
848 } else if len > 1 && strd == -1 {
849 VecLayoutTransform::Reverse
850 } else {
851 VecLayoutTransform::None
852 }
853 }
854
855 #[inline(always)]
856 fn with_layout(this: Self, layout: Self::LayoutTransform) -> Self::Dyn {
857 use VecLayoutTransform::*;
858 let this = this.as_dyn_mut().as_dyn_stride_mut();
859 match layout {
860 None => this,
861 Reverse => this.column_vector_mut().reverse_rows_mut().as_diagonal_mut(),
862 }
863 }
864}
865
866impl<'b, T, Len: Shape, Strd: Stride> MatIndex for RowMut<'b, T, Len, Strd> {
867 type Cols = Len;
868 type Dyn = RowMut<'b, T, usize, isize>;
869 type Index = Idx<Len>;
870 type Item = &'b mut T;
871 type Kind = kind::Row;
872 type LayoutTransform = VecLayoutTransform;
873 type Rows = ();
874 type Slice = SliceMut<'b, T>;
875
876 #[inline]
877 fn nrows(_: &Self) -> Self::Rows {
878 ()
879 }
880
881 #[inline]
882 fn ncols(this: &Self) -> Self::Cols {
883 this.ncols()
884 }
885
886 #[inline]
887 unsafe fn get_slice_unchecked<'a>(this: &'a mut Self, idx: Self::Index, n_elems: usize) -> <Self::Slice as SliceFamily<'a, Self::Item>>::Slice {
888 let ptr = this.ptr_inbounds_at_mut(idx);
889 core::slice::from_raw_parts_mut(ptr, n_elems)
890 }
891
892 #[inline]
893 unsafe fn from_dyn_idx(idx: <Self::Dyn as MatIndex>::Index) -> Self::Index {
894 Idx::<Len>::new_unbound(idx)
895 }
896
897 #[inline]
898 unsafe fn get_unchecked(this: &mut Self, i: Self::Index) -> Self::Item {
899 let ptr = this.rb().ptr_inbounds_at_mut(i);
900 &mut *ptr
901 }
902
903 #[inline(always)]
904 unsafe fn next_unchecked<'a>(slice: &mut <Self::Slice as SliceFamily<'a, Self::Item>>::Slice) -> Self::Item {
905 let (head, tail) = core::mem::take(slice).split_first_mut().unwrap_unchecked();
906 *slice = tail;
907 head
908 }
909
910 #[inline(always)]
911 fn is_contiguous(this: &Self) -> bool {
912 this.col_stride().element_stride() == 1
913 }
914
915 #[inline(always)]
916 fn preferred_layout(this: &Self) -> Self::LayoutTransform {
917 let strd = this.col_stride().element_stride();
918 let len = this.ncols().unbound();
919
920 if len > 1 && strd == 1 {
921 VecLayoutTransform::None
922 } else if len > 1 && strd == -1 {
923 VecLayoutTransform::Reverse
924 } else {
925 VecLayoutTransform::None
926 }
927 }
928
929 #[inline(always)]
930 fn with_layout(this: Self, layout: Self::LayoutTransform) -> Self::Dyn {
931 use VecLayoutTransform::*;
932 let this = this.as_dyn_cols_mut().as_dyn_stride_mut();
933 match layout {
934 None => this,
935 Reverse => this.reverse_cols_mut(),
936 }
937 }
938}
939
940impl<'b, T, Len: Shape, Strd: Stride> MatIndex for ColRef<'b, T, Len, Strd> {
941 type Cols = ();
942 type Dyn = ColRef<'b, T, usize, isize>;
943 type Index = Idx<Len>;
944 type Item = &'b T;
945 type Kind = kind::Col;
946 type LayoutTransform = VecLayoutTransform;
947 type Rows = Len;
948 type Slice = SliceRef<'b, T>;
949
950 #[inline]
951 fn nrows(this: &Self) -> Self::Rows {
952 this.nrows()
953 }
954
955 #[inline]
956 fn ncols(_: &Self) -> Self::Cols {
957 ()
958 }
959
960 #[inline]
961 unsafe fn get_slice_unchecked<'a>(this: &'a mut Self, idx: Self::Index, n_elems: usize) -> <Self::Slice as SliceFamily<'a, Self::Item>>::Slice {
962 let ptr = this.ptr_inbounds_at(idx);
963 core::slice::from_raw_parts(ptr, n_elems)
964 }
965
966 #[inline]
967 unsafe fn from_dyn_idx(idx: <Self::Dyn as MatIndex>::Index) -> Self::Index {
968 Idx::<Len>::new_unbound(idx)
969 }
970
971 #[inline]
972 unsafe fn get_unchecked(this: &mut Self, i: Self::Index) -> Self::Item {
973 let ptr = this.rb().ptr_inbounds_at(i);
974 &*ptr
975 }
976
977 #[inline(always)]
978 unsafe fn next_unchecked<'a>(slice: &mut <Self::Slice as SliceFamily<'a, Self::Item>>::Slice) -> Self::Item {
979 let (head, tail) = core::mem::take(slice).split_first().unwrap_unchecked();
980 *slice = tail;
981 head
982 }
983
984 #[inline(always)]
985 fn is_contiguous(this: &Self) -> bool {
986 this.row_stride().element_stride() == 1
987 }
988
989 #[inline(always)]
990 fn preferred_layout(this: &Self) -> Self::LayoutTransform {
991 let strd = this.row_stride().element_stride();
992 let len = this.nrows().unbound();
993
994 if len > 1 && strd == 1 {
995 VecLayoutTransform::None
996 } else if len > 1 && strd == -1 {
997 VecLayoutTransform::Reverse
998 } else {
999 VecLayoutTransform::None
1000 }
1001 }
1002
1003 #[inline(always)]
1004 fn with_layout(this: Self, layout: Self::LayoutTransform) -> Self::Dyn {
1005 use VecLayoutTransform::*;
1006 let this = this.as_dyn_rows().as_dyn_stride();
1007 match layout {
1008 None => this,
1009 Reverse => this.reverse_rows(),
1010 }
1011 }
1012}
1013
1014impl<'b, T, Len: Shape, Strd: Stride> MatIndex for diag::DiagRef<'b, T, Len, Strd> {
1015 type Cols = Len;
1016 type Dyn = diag::DiagRef<'b, T, usize, isize>;
1017 type Index = Idx<Len>;
1018 type Item = &'b T;
1019 type Kind = kind::Diag;
1020 type LayoutTransform = VecLayoutTransform;
1021 type Rows = Len;
1022 type Slice = SliceRef<'b, T>;
1023
1024 #[inline]
1025 fn nrows(this: &Self) -> Self::Rows {
1026 this.dim()
1027 }
1028
1029 #[inline]
1030 fn ncols(this: &Self) -> Self::Cols {
1031 this.dim()
1032 }
1033
1034 #[inline]
1035 unsafe fn get_slice_unchecked<'a>(this: &'a mut Self, idx: Self::Index, n_elems: usize) -> <Self::Slice as SliceFamily<'a, Self::Item>>::Slice {
1036 let ptr = this.column_vector().ptr_inbounds_at(idx);
1037 core::slice::from_raw_parts(ptr, n_elems)
1038 }
1039
1040 #[inline]
1041 unsafe fn from_dyn_idx(idx: <Self::Dyn as MatIndex>::Index) -> Self::Index {
1042 Idx::<Len>::new_unbound(idx)
1043 }
1044
1045 #[inline]
1046 unsafe fn get_unchecked(this: &mut Self, i: Self::Index) -> Self::Item {
1047 let ptr = this.column_vector().ptr_inbounds_at(i);
1048 &*ptr
1049 }
1050
1051 #[inline(always)]
1052 unsafe fn next_unchecked<'a>(slice: &mut <Self::Slice as SliceFamily<'a, Self::Item>>::Slice) -> Self::Item {
1053 let (head, tail) = core::mem::take(slice).split_first().unwrap_unchecked();
1054 *slice = tail;
1055 head
1056 }
1057
1058 #[inline(always)]
1059 fn is_contiguous(this: &Self) -> bool {
1060 this.stride().element_stride() == 1
1061 }
1062
1063 #[inline(always)]
1064 fn preferred_layout(this: &Self) -> Self::LayoutTransform {
1065 let strd = this.stride().element_stride();
1066 let len = this.dim().unbound();
1067
1068 if len > 1 && strd == 1 {
1069 VecLayoutTransform::None
1070 } else if len > 1 && strd == -1 {
1071 VecLayoutTransform::Reverse
1072 } else {
1073 VecLayoutTransform::None
1074 }
1075 }
1076
1077 #[inline(always)]
1078 fn with_layout(this: Self, layout: Self::LayoutTransform) -> Self::Dyn {
1079 use VecLayoutTransform::*;
1080 let this = this.as_dyn().as_dyn_stride();
1081 match layout {
1082 None => this,
1083 Reverse => this.column_vector().reverse_rows().as_diagonal(),
1084 }
1085 }
1086}
1087
1088impl<'b, T, Len: Shape, Strd: Stride> MatIndex for RowRef<'b, T, Len, Strd> {
1089 type Cols = Len;
1090 type Dyn = RowRef<'b, T, usize, isize>;
1091 type Index = Idx<Len>;
1092 type Item = &'b T;
1093 type Kind = kind::Row;
1094 type LayoutTransform = VecLayoutTransform;
1095 type Rows = ();
1096 type Slice = SliceRef<'b, T>;
1097
1098 #[inline]
1099 fn nrows(_: &Self) -> Self::Rows {
1100 ()
1101 }
1102
1103 #[inline]
1104 fn ncols(this: &Self) -> Self::Cols {
1105 this.ncols()
1106 }
1107
1108 #[inline]
1109 unsafe fn get_slice_unchecked<'a>(this: &'a mut Self, idx: Self::Index, n_elems: usize) -> <Self::Slice as SliceFamily<'a, Self::Item>>::Slice {
1110 let ptr = this.ptr_inbounds_at(idx);
1111 core::slice::from_raw_parts(ptr, n_elems)
1112 }
1113
1114 #[inline]
1115 unsafe fn from_dyn_idx(idx: <Self::Dyn as MatIndex>::Index) -> Self::Index {
1116 Idx::<Len>::new_unbound(idx)
1117 }
1118
1119 #[inline]
1120 unsafe fn get_unchecked(this: &mut Self, i: Self::Index) -> Self::Item {
1121 let ptr = this.rb().ptr_inbounds_at(i);
1122 &*ptr
1123 }
1124
1125 #[inline(always)]
1126 unsafe fn next_unchecked<'a>(slice: &mut <Self::Slice as SliceFamily<'a, Self::Item>>::Slice) -> Self::Item {
1127 let (head, tail) = core::mem::take(slice).split_first().unwrap_unchecked();
1128 *slice = tail;
1129 head
1130 }
1131
1132 #[inline(always)]
1133 fn is_contiguous(this: &Self) -> bool {
1134 this.col_stride().element_stride() == 1
1135 }
1136
1137 #[inline(always)]
1138 fn preferred_layout(this: &Self) -> Self::LayoutTransform {
1139 let strd = this.col_stride().element_stride();
1140 let len = this.ncols().unbound();
1141
1142 if len > 1 && strd == 1 {
1143 VecLayoutTransform::None
1144 } else if len > 1 && strd == -1 {
1145 VecLayoutTransform::Reverse
1146 } else {
1147 VecLayoutTransform::None
1148 }
1149 }
1150
1151 #[inline(always)]
1152 fn with_layout(this: Self, layout: Self::LayoutTransform) -> Self::Dyn {
1153 use VecLayoutTransform::*;
1154 let this = this.as_dyn_cols().as_dyn_stride();
1155 match layout {
1156 None => this,
1157 Reverse => this.reverse_cols(),
1158 }
1159 }
1160}
1161
1162#[inline(always)]
1163fn annotate_noalias_mat<Z: MatIndex>(
1164 f: &mut impl FnMut(<Z as MatIndex>::Item),
1165 mut slice: <Z::Slice as SliceFamily<'_, Z::Item>>::Slice,
1166 i_begin: usize,
1167 i_end: usize,
1168 _j: usize,
1169) {
1170 for _ in i_begin..i_end {
1171 unsafe { f(Z::next_unchecked(&mut slice)) };
1172 }
1173}
1174
1175#[inline(always)]
1176fn annotate_noalias_mat_with_index<Z: MatIndex<Index = (RowIdx, ColIdx)>, RowIdx, ColIdx>(
1177 f: &mut impl FnMut(RowIdx, ColIdx, <Z as MatIndex>::Item),
1178 mut slice: <Z::Slice as SliceFamily<'_, Z::Item>>::Slice,
1179 i_begin: usize,
1180 i_end: usize,
1181 j: usize,
1182 transpose: bool,
1183 reverse_rows: bool,
1184) where
1185 Z::Dyn: MatIndex<Index = (usize, usize)>,
1186{
1187 if !transpose {
1188 if !reverse_rows {
1189 for i in i_begin..i_end {
1190 unsafe {
1191 let (ii, jj) = Z::from_dyn_idx((i, j));
1192 f(ii, jj, Z::next_unchecked(&mut slice))
1193 };
1194 }
1195 } else {
1196 for i in i_begin..i_end {
1197 unsafe {
1198 let (ii, jj) = Z::from_dyn_idx((i_begin + (i_end - i - 1), j));
1199 f(ii, jj, Z::next_unchecked(&mut slice))
1200 };
1201 }
1202 }
1203 } else {
1204 if !reverse_rows {
1205 for i in i_begin..i_end {
1206 unsafe {
1207 let (ii, jj) = Z::from_dyn_idx((j, i));
1208 f(ii, jj, Z::next_unchecked(&mut slice))
1209 };
1210 }
1211 } else {
1212 for i in i_begin..i_end {
1213 unsafe {
1214 let (ii, jj) = Z::from_dyn_idx((j, i_begin + (i_end - i - 1)));
1215 f(ii, jj, Z::next_unchecked(&mut slice))
1216 };
1217 }
1218 }
1219 }
1220}
1221
1222#[inline(always)]
1223fn annotate_noalias_col<Z: MatIndex>(
1224 f: &mut impl FnMut(<Z as MatIndex>::Item),
1225 mut slice: <Z::Slice as SliceFamily<'_, Z::Item>>::Slice,
1226 i_begin: usize,
1227 i_end: usize,
1228) {
1229 for _ in i_begin..i_end {
1230 unsafe { f(Z::next_unchecked(&mut slice)) };
1231 }
1232}
1233
1234#[inline(always)]
1235fn annotate_noalias_col_with_index<Z: MatIndex<Index = Idx>, Idx>(
1236 f: &mut impl FnMut(Idx, <Z as MatIndex>::Item),
1237 mut slice: <Z::Slice as SliceFamily<'_, Z::Item>>::Slice,
1238 i_begin: usize,
1239 i_end: usize,
1240 reverse: bool,
1241) where
1242 Z::Dyn: MatIndex<Item = Z::Item, Index = usize>,
1243{
1244 if !reverse {
1245 for i in i_begin..i_end {
1246 unsafe {
1247 let ii = Z::from_dyn_idx(i);
1248 f(ii, Z::next_unchecked(&mut slice))
1249 };
1250 }
1251 } else {
1252 for i in i_begin..i_end {
1253 unsafe {
1254 let ii = Z::from_dyn_idx(i_begin + (i_end - i - 1));
1255 f(ii, Z::next_unchecked(&mut slice))
1256 };
1257 }
1258 }
1259}
1260
1261#[inline(always)]
1262fn for_each_mat<Z: MatIndex>(z: Z, mut f: impl FnMut(<Z as MatIndex>::Item))
1263where
1264 Z::Dyn: MatIndex<Item = Z::Item, Slice = Z::Slice, Rows = usize, Cols = usize, Index = (usize, usize)>,
1265{
1266 let layout = Z::preferred_layout(&z);
1267 let mut z = Z::with_layout(z, layout);
1268
1269 let m = Z::Dyn::nrows(&z);
1270 let n = Z::Dyn::ncols(&z);
1271 if m == 0 || n == 0 {
1272 return;
1273 }
1274
1275 unsafe {
1276 if Z::Dyn::is_contiguous(&z) {
1277 for j in 0..n {
1278 annotate_noalias_mat::<Z::Dyn>(&mut f, Z::Dyn::get_slice_unchecked(&mut z, (0, j), m), 0, m, j);
1279 }
1280 } else {
1281 for j in 0..n {
1282 for i in 0..m {
1283 f(Z::Dyn::get_unchecked(&mut z, (i, j)))
1284 }
1285 }
1286 }
1287 }
1288}
1289
1290#[inline(always)]
1294fn for_each_mat_with_index<RowIdx, ColIdx, Z: MatIndex<Index = (RowIdx, ColIdx), LayoutTransform = MatLayoutTransform>>(
1295 z: Z,
1296 mut f: impl FnMut(RowIdx, ColIdx, <Z as MatIndex>::Item),
1297) where
1298 Z::Dyn: MatIndex<Rows = usize, Cols = usize, Index = (usize, usize), Slice = Z::Slice, Item = Z::Item>,
1299{
1300 let layout = Z::preferred_layout(&z);
1301 let mut z = Z::with_layout(z, layout);
1302
1303 let m = Z::Dyn::nrows(&z);
1304 let n = Z::Dyn::ncols(&z);
1305 if m == 0 || n == 0 {
1306 return;
1307 }
1308
1309 match layout {
1310 MatLayoutTransform::None => unsafe {
1311 if Z::Dyn::is_contiguous(&z) {
1312 for j in 0..n {
1313 annotate_noalias_mat_with_index::<Z, _, _>(&mut f, Z::Dyn::get_slice_unchecked(&mut z, (0, j), m), 0, m, j, false, false);
1314 }
1315 } else {
1316 for j in 0..n {
1317 for i in 0..m {
1318 let (ii, jj) = Z::from_dyn_idx((i, j));
1319 f(ii, jj, Z::Dyn::get_unchecked(&mut z, (i, j)))
1320 }
1321 }
1322 }
1323 },
1324 MatLayoutTransform::ReverseRows => unsafe {
1325 if Z::Dyn::is_contiguous(&z) {
1326 for j in 0..n {
1327 annotate_noalias_mat_with_index::<Z, _, _>(&mut f, Z::Dyn::get_slice_unchecked(&mut z, (0, j), m), 0, m, j, false, true);
1328 }
1329 } else {
1330 for j in 0..n {
1331 for i in 0..m {
1332 let (ii, jj) = Z::from_dyn_idx((m - i - 1, j));
1333 f(ii, jj, Z::Dyn::get_unchecked(&mut z, (i, j)))
1334 }
1335 }
1336 }
1337 },
1338 MatLayoutTransform::Transpose => unsafe {
1339 if Z::Dyn::is_contiguous(&z) {
1340 for j in 0..n {
1341 annotate_noalias_mat_with_index::<Z, _, _>(&mut f, Z::Dyn::get_slice_unchecked(&mut z, (0, j), m), 0, m, j, true, false);
1342 }
1343 } else {
1344 for j in 0..n {
1345 for i in 0..m {
1346 let (ii, jj) = Z::from_dyn_idx((j, i));
1347 f(ii, jj, Z::Dyn::get_unchecked(&mut z, (i, j)))
1348 }
1349 }
1350 }
1351 },
1352 MatLayoutTransform::TransposeReverseRows => unsafe {
1353 if Z::Dyn::is_contiguous(&z) {
1354 for j in 0..n {
1355 annotate_noalias_mat_with_index::<Z, _, _>(&mut f, Z::Dyn::get_slice_unchecked(&mut z, (0, j), m), 0, m, j, true, true);
1356 }
1357 } else {
1358 for j in 0..n {
1359 for i in 0..m {
1360 let (ii, jj) = Z::from_dyn_idx((j, m - i - 1));
1361 f(ii, jj, Z::Dyn::get_unchecked(&mut z, (i, j)))
1362 }
1363 }
1364 }
1365 },
1366 }
1367}
1368
1369#[inline(always)]
1370fn for_each_mat_triangular_lower_with_index<RowIdx, ColIdx, Z: MatIndex<Index = (RowIdx, ColIdx), LayoutTransform = MatLayoutTransform>>(
1371 z: Z,
1372 diag: Diag,
1373 mut f: impl FnMut(RowIdx, ColIdx, <Z as MatIndex>::Item),
1374) where
1375 Z::Dyn: MatIndex<Rows = usize, Cols = usize, Index = (usize, usize), Item = Z::Item, Slice = Z::Slice>,
1376{
1377 let layout = Z::preferred_layout(&z);
1378 let mut z = Z::with_layout(z, layout);
1379
1380 let m = Z::Dyn::nrows(&z);
1381 let n = Z::Dyn::ncols(&z);
1382 let strict = match diag {
1383 Diag::Skip => true,
1384 Diag::Include => false,
1385 };
1386 let strict = strict as usize;
1387
1388 if m == 0 || n == 0 {
1389 return;
1390 }
1391
1392 match layout {
1393 MatLayoutTransform::None => unsafe {
1394 if Z::Dyn::is_contiguous(&z) {
1395 for j in 0..n {
1396 let start = j + strict;
1397 let end = m;
1398 if start == end {
1399 continue;
1400 }
1401 annotate_noalias_mat_with_index::<Z, _, _>(
1402 &mut f,
1403 Z::Dyn::get_slice_unchecked(&mut z, (start, j), end - start),
1404 start,
1405 end,
1406 j,
1407 false,
1408 false,
1409 );
1410 }
1411 } else {
1412 for j in 0..n {
1413 let start = j + strict;
1414 let end = m;
1415 if start == end {
1416 continue;
1417 }
1418 for i in start..end {
1419 let (ii, jj) = Z::from_dyn_idx((i, j));
1420 f(ii, jj, Z::Dyn::get_unchecked(&mut z, (i, j)))
1421 }
1422 }
1423 }
1424 },
1425 MatLayoutTransform::ReverseRows => unsafe {
1426 if Z::Dyn::is_contiguous(&z) {
1427 for j in 0..Ord::min(m, n) {
1428 let start = 0;
1429 let end = m - j - strict;
1430 if start == end {
1431 continue;
1432 }
1433 annotate_noalias_mat_with_index::<Z, _, _>(
1434 &mut f,
1435 Z::Dyn::get_slice_unchecked(&mut z, (start, j), end - start),
1436 j + strict + start,
1437 j + strict + end,
1438 j,
1439 false,
1440 true,
1441 );
1442 }
1443 } else {
1444 for j in 0..Ord::min(m, n) {
1445 let start = 0;
1446 let end = m - j - strict;
1447 if start == end {
1448 continue;
1449 }
1450 for i in start..end {
1451 let (ii, jj) = Z::from_dyn_idx((m - i - 1, j));
1452 f(ii, jj, Z::Dyn::get_unchecked(&mut z, (i, j)))
1453 }
1454 }
1455 }
1456 },
1457 MatLayoutTransform::Transpose => unsafe {
1458 if Z::Dyn::is_contiguous(&z) {
1459 for j in 0..n {
1460 let start = 0;
1461 let end = Ord::min(m, j + (1 - strict));
1462 if start == end {
1463 continue;
1464 }
1465 annotate_noalias_mat_with_index::<Z, _, _>(
1466 &mut f,
1467 Z::Dyn::get_slice_unchecked(&mut z, (0, j), end - start),
1468 start,
1469 end,
1470 j,
1471 true,
1472 false,
1473 );
1474 }
1475 } else {
1476 for j in 0..n {
1477 let start = 0;
1478 let end = Ord::min(m, j + (1 - strict));
1479 if start == end {
1480 continue;
1481 }
1482 for i in start..end {
1483 let (ii, jj) = Z::from_dyn_idx((j, i));
1484 f(ii, jj, Z::Dyn::get_unchecked(&mut z, (i, j)))
1485 }
1486 }
1487 }
1488 },
1489 MatLayoutTransform::TransposeReverseRows => unsafe {
1490 if Z::Dyn::is_contiguous(&z) {
1491 for j in 0..n {
1492 let start = m - Ord::min(j + (1 - strict) as usize, m);
1493 let end = m;
1494 if start == end {
1495 continue;
1496 }
1497 annotate_noalias_mat_with_index::<Z, _, _>(
1498 &mut f,
1499 Z::Dyn::get_slice_unchecked(&mut z, (start, j), end - start),
1500 0,
1501 end - start,
1502 j,
1503 true,
1504 true,
1505 );
1506 }
1507 } else {
1508 for j in 0..n {
1509 let start = m - Ord::min(j + (1 - strict) as usize, m);
1510 let end = m;
1511 if start == end {
1512 continue;
1513 }
1514 for i in start..end {
1515 let (ii, jj) = Z::from_dyn_idx((j, m - i - 1));
1516 f(ii, jj, Z::Dyn::get_unchecked(&mut z, (i, j)))
1517 }
1518 }
1519 }
1520 },
1521 }
1522}
1523
1524#[inline(always)]
1525fn for_each_mat_triangular_upper_with_index<RowIdx, ColIdx, Z: MatIndex<Index = (RowIdx, ColIdx), LayoutTransform = MatLayoutTransform>>(
1526 z: Z,
1527 diag: Diag,
1528 mut f: impl FnMut(RowIdx, ColIdx, <Z as MatIndex>::Item),
1529) where
1530 Z::Dyn: MatIndex<Rows = usize, Cols = usize, Index = (usize, usize), Item = Z::Item, Slice = Z::Slice>,
1531{
1532 let layout = Z::preferred_layout(&z);
1533 let mut z = Z::with_layout(z, layout);
1534
1535 let m = Z::Dyn::nrows(&z);
1536 let n = Z::Dyn::ncols(&z);
1537 let strict = match diag {
1538 Diag::Skip => true,
1539 Diag::Include => false,
1540 };
1541 let strict = strict as usize;
1542
1543 if m == 0 || n == 0 {
1544 return;
1545 }
1546
1547 match layout {
1548 MatLayoutTransform::None => unsafe {
1549 if Z::Dyn::is_contiguous(&z) {
1550 for j in 0..n {
1551 let start = 0;
1552 let end = Ord::min(m, j + (1 - strict));
1553 if start == end {
1554 continue;
1555 }
1556
1557 annotate_noalias_mat_with_index::<Z, _, _>(
1558 &mut f,
1559 Z::Dyn::get_slice_unchecked(&mut z, (start, j), end - start),
1560 start,
1561 end,
1562 j,
1563 false,
1564 false,
1565 );
1566 }
1567 } else {
1568 for j in 0..n {
1569 let start = 0;
1570 let end = Ord::min(m, j + (1 - strict));
1571 if start == end {
1572 continue;
1573 }
1574 for i in start..end {
1575 let (ii, jj) = Z::from_dyn_idx((i, j));
1576 f(ii, jj, Z::Dyn::get_unchecked(&mut z, (i, j)))
1577 }
1578 }
1579 }
1580 },
1581 MatLayoutTransform::ReverseRows => unsafe {
1582 if Z::Dyn::is_contiguous(&z) {
1583 for j in 0..Ord::min(m, n) {
1584 let start = m - Ord::min(j + (1 - strict) as usize, m);
1585 let end = m;
1586 if start == end {
1587 continue;
1588 }
1589 annotate_noalias_mat_with_index::<Z, _, _>(
1590 &mut f,
1591 Z::Dyn::get_slice_unchecked(&mut z, (start, j), end - start),
1592 0,
1593 end - start,
1594 j,
1595 false,
1596 true,
1597 );
1598 }
1599 } else {
1600 for j in 0..Ord::min(m, n) {
1601 let start = m - Ord::min(j + (1 - strict) as usize, m);
1602 let end = m;
1603 if start == end {
1604 continue;
1605 }
1606 for i in start..end {
1607 let (ii, jj) = Z::from_dyn_idx((m - i - 1, j));
1608 f(ii, jj, Z::Dyn::get_unchecked(&mut z, (i, j)))
1609 }
1610 }
1611 }
1612 },
1613 MatLayoutTransform::Transpose => unsafe {
1614 if Z::Dyn::is_contiguous(&z) {
1615 for j in 0..n {
1616 let start = j + strict;
1617 let end = m;
1618 if start == end {
1619 continue;
1620 }
1621 annotate_noalias_mat_with_index::<Z, _, _>(
1622 &mut f,
1623 Z::Dyn::get_slice_unchecked(&mut z, (start, j), end - start),
1624 start,
1625 end,
1626 j,
1627 true,
1628 false,
1629 );
1630 }
1631 } else {
1632 for j in 0..n {
1633 let start = j + strict;
1634 let end = m;
1635 if start == end {
1636 continue;
1637 }
1638 for i in start..end {
1639 let (ii, jj) = Z::from_dyn_idx((j, i));
1640 f(ii, jj, Z::Dyn::get_unchecked(&mut z, (i, j)))
1641 }
1642 }
1643 }
1644 },
1645 MatLayoutTransform::TransposeReverseRows => unsafe {
1646 if Z::Dyn::is_contiguous(&z) {
1647 for j in 0..n {
1648 let start = 0;
1649 let end = m - j - strict;
1650 if start == end {
1651 continue;
1652 }
1653 annotate_noalias_mat_with_index::<Z, _, _>(
1654 &mut f,
1655 Z::Dyn::get_slice_unchecked(&mut z, (start, j), end - start),
1656 j + strict,
1657 j + strict + end - start,
1658 j,
1659 true,
1660 true,
1661 );
1662 }
1663 } else {
1664 for j in 0..n {
1665 let start = 0;
1666 let end = m - j - strict;
1667 if start == end {
1668 continue;
1669 }
1670 for i in start..end {
1671 let (ii, jj) = Z::from_dyn_idx((j, m - i - 1));
1672 f(ii, jj, Z::Dyn::get_unchecked(&mut z, (i, j)))
1673 }
1674 }
1675 }
1676 },
1677 }
1678}
1679
1680#[inline(always)]
1681fn for_each_mat_triangular_lower<Z: MatIndex<LayoutTransform = MatLayoutTransform>>(
1682 z: Z,
1683 diag: Diag,
1684 transpose: bool,
1685 mut f: impl FnMut(<Z as MatIndex>::Item),
1686) where
1687 Z::Dyn: MatIndex<
1688 LayoutTransform = MatLayoutTransform,
1689 Item = Z::Item,
1690 Slice = Z::Slice,
1691 Rows = usize,
1692 Cols = usize,
1693 Index = (usize, usize),
1694 Dyn = Z::Dyn,
1695 >,
1696{
1697 use MatLayoutTransform::*;
1698
1699 let z = if transpose {
1700 Z::with_layout(z, MatLayoutTransform::Transpose)
1701 } else {
1702 Z::with_layout(z, MatLayoutTransform::None)
1703 };
1704 let layout = Z::Dyn::preferred_layout(&z);
1705 let mut z = Z::Dyn::with_layout(z, layout);
1706
1707 let m = Z::Dyn::nrows(&z);
1708 let n = Z::Dyn::ncols(&z);
1709 let n = match layout {
1710 None | ReverseRows => Ord::min(m, n),
1711 Transpose | TransposeReverseRows => n,
1712 };
1713 if m == 0 || n == 0 {
1714 return;
1715 }
1716
1717 let strict = match diag {
1718 Diag::Skip => true,
1719 Diag::Include => false,
1720 };
1721
1722 unsafe {
1723 if Z::Dyn::is_contiguous(&z) {
1724 for j in 0..n {
1725 let (start, end) = match layout {
1726 None => (j + strict as usize, m),
1727 ReverseRows => (0, (m - (j + strict as usize))),
1728 Transpose => (0, (j + !strict as usize).min(m)),
1729 TransposeReverseRows => (m - ((j + !strict as usize).min(m)), m),
1730 };
1731
1732 let len = end - start;
1733 if start == end {
1734 continue;
1735 }
1736
1737 annotate_noalias_mat::<Z::Dyn>(&mut f, Z::Dyn::get_slice_unchecked(&mut z, (start, j), len), start, end, j);
1738 }
1739 } else {
1740 for j in 0..n {
1741 let (start, end) = match layout {
1742 None => (j + strict as usize, m),
1743 ReverseRows => (0, (m - (j + strict as usize))),
1744 Transpose => (0, (j + !strict as usize).min(m)),
1745 TransposeReverseRows => (m - ((j + !strict as usize).min(m)), m),
1746 };
1747 if start == end {
1748 continue;
1749 }
1750
1751 for i in start..end {
1752 f(Z::Dyn::get_unchecked(&mut z, (i, j)))
1753 }
1754 }
1755 }
1756 }
1757}
1758
1759#[inline(always)]
1760fn for_each_diag<Z: MatIndex>(z: Z, mut f: impl FnMut(<Z as MatIndex>::Item))
1761where
1762 Z::Dyn: MatIndex<Rows = usize, Cols = usize, Index = usize, Item = Z::Item, Slice = Z::Slice>,
1763{
1764 let layout = Z::preferred_layout(&z);
1765 let mut z = Z::with_layout(z, layout);
1766
1767 let m = Z::Dyn::nrows(&z);
1768 if m == 0 {
1769 return;
1770 }
1771
1772 unsafe {
1773 if Z::Dyn::is_contiguous(&z) {
1774 annotate_noalias_col::<Z::Dyn>(&mut f, Z::Dyn::get_slice_unchecked(&mut z, 0, m), 0, m);
1775 } else {
1776 for i in 0..m {
1777 f(Z::Dyn::get_unchecked(&mut z, i))
1778 }
1779 }
1780 }
1781}
1782
1783#[inline(always)]
1784fn for_each_diag_with_index<Idx, Z: MatIndex<LayoutTransform = VecLayoutTransform, Index = Idx>>(z: Z, mut f: impl FnMut(Idx, <Z as MatIndex>::Item))
1785where
1786 Z::Dyn: MatIndex<Rows = usize, Cols = usize, Index = usize, Item = Z::Item, Slice = Z::Slice>,
1787{
1788 let layout = Z::preferred_layout(&z);
1789 let mut z = Z::with_layout(z, layout);
1790
1791 let m = Z::Dyn::nrows(&z);
1792 if m == 0 {
1793 return;
1794 }
1795
1796 unsafe {
1797 match layout {
1798 VecLayoutTransform::None => {
1799 if Z::Dyn::is_contiguous(&z) {
1800 annotate_noalias_col_with_index::<Z, _>(&mut f, Z::Dyn::get_slice_unchecked(&mut z, 0, m), 0, m, false);
1801 } else {
1802 for i in 0..m {
1803 f(Z::from_dyn_idx(i), Z::Dyn::get_unchecked(&mut z, i))
1804 }
1805 }
1806 },
1807 VecLayoutTransform::Reverse => {
1808 if Z::Dyn::is_contiguous(&z) {
1809 annotate_noalias_col_with_index::<Z, _>(&mut f, Z::Dyn::get_slice_unchecked(&mut z, 0, m), 0, m, true);
1810 } else {
1811 for i in 0..m {
1812 f(Z::from_dyn_idx(m - i - 1), Z::Dyn::get_unchecked(&mut z, i))
1813 }
1814 }
1815 },
1816 }
1817 }
1818}
1819
1820#[inline(always)]
1821fn for_each_col<Z: MatIndex>(z: Z, mut f: impl FnMut(<Z as MatIndex>::Item))
1822where
1823 Z::Dyn: MatIndex<Rows = usize, Cols = (), Index = usize, Item = Z::Item, Slice = Z::Slice>,
1824{
1825 let layout = Z::preferred_layout(&z);
1826 let mut z = Z::with_layout(z, layout);
1827
1828 let m = Z::Dyn::nrows(&z);
1829 if m == 0 {
1830 return;
1831 }
1832
1833 unsafe {
1834 if Z::Dyn::is_contiguous(&z) {
1835 annotate_noalias_col::<Z::Dyn>(&mut f, Z::Dyn::get_slice_unchecked(&mut z, 0, m), 0, m);
1836 } else {
1837 for i in 0..m {
1838 f(Z::Dyn::get_unchecked(&mut z, i))
1839 }
1840 }
1841 }
1842}
1843
1844#[inline(always)]
1845fn for_each_col_with_index<Idx, Z: MatIndex<LayoutTransform = VecLayoutTransform, Index = Idx>>(z: Z, mut f: impl FnMut(Idx, <Z as MatIndex>::Item))
1846where
1847 Z::Dyn: MatIndex<Rows = usize, Cols = (), Index = usize, Item = Z::Item, Slice = Z::Slice>,
1848{
1849 let layout = Z::preferred_layout(&z);
1850 let mut z = Z::with_layout(z, layout);
1851
1852 let m = Z::Dyn::nrows(&z);
1853 if m == 0 {
1854 return;
1855 }
1856
1857 unsafe {
1858 match layout {
1859 VecLayoutTransform::None => {
1860 if Z::Dyn::is_contiguous(&z) {
1861 annotate_noalias_col_with_index::<Z, _>(&mut f, Z::Dyn::get_slice_unchecked(&mut z, 0, m), 0, m, false);
1862 } else {
1863 for i in 0..m {
1864 f(Z::from_dyn_idx(i), Z::Dyn::get_unchecked(&mut z, i))
1865 }
1866 }
1867 },
1868 VecLayoutTransform::Reverse => {
1869 if Z::Dyn::is_contiguous(&z) {
1870 annotate_noalias_col_with_index::<Z, _>(&mut f, Z::Dyn::get_slice_unchecked(&mut z, 0, m), 0, m, true);
1871 } else {
1872 for i in 0..m {
1873 f(Z::from_dyn_idx(m - i - 1), Z::Dyn::get_unchecked(&mut z, i))
1874 }
1875 }
1876 },
1877 }
1878 }
1879}
1880
1881#[inline(always)]
1882fn for_each_row_with_index<Idx, Z: MatIndex<LayoutTransform = VecLayoutTransform, Index = Idx>>(z: Z, mut f: impl FnMut(Idx, <Z as MatIndex>::Item))
1883where
1884 Z::Dyn: MatIndex<Rows = (), Cols = usize, Index = usize, Item = Z::Item, Slice = Z::Slice>,
1885{
1886 let layout = Z::preferred_layout(&z);
1887 let mut z = Z::with_layout(z, layout);
1888
1889 let n = Z::Dyn::ncols(&z);
1890 if n == 0 {
1891 return;
1892 }
1893
1894 unsafe {
1895 match layout {
1896 VecLayoutTransform::None => {
1897 if Z::Dyn::is_contiguous(&z) {
1898 annotate_noalias_col_with_index::<Z, _>(&mut f, Z::Dyn::get_slice_unchecked(&mut z, 0, n), 0, n, false);
1899 } else {
1900 for i in 0..n {
1901 f(Z::from_dyn_idx(i), Z::Dyn::get_unchecked(&mut z, i))
1902 }
1903 }
1904 },
1905 VecLayoutTransform::Reverse => {
1906 if Z::Dyn::is_contiguous(&z) {
1907 annotate_noalias_col_with_index::<Z, _>(&mut f, Z::Dyn::get_slice_unchecked(&mut z, 0, n), 0, n, true);
1908 } else {
1909 for i in 0..n {
1910 f(Z::from_dyn_idx(n - i - 1), Z::Dyn::get_unchecked(&mut z, i))
1911 }
1912 }
1913 },
1914 }
1915 }
1916}
1917#[inline(always)]
1918fn for_each_row<Z: MatIndex>(z: Z, mut f: impl FnMut(<Z as MatIndex>::Item))
1919where
1920 Z::Dyn: MatIndex<Rows = (), Cols = usize, Index = usize, Item = Z::Item, Slice = Z::Slice>,
1921{
1922 let layout = Z::preferred_layout(&z);
1923 let mut z = Z::with_layout(z, layout);
1924
1925 let n = Z::Dyn::ncols(&z);
1926 if n == 0 {
1927 return;
1928 }
1929
1930 unsafe {
1931 if Z::Dyn::is_contiguous(&z) {
1932 annotate_noalias_col::<Z::Dyn>(&mut f, Z::Dyn::get_slice_unchecked(&mut z, 0, n), 0, n);
1933 } else {
1934 for j in 0..n {
1935 f(Z::Dyn::get_unchecked(&mut z, j))
1936 }
1937 }
1938 }
1939}
1940
1941impl<
1942 Rows: Shape,
1943 Cols: Shape,
1944 M: MatIndex<Kind = kind::Mat, LayoutTransform = MatLayoutTransform, Rows = Rows, Cols = Cols, Index = (Idx<Rows>, Idx<Cols>)>,
1945> LastEq<kind::Mat, M>
1946where
1947 M::Dyn: MatIndex<Rows = usize, Cols = usize, Index = (usize, usize)>,
1948{
1949 #[inline(always)]
1951 pub fn for_each(self, f: impl FnMut(<Self as MatIndex>::Item)) {
1952 for_each_mat(self, f);
1953 }
1954
1955 #[inline(always)]
1958 pub fn for_each_with_index(self, f: impl FnMut(Idx<Rows>, Idx<Cols>, <Self as MatIndex>::Item)) {
1959 for_each_mat_with_index(self, f);
1960 }
1961
1962 #[inline(always)]
1967 pub fn for_each_triangular_lower_with_index(self, diag: Diag, f: impl FnMut(Idx<Rows>, Idx<Cols>, <Self as MatIndex>::Item)) {
1968 for_each_mat_triangular_lower_with_index(self, diag, f);
1969 }
1970
1971 #[inline(always)]
1976 pub fn for_each_triangular_upper_with_index(self, diag: Diag, f: impl FnMut(Idx<Rows>, Idx<Cols>, <Self as MatIndex>::Item)) {
1977 for_each_mat_triangular_upper_with_index(self, diag, f);
1978 }
1979
1980 #[inline(always)]
1984 pub fn for_each_triangular_lower(self, diag: Diag, f: impl FnMut(<Self as MatIndex>::Item)) {
1985 for_each_mat_triangular_lower(self, diag, false, f);
1986 }
1987
1988 #[inline(always)]
1992 pub fn for_each_triangular_upper(self, diag: Diag, f: impl FnMut(<Self as MatIndex>::Item)) {
1993 for_each_mat_triangular_lower(self, diag, true, f);
1994 }
1995
1996 #[inline(always)]
1998 pub fn map<T>(self, f: impl FnMut(<Self as MatIndex>::Item) -> T) -> Mat<T, Rows, Cols> {
1999 let (m, n) = (Self::nrows(&self), Self::ncols(&self));
2000 let mut f = f;
2001 let mut this = self;
2002 Mat::from_fn(
2003 m,
2004 n,
2005 #[inline(always)]
2006 |i, j| f(unsafe { Self::get_unchecked(&mut this, (i, j)) }),
2007 )
2008 }
2009
2010 #[inline(always)]
2012 pub fn map_with_index<T>(self, f: impl FnMut(Idx<Rows>, Idx<Cols>, <Self as MatIndex>::Item) -> T) -> Mat<T, Rows, Cols> {
2013 let (m, n) = (Self::nrows(&self), Self::ncols(&self));
2014 let mut f = f;
2015 let mut this = self;
2016
2017 Mat::from_fn(
2018 m,
2019 n,
2020 #[inline(always)]
2021 |i, j| f(i, j, unsafe { Self::get_unchecked(&mut this, (i, j)) }),
2022 )
2023 }
2024}
2025
2026impl<
2027 Rows: Shape,
2028 Cols: Shape,
2029 L: MatIndex<Kind = kind::Mat, LayoutTransform = MatLayoutTransform, Rows = Rows, Cols = Cols, Index = (Idx<Rows>, Idx<Cols>)>,
2030 R: MatIndex<Kind = kind::Mat, LayoutTransform = MatLayoutTransform, Rows = Rows, Cols = Cols, Index = (Idx<Rows>, Idx<Cols>)>,
2031> ZipEq<kind::Mat, L, R>
2032where
2033 L::Dyn: MatIndex<Rows = usize, Cols = usize, Index = (usize, usize)>,
2034 R::Dyn: MatIndex<Rows = usize, Cols = usize, Index = (usize, usize)>,
2035{
2036 #[inline(always)]
2038 pub fn for_each(self, f: impl FnMut(<Self as MatIndex>::Item)) {
2039 for_each_mat(self, f);
2040 }
2041
2042 #[inline(always)]
2045 pub fn for_each_with_index(self, f: impl FnMut(Idx<Rows>, Idx<Cols>, <Self as MatIndex>::Item)) {
2046 for_each_mat_with_index(self, f);
2047 }
2048
2049 #[inline(always)]
2054 pub fn for_each_triangular_lower_with_index(self, diag: Diag, f: impl FnMut(Idx<Rows>, Idx<Cols>, <Self as MatIndex>::Item)) {
2055 for_each_mat_triangular_lower_with_index(self, diag, f);
2056 }
2057
2058 #[inline(always)]
2063 pub fn for_each_triangular_upper_with_index(self, diag: Diag, f: impl FnMut(Idx<Rows>, Idx<Cols>, <Self as MatIndex>::Item)) {
2064 for_each_mat_triangular_upper_with_index(self, diag, f);
2065 }
2066
2067 #[inline(always)]
2071 pub fn for_each_triangular_lower(self, diag: Diag, f: impl FnMut(<Self as MatIndex>::Item)) {
2072 for_each_mat_triangular_lower(self, diag, false, f);
2073 }
2074
2075 #[inline(always)]
2079 pub fn for_each_triangular_upper(self, diag: Diag, f: impl FnMut(<Self as MatIndex>::Item)) {
2080 for_each_mat_triangular_lower(self, diag, true, f);
2081 }
2082
2083 #[inline(always)]
2085 pub fn map<T>(self, f: impl FnMut(<Self as MatIndex>::Item) -> T) -> Mat<T, Rows, Cols> {
2086 let (m, n) = (Self::nrows(&self), Self::ncols(&self));
2087 let mut f = f;
2088 let mut this = self;
2089 Mat::from_fn(
2090 m,
2091 n,
2092 #[inline(always)]
2093 |i, j| f(unsafe { Self::get_unchecked(&mut this, (i, j)) }),
2094 )
2095 }
2096
2097 #[inline(always)]
2099 pub fn map_with_index<T>(self, f: impl FnMut(Idx<Rows>, Idx<Cols>, <Self as MatIndex>::Item) -> T) -> Mat<T, Rows, Cols> {
2100 let (m, n) = (Self::nrows(&self), Self::ncols(&self));
2101 let mut f = f;
2102 let mut this = self;
2103
2104 Mat::from_fn(
2105 m,
2106 n,
2107 #[inline(always)]
2108 |i, j| f(i, j, unsafe { Self::get_unchecked(&mut this, (i, j)) }),
2109 )
2110 }
2111}
2112
2113impl<Rows: Shape, M: MatIndex<Kind = kind::Col, LayoutTransform = VecLayoutTransform, Rows = Rows, Cols = (), Index = Idx<Rows>>> LastEq<kind::Col, M>
2114where
2115 M::Dyn: MatIndex<Rows = usize, Cols = (), Index = usize>,
2116{
2117 #[inline(always)]
2119 pub fn for_each(self, f: impl FnMut(<Self as MatIndex>::Item)) {
2120 for_each_col(self, f);
2121 }
2122
2123 #[inline(always)]
2126 pub fn for_each_with_index(self, f: impl FnMut(Idx<Rows>, <Self as MatIndex>::Item)) {
2127 for_each_col_with_index(self, f);
2128 }
2129
2130 #[inline(always)]
2132 pub fn map<T>(self, f: impl FnMut(<Self as MatIndex>::Item) -> T) -> Col<T, Rows> {
2133 let (m, _) = (Self::nrows(&self), Self::ncols(&self));
2134 let mut f = f;
2135 let mut this = self;
2136 Col::from_fn(
2137 m,
2138 #[inline(always)]
2139 |i| f(unsafe { Self::get_unchecked(&mut this, i) }),
2140 )
2141 }
2142
2143 #[inline(always)]
2145 pub fn map_with_index<T>(self, f: impl FnMut(Idx<Rows>, <Self as MatIndex>::Item) -> T) -> Col<T, Rows> {
2146 let (m, _) = (Self::nrows(&self), Self::ncols(&self));
2147 let mut f = f;
2148 let mut this = self;
2149
2150 Col::from_fn(
2151 m,
2152 #[inline(always)]
2153 |i| f(i, unsafe { Self::get_unchecked(&mut this, i) }),
2154 )
2155 }
2156}
2157
2158impl<
2159 Rows: Shape,
2160 L: MatIndex<Kind = kind::Col, LayoutTransform = VecLayoutTransform, Rows = Rows, Cols = (), Index = Idx<Rows>>,
2161 R: MatIndex<Kind = kind::Col, LayoutTransform = VecLayoutTransform, Rows = Rows, Cols = (), Index = Idx<Rows>>,
2162> ZipEq<kind::Col, L, R>
2163where
2164 L::Dyn: MatIndex<Rows = usize, Cols = (), Index = usize>,
2165 R::Dyn: MatIndex<Rows = usize, Cols = (), Index = usize>,
2166{
2167 #[inline(always)]
2169 pub fn for_each(self, f: impl FnMut(<Self as MatIndex>::Item)) {
2170 for_each_col(self, f);
2171 }
2172
2173 #[inline(always)]
2176 pub fn for_each_with_index(self, f: impl FnMut(Idx<Rows>, <Self as MatIndex>::Item)) {
2177 for_each_col_with_index(self, f);
2178 }
2179
2180 #[inline(always)]
2182 pub fn map<T>(self, f: impl FnMut(<Self as MatIndex>::Item) -> T) -> Col<T, Rows> {
2183 let (m, _) = (Self::nrows(&self), Self::ncols(&self));
2184 let mut f = f;
2185 let mut this = self;
2186 Col::from_fn(
2187 m,
2188 #[inline(always)]
2189 |i| f(unsafe { Self::get_unchecked(&mut this, i) }),
2190 )
2191 }
2192
2193 #[inline(always)]
2195 pub fn map_with_index<T>(self, f: impl FnMut(Idx<Rows>, <Self as MatIndex>::Item) -> T) -> Col<T, Rows> {
2196 let (m, _) = (Self::nrows(&self), Self::ncols(&self));
2197 let mut f = f;
2198 let mut this = self;
2199
2200 Col::from_fn(
2201 m,
2202 #[inline(always)]
2203 |i| f(i, unsafe { Self::get_unchecked(&mut this, i) }),
2204 )
2205 }
2206}
2207
2208impl<Dim: Shape, M: MatIndex<Kind = kind::Diag, LayoutTransform = VecLayoutTransform, Rows = Dim, Cols = Dim, Index = Idx<Dim>>> LastEq<kind::Diag, M>
2209where
2210 M::Dyn: MatIndex<Rows = usize, Cols = usize, Index = usize>,
2211{
2212 #[inline(always)]
2214 pub fn for_each(self, f: impl FnMut(<Self as MatIndex>::Item)) {
2215 for_each_diag(self, f);
2216 }
2217
2218 #[inline(always)]
2221 pub fn for_each_with_index(self, f: impl FnMut(Idx<Dim>, <Self as MatIndex>::Item)) {
2222 for_each_diag_with_index(self, f);
2223 }
2224
2225 #[inline(always)]
2227 pub fn map<T>(self, f: impl FnMut(<Self as MatIndex>::Item) -> T) -> diag::Diag<T, Dim> {
2228 let (m, _) = (Self::nrows(&self), Self::ncols(&self));
2229 let mut f = f;
2230 let mut this = self;
2231 Col::from_fn(
2232 m,
2233 #[inline(always)]
2234 |i| f(unsafe { Self::get_unchecked(&mut this, i) }),
2235 )
2236 .into_diagonal()
2237 }
2238
2239 #[inline(always)]
2241 pub fn map_with_index<T>(self, f: impl FnMut(Idx<Dim>, <Self as MatIndex>::Item) -> T) -> diag::Diag<T, Dim> {
2242 let (m, _) = (Self::nrows(&self), Self::ncols(&self));
2243 let mut f = f;
2244 let mut this = self;
2245
2246 Col::from_fn(
2247 m,
2248 #[inline(always)]
2249 |i| f(i, unsafe { Self::get_unchecked(&mut this, i) }),
2250 )
2251 .into_diagonal()
2252 }
2253}
2254
2255impl<
2256 Dim: Shape,
2257 L: MatIndex<Kind = kind::Diag, LayoutTransform = VecLayoutTransform, Rows = Dim, Cols = Dim, Index = Idx<Dim>>,
2258 R: MatIndex<Kind = kind::Diag, LayoutTransform = VecLayoutTransform, Rows = Dim, Cols = Dim, Index = Idx<Dim>>,
2259> ZipEq<kind::Diag, L, R>
2260where
2261 L::Dyn: MatIndex<Rows = usize, Cols = usize, Index = usize>,
2262 R::Dyn: MatIndex<Rows = usize, Cols = usize, Index = usize>,
2263{
2264 #[inline(always)]
2266 pub fn for_each(self, f: impl FnMut(<Self as MatIndex>::Item)) {
2267 for_each_diag(self, f);
2268 }
2269
2270 #[inline(always)]
2273 pub fn for_each_with_index(self, f: impl FnMut(Idx<Dim>, <Self as MatIndex>::Item)) {
2274 for_each_diag_with_index(self, f);
2275 }
2276
2277 #[inline(always)]
2279 pub fn map<T>(self, f: impl FnMut(<Self as MatIndex>::Item) -> T) -> diag::Diag<T, Dim> {
2280 let (m, _) = (Self::nrows(&self), Self::ncols(&self));
2281 let mut f = f;
2282 let mut this = self;
2283 Col::from_fn(
2284 m,
2285 #[inline(always)]
2286 |i| f(unsafe { Self::get_unchecked(&mut this, i) }),
2287 )
2288 .into_diagonal()
2289 }
2290
2291 #[inline(always)]
2293 pub fn map_with_index<T>(self, f: impl FnMut(Idx<Dim>, <Self as MatIndex>::Item) -> T) -> diag::Diag<T, Dim> {
2294 let (m, _) = (Self::nrows(&self), Self::ncols(&self));
2295 let mut f = f;
2296 let mut this = self;
2297
2298 Col::from_fn(
2299 m,
2300 #[inline(always)]
2301 |i| f(i, unsafe { Self::get_unchecked(&mut this, i) }),
2302 )
2303 .into_diagonal()
2304 }
2305}
2306
2307impl<Cols: Shape, M: MatIndex<Kind = kind::Row, LayoutTransform = VecLayoutTransform, Rows = (), Cols = Cols, Index = Idx<Cols>>> LastEq<kind::Row, M>
2308where
2309 M::Dyn: MatIndex<Rows = (), Cols = usize, Index = usize>,
2310{
2311 #[inline(always)]
2313 pub fn for_each(self, f: impl FnMut(<Self as MatIndex>::Item)) {
2314 for_each_row(self, f);
2315 }
2316
2317 #[inline(always)]
2320 pub fn for_each_with_index(self, f: impl FnMut(Idx<Cols>, <Self as MatIndex>::Item)) {
2321 for_each_row_with_index(self, f);
2322 }
2323
2324 #[inline(always)]
2326 pub fn map<T>(self, f: impl FnMut(<Self as MatIndex>::Item) -> T) -> Row<T, Cols> {
2327 let (_, n) = (Self::nrows(&self), Self::ncols(&self));
2328 let mut f = f;
2329 let mut this = self;
2330 Row::from_fn(
2331 n,
2332 #[inline(always)]
2333 |i| f(unsafe { Self::get_unchecked(&mut this, i) }),
2334 )
2335 }
2336
2337 #[inline(always)]
2339 pub fn map_with_index<T>(self, f: impl FnMut(Idx<Cols>, <Self as MatIndex>::Item) -> T) -> Row<T, Cols> {
2340 let (_, n) = (Self::nrows(&self), Self::ncols(&self));
2341 let mut f = f;
2342 let mut this = self;
2343
2344 Row::from_fn(
2345 n,
2346 #[inline(always)]
2347 |i| f(i, unsafe { Self::get_unchecked(&mut this, i) }),
2348 )
2349 }
2350}
2351
2352impl<
2353 Cols: Shape,
2354 L: MatIndex<Kind = kind::Row, LayoutTransform = VecLayoutTransform, Rows = (), Cols = Cols, Index = Idx<Cols>>,
2355 R: MatIndex<Kind = kind::Row, LayoutTransform = VecLayoutTransform, Rows = (), Cols = Cols, Index = Idx<Cols>>,
2356> ZipEq<kind::Row, L, R>
2357where
2358 L::Dyn: MatIndex<Rows = (), Cols = usize, Index = usize>,
2359 R::Dyn: MatIndex<Rows = (), Cols = usize, Index = usize>,
2360{
2361 #[inline(always)]
2363 pub fn for_each(self, f: impl FnMut(<Self as MatIndex>::Item)) {
2364 for_each_row(self, f);
2365 }
2366
2367 #[inline(always)]
2370 pub fn for_each_with_index(self, f: impl FnMut(Idx<Cols>, <Self as MatIndex>::Item)) {
2371 for_each_row_with_index(self, f);
2372 }
2373
2374 #[inline(always)]
2376 pub fn map<T>(self, f: impl FnMut(<Self as MatIndex>::Item) -> T) -> Row<T, Cols> {
2377 let (_, n) = (Self::nrows(&self), Self::ncols(&self));
2378 let mut f = f;
2379 let mut this = self;
2380 Row::from_fn(
2381 n,
2382 #[inline(always)]
2383 |i| f(unsafe { Self::get_unchecked(&mut this, i) }),
2384 )
2385 }
2386
2387 #[inline(always)]
2389 pub fn map_with_index<T>(self, f: impl FnMut(Idx<Cols>, <Self as MatIndex>::Item) -> T) -> Row<T, Cols> {
2390 let (_, n) = (Self::nrows(&self), Self::ncols(&self));
2391 let mut f = f;
2392 let mut this = self;
2393
2394 Row::from_fn(
2395 n,
2396 #[inline(always)]
2397 |i| f(i, unsafe { Self::get_unchecked(&mut this, i) }),
2398 )
2399 }
2400}
2401
2402pub mod kind {
2403 pub struct Col;
2404 pub struct Row;
2405 pub struct Mat;
2406 pub struct Diag;
2407}