Skip to main content

faer/row/
rowmut.rs

1use super::*;
2use crate::utils::bound::{Array, Dim, Partition};
3use crate::{ContiguousFwd, Idx, IdxInc};
4use equator::{assert, debug_assert};
5/// see [`super::RowMut`]
6pub struct Mut<'a, T, Cols = usize, CStride = isize> {
7	pub(crate) trans: ColMut<'a, T, Cols, CStride>,
8}
9impl<'short, T, Rows: Copy, RStride: Copy> Reborrow<'short>
10	for Mut<'_, T, Rows, RStride>
11{
12	type Target = Ref<'short, T, Rows, RStride>;
13
14	#[inline]
15	fn rb(&'short self) -> Self::Target {
16		Ref {
17			trans: self.trans.rb(),
18		}
19	}
20}
21impl<'short, T, Rows: Copy, RStride: Copy> ReborrowMut<'short>
22	for Mut<'_, T, Rows, RStride>
23{
24	type Target = Mut<'short, T, Rows, RStride>;
25
26	#[inline]
27	fn rb_mut(&'short mut self) -> Self::Target {
28		Mut {
29			trans: self.trans.rb_mut(),
30		}
31	}
32}
33impl<'a, T, Rows: Copy, RStride: Copy> IntoConst for Mut<'a, T, Rows, RStride> {
34	type Target = Ref<'a, T, Rows, RStride>;
35
36	#[inline]
37	fn into_const(self) -> Self::Target {
38		Ref {
39			trans: self.trans.into_const(),
40		}
41	}
42}
43impl<'a, T> RowMut<'a, T> {
44	/// creates a row view over the given element
45	#[inline]
46	pub fn from_mut(value: &'a mut T) -> Self {
47		unsafe { RowMut::from_raw_parts_mut(value as *mut T, 1, 1) }
48	}
49
50	/// creates a `RowMut` from slice views over the row vector data, the result
51	/// has the same number of columns as the length of the input slice
52	#[inline]
53	pub fn from_slice_mut(slice: &'a mut [T]) -> Self {
54		let len = slice.len();
55		unsafe { Self::from_raw_parts_mut(slice.as_mut_ptr(), len, 1) }
56	}
57}
58impl<'a, T, Cols: Shape, CStride: Stride> RowMut<'a, T, Cols, CStride> {
59	/// creates a `RowMut` from pointers to the column vector data, number of
60	/// rows, and row stride
61	///
62	/// # safety
63	/// this function has the same safety requirements as
64	/// [`MatMut::from_raw_parts_mut(ptr, 1, ncols, 0, col_stride)`]
65	#[inline(always)]
66	#[track_caller]
67	pub const unsafe fn from_raw_parts_mut(
68		ptr: *mut T,
69		ncols: Cols,
70		col_stride: CStride,
71	) -> Self {
72		Self {
73			0: Mut {
74				trans: ColMut::from_raw_parts_mut(ptr, ncols, col_stride),
75			},
76		}
77	}
78
79	/// returns a pointer to the row data
80	#[inline(always)]
81	pub fn as_ptr(&self) -> *const T {
82		self.trans.as_ptr()
83	}
84
85	/// returns the number of rows of the row (always 1)
86	#[inline(always)]
87	pub fn nrows(&self) -> usize {
88		1
89	}
90
91	/// returns the number of columns of the row
92	#[inline(always)]
93	pub fn ncols(&self) -> Cols {
94		self.trans.nrows()
95	}
96
97	/// returns the number of rows and columns of the row
98	#[inline(always)]
99	pub fn shape(&self) -> (usize, Cols) {
100		(self.nrows(), self.ncols())
101	}
102
103	/// returns the column stride of the row
104	#[inline(always)]
105	pub fn col_stride(&self) -> CStride {
106		self.trans.row_stride()
107	}
108
109	#[inline]
110	pub fn map<U>(&self, f: impl Fn(&T) -> U) -> Row<U, Cols> {
111		self.rb().map(f)
112	}
113
114	#[inline]
115	pub fn for_each(&self, f: impl Fn(&T)) {
116		self.rb().for_each(f)
117	}
118
119	#[inline]
120	pub fn map_mut<U>(&mut self, f: impl FnMut(&mut T) -> U) -> Row<U, Cols> {
121		let mut f = f;
122		zip!(self).map(|unzip!(x)| f(x))
123	}
124
125	#[inline]
126	pub fn for_each_mut(&mut self, f: impl FnMut(&mut T)) {
127		let mut f = f;
128		zip!(self).for_each(|unzip!(x)| f(x))
129	}
130
131	/// returns a raw pointer to the element at the given index
132	#[inline(always)]
133	pub fn ptr_at(&self, col: IdxInc<Cols>) -> *const T {
134		self.trans.ptr_at(col)
135	}
136
137	/// returns a raw pointer to the element at the given index, assuming the
138	/// provided index is within the row bounds
139	///
140	/// # safety
141	/// the behavior is undefined if any of the following conditions are
142	/// violated:
143	/// * `col < self.ncols()`
144	#[inline(always)]
145	#[track_caller]
146	pub unsafe fn ptr_inbounds_at(&self, col: Idx<Cols>) -> *const T {
147		debug_assert!(all(col < self.ncols()));
148		self.trans.ptr_inbounds_at(col)
149	}
150
151	#[inline]
152	#[track_caller]
153	/// see [`RowRef::split_at_col`]
154	pub fn split_at_col(
155		self,
156		col: IdxInc<Cols>,
157	) -> (RowRef<'a, T, usize, CStride>, RowRef<'a, T, usize, CStride>) {
158		self.into_const().split_at_col(col)
159	}
160
161	#[inline(always)]
162	/// see [`RowRef::transpose`]
163	pub fn transpose(self) -> ColRef<'a, T, Cols, CStride> {
164		self.into_const().transpose()
165	}
166
167	#[inline(always)]
168	/// see [`RowRef::conjugate`]
169	pub fn conjugate(self) -> RowRef<'a, T::Conj, Cols, CStride>
170	where
171		T: Conjugate,
172	{
173		self.into_const().conjugate()
174	}
175
176	#[inline(always)]
177	/// see [`RowRef::canonical`]
178	pub fn canonical(self) -> RowRef<'a, T::Canonical, Cols, CStride>
179	where
180		T: Conjugate,
181	{
182		self.into_const().canonical()
183	}
184
185	#[inline(always)]
186	/// see [`RowRef::adjoint`]
187	pub fn adjoint(self) -> ColRef<'a, T::Conj, Cols, CStride>
188	where
189		T: Conjugate,
190	{
191		self.into_const().adjoint()
192	}
193
194	#[track_caller]
195	#[inline(always)]
196	/// see [`RowRef::get`]
197	pub fn get<ColRange>(
198		self,
199		col: ColRange,
200	) -> <RowRef<'a, T, Cols, CStride> as RowIndex<ColRange>>::Target
201	where
202		RowRef<'a, T, Cols, CStride>: RowIndex<ColRange>,
203	{
204		<RowRef<'a, T, Cols, CStride> as RowIndex<ColRange>>::get(
205			self.into_const(),
206			col,
207		)
208	}
209
210	#[track_caller]
211	#[inline(always)]
212	/// see [`RowRef::get_unchecked`]
213	pub unsafe fn get_unchecked<ColRange>(
214		self,
215		col: ColRange,
216	) -> <RowRef<'a, T, Cols, CStride> as RowIndex<ColRange>>::Target
217	where
218		RowRef<'a, T, Cols, CStride>: RowIndex<ColRange>,
219	{
220		unsafe {
221			<RowRef<'a, T, Cols, CStride> as RowIndex<ColRange>>::get_unchecked(
222				self.into_const(),
223				col,
224			)
225		}
226	}
227
228	#[inline]
229	/// see [`RowRef::reverse_cols`]
230	pub fn reverse_cols(self) -> RowRef<'a, T, Cols, CStride::Rev> {
231		self.into_const().reverse_cols()
232	}
233
234	#[inline]
235	/// see [`RowRef::subcols`]
236	pub fn subcols<V: Shape>(
237		self,
238		col_start: IdxInc<Cols>,
239		ncols: V,
240	) -> RowRef<'a, T, V, CStride> {
241		self.into_const().subcols(col_start, ncols)
242	}
243
244	#[inline]
245	#[track_caller]
246	/// see [`RowRef::as_col_shape`]
247	pub fn as_col_shape<V: Shape>(self, ncols: V) -> RowRef<'a, T, V, CStride> {
248		self.into_const().as_col_shape(ncols)
249	}
250
251	#[inline]
252	/// see [`RowRef::as_dyn_cols`]
253	pub fn as_dyn_cols(self) -> RowRef<'a, T, usize, CStride> {
254		self.into_const().as_dyn_cols()
255	}
256
257	#[inline]
258	/// see [`RowRef::as_dyn_stride`]
259	pub fn as_dyn_stride(self) -> RowRef<'a, T, Cols, isize> {
260		self.into_const().as_dyn_stride()
261	}
262
263	#[inline]
264	/// see [`RowRef::iter`]
265	pub fn iter(
266		self,
267	) -> impl 'a + ExactSizeIterator + DoubleEndedIterator<Item = &'a T>
268	where
269		Cols: 'a,
270	{
271		self.0.trans.iter()
272	}
273
274	#[inline]
275	#[cfg(feature = "rayon")]
276	/// see [`RowRef::par_iter`]
277	pub fn par_iter(
278		self,
279	) -> impl 'a + rayon::iter::IndexedParallelIterator<Item = &'a T>
280	where
281		T: Sync,
282		Cols: 'a,
283	{
284		self.0.trans.par_iter()
285	}
286
287	#[inline]
288	/// see [`RowRef::try_as_row_major`]
289	pub fn try_as_row_major(
290		self,
291	) -> Option<RowRef<'a, T, Cols, ContiguousFwd>> {
292		self.into_const().try_as_row_major()
293	}
294
295	#[inline]
296	/// see [`RowRef::as_diagonal`]
297	pub fn as_diagonal(self) -> DiagRef<'a, T, Cols, CStride> {
298		DiagRef {
299			0: crate::diag::Ref {
300				inner: self.0.trans.into_const(),
301			},
302		}
303	}
304
305	#[inline(always)]
306	#[doc(hidden)]
307	pub unsafe fn const_cast(self) -> RowMut<'a, T, Cols, CStride> {
308		RowMut {
309			0: Mut {
310				trans: self.0.trans.const_cast(),
311			},
312		}
313	}
314
315	#[inline]
316	/// see [`RowRef::as_mat`]
317	pub fn as_mat(self) -> MatRef<'a, T, usize, Cols, isize, CStride> {
318		self.into_const().as_mat()
319	}
320
321	#[inline]
322	/// see [`RowRef::as_mat`]
323	pub fn as_mat_mut(self) -> MatMut<'a, T, usize, Cols, isize, CStride> {
324		unsafe { self.into_const().as_mat().const_cast() }
325	}
326}
327impl<
328	T,
329	Cols: Shape,
330	CStride: Stride,
331	Inner: for<'short> ReborrowMut<'short, Target = Mut<'short, T, Cols, CStride>>,
332> generic::Row<Inner>
333{
334	#[inline]
335	/// returns a view over `self`
336	pub fn as_mut(&mut self) -> RowMut<'_, T, Cols, CStride> {
337		self.rb_mut()
338	}
339
340	#[inline]
341	/// copies `other` into `self`
342	pub fn copy_from<RhsT: Conjugate<Canonical = T>>(
343		&mut self,
344		other: impl AsRowRef<T = RhsT, Cols = Cols>,
345	) where
346		T: ComplexField,
347	{
348		self.rb_mut()
349			.transpose_mut()
350			.copy_from(other.as_row_ref().transpose());
351	}
352
353	/// fills all the elements of `self` with `value`
354	pub fn fill(&mut self, value: T)
355	where
356		T: Clone,
357	{
358		self.rb_mut().transpose_mut().fill(value)
359	}
360}
361impl<'a, T, Cols: Shape, CStride: Stride> RowMut<'a, T, Cols, CStride> {
362	#[inline(always)]
363	/// see [`RowRef::as_ptr`]
364	pub fn as_ptr_mut(&self) -> *mut T {
365		self.trans.as_ptr_mut()
366	}
367
368	#[inline(always)]
369	/// see [`RowRef::ptr_at`]
370	pub fn ptr_at_mut(&self, col: IdxInc<Cols>) -> *mut T {
371		self.trans.ptr_at_mut(col)
372	}
373
374	#[inline(always)]
375	#[track_caller]
376	/// see [`RowRef::ptr_inbounds_at`]
377	pub unsafe fn ptr_inbounds_at_mut(&self, col: Idx<Cols>) -> *mut T {
378		debug_assert!(all(col < self.ncols()));
379		self.trans.ptr_inbounds_at_mut(col)
380	}
381
382	#[inline]
383	#[track_caller]
384	/// see [`RowRef::split_at_col`]
385	pub fn split_at_col_mut(
386		self,
387		col: IdxInc<Cols>,
388	) -> (RowMut<'a, T, usize, CStride>, RowMut<'a, T, usize, CStride>) {
389		let (a, b) = self.into_const().split_at_col(col);
390		unsafe { (a.const_cast(), b.const_cast()) }
391	}
392
393	#[inline(always)]
394	/// see [`RowRef::transpose`]
395	pub fn transpose_mut(self) -> ColMut<'a, T, Cols, CStride> {
396		self.0.trans
397	}
398
399	#[inline(always)]
400	/// see [`RowRef::conjugate`]
401	pub fn conjugate_mut(self) -> RowMut<'a, T::Conj, Cols, CStride>
402	where
403		T: Conjugate,
404	{
405		unsafe { self.into_const().conjugate().const_cast() }
406	}
407
408	#[inline(always)]
409	/// see [`RowRef::canonical`]
410	pub fn canonical_mut(self) -> RowMut<'a, T::Canonical, Cols, CStride>
411	where
412		T: Conjugate,
413	{
414		unsafe { self.into_const().canonical().const_cast() }
415	}
416
417	#[inline(always)]
418	/// see [`RowRef::adjoint`]
419	pub fn adjoint_mut(self) -> ColMut<'a, T::Conj, Cols, CStride>
420	where
421		T: Conjugate,
422	{
423		unsafe { self.into_const().adjoint().const_cast() }
424	}
425
426	#[inline(always)]
427	#[track_caller]
428	pub(crate) fn at_mut(self, col: Idx<Cols>) -> &'a mut T {
429		assert!(all(col < self.ncols()));
430		unsafe { self.at_mut_unchecked(col) }
431	}
432
433	#[inline(always)]
434	#[track_caller]
435	pub(crate) unsafe fn at_mut_unchecked(self, col: Idx<Cols>) -> &'a mut T {
436		&mut *self.ptr_inbounds_at_mut(col)
437	}
438
439	#[track_caller]
440	#[inline(always)]
441	/// see [`RowRef::get`]
442	pub fn get_mut<ColRange>(
443		self,
444		col: ColRange,
445	) -> <RowMut<'a, T, Cols, CStride> as RowIndex<ColRange>>::Target
446	where
447		RowMut<'a, T, Cols, CStride>: RowIndex<ColRange>,
448	{
449		<RowMut<'a, T, Cols, CStride> as RowIndex<ColRange>>::get(self, col)
450	}
451
452	#[track_caller]
453	#[inline(always)]
454	/// see [`RowRef::get`]
455	pub unsafe fn get_mut_unchecked<ColRange>(
456		self,
457		col: ColRange,
458	) -> <RowMut<'a, T, Cols, CStride> as RowIndex<ColRange>>::Target
459	where
460		RowMut<'a, T, Cols, CStride>: RowIndex<ColRange>,
461	{
462		unsafe {
463			<RowMut<'a, T, Cols, CStride> as RowIndex<ColRange>>::get_unchecked(
464				self, col,
465			)
466		}
467	}
468
469	#[inline]
470	/// see [`RowRef::reverse_cols`]
471	pub fn reverse_cols_mut(self) -> RowMut<'a, T, Cols, CStride::Rev> {
472		unsafe { self.into_const().reverse_cols().const_cast() }
473	}
474
475	#[inline]
476	/// see [`RowRef::subcols`]
477	pub fn subcols_mut<V: Shape>(
478		self,
479		col_start: IdxInc<Cols>,
480		ncols: V,
481	) -> RowMut<'a, T, V, CStride> {
482		unsafe { self.into_const().subcols(col_start, ncols).const_cast() }
483	}
484
485	#[inline]
486	#[track_caller]
487	/// see [`RowRef::as_col_shape`]
488	pub fn as_col_shape_mut<V: Shape>(
489		self,
490		ncols: V,
491	) -> RowMut<'a, T, V, CStride> {
492		unsafe { self.into_const().as_col_shape(ncols).const_cast() }
493	}
494
495	#[inline]
496	/// see [`RowRef::as_dyn_cols`]
497	pub fn as_dyn_cols_mut(self) -> RowMut<'a, T, usize, CStride> {
498		unsafe { self.into_const().as_dyn_cols().const_cast() }
499	}
500
501	#[inline]
502	/// see [`RowRef::as_dyn_stride`]
503	pub fn as_dyn_stride_mut(self) -> RowMut<'a, T, Cols, isize> {
504		unsafe { self.into_const().as_dyn_stride().const_cast() }
505	}
506
507	#[inline]
508	/// see [`RowRef::iter`]
509	pub fn iter_mut(
510		self,
511	) -> impl 'a + ExactSizeIterator + DoubleEndedIterator<Item = &'a mut T>
512	where
513		Cols: 'a,
514	{
515		self.0.trans.iter_mut()
516	}
517
518	#[inline]
519	#[cfg(feature = "rayon")]
520	/// see [`RowRef::par_iter`]
521	pub fn par_iter_mut(
522		self,
523	) -> impl 'a + rayon::iter::IndexedParallelIterator<Item = &'a mut T>
524	where
525		T: Send,
526		Cols: 'a,
527	{
528		self.0.trans.par_iter_mut()
529	}
530
531	#[inline]
532	#[track_caller]
533	#[cfg(feature = "rayon")]
534	/// see [`RowRef::par_partition`]
535	pub fn par_partition(
536		self,
537		count: usize,
538	) -> impl 'a
539	+ rayon::iter::IndexedParallelIterator<
540		Item = RowRef<'a, T, usize, CStride>,
541	>
542	where
543		T: Sync,
544		Cols: 'a,
545	{
546		self.into_const().par_partition(count)
547	}
548
549	#[inline]
550	#[track_caller]
551	#[cfg(feature = "rayon")]
552	/// see [`RowRef::par_partition`]
553	pub fn par_partition_mut(
554		self,
555		count: usize,
556	) -> impl 'a
557	+ rayon::iter::IndexedParallelIterator<
558		Item = RowMut<'a, T, usize, CStride>,
559	>
560	where
561		T: Send,
562		Cols: 'a,
563	{
564		use crate::mat::matmut::SyncCell;
565		use rayon::prelude::*;
566		unsafe {
567			self.as_type::<SyncCell<T>>()
568				.into_const()
569				.par_partition(count)
570				.map(|col| col.const_cast().as_type::<T>())
571		}
572	}
573
574	pub(crate) unsafe fn as_type<U>(self) -> RowMut<'a, U, Cols, CStride> {
575		RowMut::from_raw_parts_mut(
576			self.as_ptr_mut() as *mut U,
577			self.ncols(),
578			self.col_stride(),
579		)
580	}
581
582	#[inline]
583	/// see [`RowRef::try_as_row_major`]
584	pub fn try_as_row_major_mut(
585		self,
586	) -> Option<RowMut<'a, T, Cols, ContiguousFwd>> {
587		self.into_const()
588			.try_as_row_major()
589			.map(|x| unsafe { x.const_cast() })
590	}
591
592	#[inline]
593	/// see [`RowRef::as_diagonal`]
594	pub fn as_diagonal_mut(self) -> DiagMut<'a, T, Cols, CStride> {
595		DiagMut {
596			0: crate::diag::Mut {
597				inner: self.0.trans,
598			},
599		}
600	}
601
602	#[inline]
603	pub(crate) fn __at_mut(self, i: Idx<Cols>) -> &'a mut T {
604		self.at_mut(i)
605	}
606}
607impl<'a, T, Rows: Shape> RowMut<'a, T, Rows, ContiguousFwd> {
608	/// returns a reference over the elements as a slice
609	#[inline]
610	pub fn as_slice(self) -> &'a [T] {
611		self.transpose().as_slice()
612	}
613}
614impl<'a, 'ROWS, T> RowMut<'a, T, Dim<'ROWS>, ContiguousFwd> {
615	/// returns a reference over the elements as a lifetime-bound slice
616	#[inline]
617	pub fn as_array(self) -> &'a Array<'ROWS, T> {
618		self.transpose().as_array()
619	}
620}
621impl<'a, T, Cols: Shape> RowMut<'a, T, Cols, ContiguousFwd> {
622	/// returns a reference over the elements as a slice
623	#[inline]
624	pub fn as_slice_mut(self) -> &'a mut [T] {
625		self.transpose_mut().as_slice_mut()
626	}
627}
628impl<'a, 'COLS, T> RowMut<'a, T, Dim<'COLS>, ContiguousFwd> {
629	/// returns a reference over the elements as a lifetime-bound slice
630	#[inline]
631	pub fn as_array_mut(self) -> &'a mut Array<'COLS, T> {
632		self.transpose_mut().as_array_mut()
633	}
634}
635impl<'COLS, 'a, T, CStride: Stride> RowMut<'a, T, Dim<'COLS>, CStride> {
636	#[doc(hidden)]
637	#[inline]
638	pub fn split_cols_with<'LEFT, 'RIGHT>(
639		self,
640		col: Partition<'LEFT, 'RIGHT, 'COLS>,
641	) -> (
642		RowRef<'a, T, Dim<'LEFT>, CStride>,
643		RowRef<'a, T, Dim<'RIGHT>, CStride>,
644	) {
645		let (a, b) = self.split_at_col(col.midpoint());
646		(a.as_col_shape(col.head), b.as_col_shape(col.tail))
647	}
648}
649impl<'COLS, 'a, T, CStride: Stride> RowMut<'a, T, Dim<'COLS>, CStride> {
650	#[doc(hidden)]
651	#[inline]
652	pub fn split_cols_with_mut<'LEFT, 'RIGHT>(
653		self,
654		col: Partition<'LEFT, 'RIGHT, 'COLS>,
655	) -> (
656		RowMut<'a, T, Dim<'LEFT>, CStride>,
657		RowMut<'a, T, Dim<'RIGHT>, CStride>,
658	) {
659		let (a, b) = self.split_at_col_mut(col.midpoint());
660		(a.as_col_shape_mut(col.head), b.as_col_shape_mut(col.tail))
661	}
662}
663impl<T: core::fmt::Debug, Cols: Shape, CStride: Stride> core::fmt::Debug
664	for Mut<'_, T, Cols, CStride>
665{
666	fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
667		self.rb().fmt(f)
668	}
669}
670impl<'a, T, Cols: Shape, CStride: Stride> RowMut<'a, T, Cols, CStride>
671where
672	T: RealField,
673{
674	/// Returns the maximum element in the row, or `None` if the row is empty
675	pub fn max(&self) -> Option<T> {
676		self.rb().as_dyn_cols().as_dyn_stride().internal_max()
677	}
678
679	/// Returns the minimum element in the row, or `None` if the row is empty
680	pub fn min(&self) -> Option<T> {
681		self.rb().as_dyn_cols().as_dyn_stride().internal_min()
682	}
683}
684#[cfg(test)]
685mod tests {
686	use crate::Row;
687	#[test]
688	fn test_row_min() {
689		let row: Row<f64> = Row::from_fn(5, |x| (x + 1) as f64);
690		let rowmut = row.as_ref();
691		assert_eq!(rowmut.min(), Some(1.0));
692		let empty: Row<f64> = Row::from_fn(0, |_| 0.0);
693		let emptymut = empty.as_ref();
694		assert_eq!(emptymut.min(), None);
695	}
696	#[test]
697	fn test_row_max() {
698		let row: Row<f64> = Row::from_fn(5, |x| (x + 1) as f64);
699		let rowmut = row.as_ref();
700		assert_eq!(rowmut.max(), Some(5.0));
701		let empty: Row<f64> = Row::from_fn(0, |_| 0.0);
702		let emptymut = empty.as_ref();
703		assert_eq!(emptymut.max(), None);
704	}
705}