Skip to main content

faer/row/
rowown.rs

1use super::*;
2use crate::{ContiguousFwd, Idx, IdxInc, TryReserveError, assert};
3/// see [`super::Row`]
4#[derive(Clone)]
5pub struct Own<T, Cols: Shape = usize> {
6	pub(crate) trans: Col<T, Cols>,
7}
8impl<T, Cols: Shape> Row<T, Cols> {
9	/// returns a new row with dimension `ncols`, filled with the provided
10	/// function
11	#[inline]
12	pub fn from_fn(ncols: Cols, f: impl FnMut(Idx<Cols>) -> T) -> Self {
13		Self {
14			0: Own {
15				trans: Col::from_fn(ncols, f),
16			},
17		}
18	}
19
20	/// returns a new row with dimension `ncols`, filled with zeros
21	#[inline]
22	pub fn zeros(ncols: Cols) -> Self
23	where
24		T: ComplexField,
25	{
26		Self {
27			0: Own {
28				trans: Col::zeros(ncols),
29			},
30		}
31	}
32
33	/// returns a new row with dimension `ncols`, filled with ones
34	#[inline]
35	pub fn ones(ncols: Cols) -> Self
36	where
37		T: ComplexField,
38	{
39		Self {
40			0: Own {
41				trans: Col::ones(ncols),
42			},
43		}
44	}
45
46	/// returns a new row with dimension `ncols`, filled with `value`
47	#[inline]
48	pub fn full(ncols: Cols, value: T) -> Self
49	where
50		T: Clone,
51	{
52		Self {
53			0: Own {
54				trans: Col::full(ncols, value),
55			},
56		}
57	}
58
59	/// reserves the minimum capacity for `col_capacity` columns without
60	/// reallocating, or returns an error in case of failure. does nothing if
61	/// the capacity is already sufficient
62	#[inline]
63	pub fn try_reserve(
64		&mut self,
65		new_row_capacity: usize,
66	) -> Result<(), TryReserveError> {
67		self.0.trans.try_reserve(new_row_capacity)
68	}
69
70	/// reserves the minimum capacity for `col_capacity` columns without
71	/// reallocating. does nothing if the capacity is already sufficient
72	#[track_caller]
73	pub fn reserve(&mut self, new_row_capacity: usize) {
74		self.0.trans.reserve(new_row_capacity)
75	}
76
77	/// resizes the row in-place so that the new dimension is `new_ncols`.
78	/// new elements are created with the given function `f`, so that elements
79	/// at index `j` are created by calling `f(j)`
80	#[inline]
81	pub fn resize_with(
82		&mut self,
83		new_ncols: Cols,
84		f: impl FnMut(Idx<Cols>) -> T,
85	) {
86		self.0.trans.resize_with(new_ncols, f);
87	}
88
89	/// truncates the row so that its new dimensions are `new_ncols`.
90	/// the new dimension must be smaller than or equal to the current dimension
91	///
92	/// # panics
93	/// the function panics if any of the following conditions are violated:
94	/// - `new_ncols > self.ncols()`
95	#[inline]
96	pub fn truncate(&mut self, new_ncols: Cols) {
97		self.0.trans.truncate(new_ncols);
98	}
99
100	/// see [`RowRef::as_col_shape`]
101	#[inline]
102	pub fn into_col_shape<V: Shape>(self, ncols: V) -> Row<T, V> {
103		assert!(all(self.ncols().unbound() == ncols.unbound()));
104		Row {
105			0: Own {
106				trans: self.0.trans.into_row_shape(ncols),
107			},
108		}
109	}
110
111	/// see [`RowRef::as_diagonal`]
112	#[inline]
113	pub fn into_diagonal(self) -> Diag<T, Cols> {
114		Diag {
115			0: crate::diag::Own {
116				inner: self.0.trans,
117			},
118		}
119	}
120
121	/// see [`RowRef::transpose`]
122	#[inline]
123	pub fn into_transpose(self) -> Col<T, Cols> {
124		self.0.trans
125	}
126}
127impl<T, Cols: Shape> Row<T, Cols> {
128	/// returns the number of rows of the row (always 1)
129	#[inline]
130	pub fn nrows(&self) -> usize {
131		self.0.trans.ncols()
132	}
133
134	/// returns the number of columns of the row
135	#[inline]
136	pub fn ncols(&self) -> Cols {
137		self.0.trans.nrows()
138	}
139}
140impl<T: core::fmt::Debug, Cols: Shape> core::fmt::Debug for Own<T, Cols> {
141	fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
142		self.rb().fmt(f)
143	}
144}
145impl<T, Cols: Shape> Row<T, Cols> {
146	#[inline(always)]
147	/// see [`RowRef::as_ptr`]
148	pub fn as_ptr(&self) -> *const T {
149		self.rb().as_ptr()
150	}
151
152	#[inline(always)]
153	/// see [`RowRef::shape`]
154	pub fn shape(&self) -> (usize, Cols) {
155		self.rb().shape()
156	}
157
158	#[inline(always)]
159	/// see [`RowRef::col_stride`]
160	pub fn col_stride(&self) -> isize {
161		self.rb().col_stride()
162	}
163
164	#[inline]
165	pub fn map<U>(&self, f: impl Fn(&T) -> U) -> Row<U, Cols> {
166		self.rb().map(f)
167	}
168
169	#[inline]
170	pub fn for_each(&self, f: impl Fn(&T)) {
171		self.rb().for_each(f)
172	}
173
174	#[inline]
175	pub fn map_mut<U>(&mut self, f: impl FnMut(&mut T) -> U) -> Row<U, Cols> {
176		self.rb_mut().map_mut(f)
177	}
178
179	#[inline]
180	pub fn for_each_mut(&mut self, f: impl FnMut(&mut T)) {
181		self.rb_mut().for_each_mut(f)
182	}
183
184	#[inline(always)]
185	/// see [`RowRef::ptr_at`]
186	pub fn ptr_at(&self, col: IdxInc<Cols>) -> *const T {
187		self.rb().ptr_at(col)
188	}
189
190	#[inline(always)]
191	#[track_caller]
192	/// see [`RowRef::ptr_inbounds_at`]
193	pub unsafe fn ptr_inbounds_at(&self, col: Idx<Cols>) -> *const T {
194		self.rb().ptr_inbounds_at(col)
195	}
196
197	#[inline]
198	#[track_caller]
199	/// see [`RowRef::split_at_col`]
200	pub fn split_at_col(
201		&self,
202		col: IdxInc<Cols>,
203	) -> (RowRef<'_, T, usize>, RowRef<'_, T, usize>) {
204		self.rb().split_at_col(col)
205	}
206
207	#[inline(always)]
208	/// see [`RowRef::transpose`]
209	pub fn transpose(&self) -> ColRef<'_, T, Cols> {
210		self.rb().transpose()
211	}
212
213	#[inline(always)]
214	/// see [`RowRef::conjugate`]
215	pub fn conjugate(&self) -> RowRef<'_, T::Conj, Cols>
216	where
217		T: Conjugate,
218	{
219		self.rb().conjugate()
220	}
221
222	#[inline(always)]
223	/// see [`RowRef::canonical`]
224	pub fn canonical(&self) -> RowRef<'_, T::Canonical, Cols>
225	where
226		T: Conjugate,
227	{
228		self.rb().canonical()
229	}
230
231	#[inline(always)]
232	/// see [`RowRef::adjoint`]
233	pub fn adjoint(&self) -> ColRef<'_, T::Conj, Cols>
234	where
235		T: Conjugate,
236	{
237		self.rb().adjoint()
238	}
239
240	#[track_caller]
241	#[inline(always)]
242	/// see [`RowRef::get`]
243	pub fn get<ColRange>(
244		&self,
245		col: ColRange,
246	) -> <RowRef<'_, T, Cols> as RowIndex<ColRange>>::Target
247	where
248		for<'a> RowRef<'a, T, Cols>: RowIndex<ColRange>,
249	{
250		<RowRef<'_, T, Cols> as RowIndex<ColRange>>::get(self.rb(), col)
251	}
252
253	#[track_caller]
254	#[inline(always)]
255	/// see [`RowRef::get_unchecked`]
256	pub unsafe fn get_unchecked<ColRange>(
257		&self,
258		col: ColRange,
259	) -> <RowRef<'_, T, Cols> as RowIndex<ColRange>>::Target
260	where
261		for<'a> RowRef<'a, T, Cols>: RowIndex<ColRange>,
262	{
263		unsafe {
264			<RowRef<'_, T, Cols> as RowIndex<ColRange>>::get_unchecked(
265				self.rb(),
266				col,
267			)
268		}
269	}
270
271	#[inline]
272	/// see [`RowRef::reverse_cols`]
273	pub fn reverse_cols(&self) -> RowRef<'_, T, Cols> {
274		self.rb().reverse_cols()
275	}
276
277	#[inline]
278	/// see [`RowRef::subcols`]
279	pub fn subcols<V: Shape>(
280		&self,
281		col_start: IdxInc<Cols>,
282		ncols: V,
283	) -> RowRef<'_, T, V> {
284		self.rb().subcols(col_start, ncols)
285	}
286
287	#[inline]
288	/// see [`RowRef::as_col_shape`]
289	pub fn as_col_shape<V: Shape>(&self, ncols: V) -> RowRef<'_, T, V> {
290		self.rb().as_col_shape(ncols)
291	}
292
293	#[inline]
294	/// see [`RowRef::as_dyn_cols`]
295	pub fn as_dyn_cols(&self) -> RowRef<'_, T, usize> {
296		self.rb().as_dyn_cols()
297	}
298
299	#[inline]
300	/// see [`RowRef::as_dyn_stride`]
301	pub fn as_dyn_stride(&self) -> RowRef<'_, T, Cols, isize> {
302		self.rb().as_dyn_stride()
303	}
304
305	#[inline]
306	/// see [`RowRef::iter`]
307	pub fn iter(
308		&self,
309	) -> impl '_ + ExactSizeIterator + DoubleEndedIterator<Item = &'_ T> {
310		self.rb().iter()
311	}
312
313	#[inline]
314	#[cfg(feature = "rayon")]
315	/// see [`RowRef::par_iter`]
316	pub fn par_iter(
317		&self,
318	) -> impl '_ + rayon::iter::IndexedParallelIterator<Item = &'_ T>
319	where
320		T: Sync,
321	{
322		self.rb().par_iter()
323	}
324
325	#[inline]
326	/// see [`RowRef::try_as_row_major`]
327	pub fn try_as_row_major(
328		&self,
329	) -> Option<RowRef<'_, T, Cols, ContiguousFwd>> {
330		self.rb().try_as_row_major()
331	}
332
333	#[inline]
334	/// see [`RowRef::as_diagonal`]
335	pub fn as_diagonal(&self) -> DiagRef<'_, T, Cols> {
336		self.rb().as_diagonal()
337	}
338
339	#[inline(always)]
340	/// see [`RowRef::const_cast`]
341	pub unsafe fn const_cast(&self) -> RowMut<'_, T, Cols> {
342		self.rb().const_cast()
343	}
344
345	#[inline]
346	/// see [`RowRef::as_mat`]
347	pub fn as_mat(&self) -> MatRef<'_, T, usize, Cols, isize> {
348		self.rb().as_mat()
349	}
350
351	#[inline]
352	/// see [`RowRef::as_mat`]
353	pub fn as_mat_mut(&mut self) -> MatMut<'_, T, usize, Cols, isize> {
354		self.rb_mut().as_mat_mut()
355	}
356}
357impl<T, Cols: Shape> Row<T, Cols> {
358	#[inline(always)]
359	/// see [`RowMut::as_ptr_mut`]
360	pub fn as_ptr_mut(&mut self) -> *mut T {
361		self.rb_mut().as_ptr_mut()
362	}
363
364	#[inline(always)]
365	/// see [`RowMut::ptr_at_mut`]
366	pub fn ptr_at_mut(&mut self, col: IdxInc<Cols>) -> *mut T {
367		self.rb_mut().ptr_at_mut(col)
368	}
369
370	#[inline(always)]
371	#[track_caller]
372	/// see [`RowMut::ptr_inbounds_at_mut`]
373	pub unsafe fn ptr_inbounds_at_mut(&mut self, col: Idx<Cols>) -> *mut T {
374		self.rb_mut().ptr_inbounds_at_mut(col)
375	}
376
377	#[inline]
378	#[track_caller]
379	/// see [`RowMut::split_at_col_mut`]
380	pub fn split_at_col_mut(
381		&mut self,
382		col: IdxInc<Cols>,
383	) -> (RowMut<'_, T, usize>, RowMut<'_, T, usize>) {
384		self.rb_mut().split_at_col_mut(col)
385	}
386
387	#[inline(always)]
388	/// see [`RowMut::transpose_mut`]
389	pub fn transpose_mut(&mut self) -> ColMut<'_, T, Cols> {
390		self.rb_mut().transpose_mut()
391	}
392
393	#[inline(always)]
394	/// see [`RowMut::conjugate_mut`]
395	pub fn conjugate_mut(&mut self) -> RowMut<'_, T::Conj, Cols>
396	where
397		T: Conjugate,
398	{
399		self.rb_mut().conjugate_mut()
400	}
401
402	#[inline(always)]
403	/// see [`RowMut::canonical_mut`]
404	pub fn canonical_mut(&mut self) -> RowMut<'_, T::Canonical, Cols>
405	where
406		T: Conjugate,
407	{
408		self.rb_mut().canonical_mut()
409	}
410
411	#[inline(always)]
412	/// see [`RowMut::adjoint_mut`]
413	pub fn adjoint_mut(&mut self) -> ColMut<'_, T::Conj, Cols>
414	where
415		T: Conjugate,
416	{
417		self.rb_mut().adjoint_mut()
418	}
419
420	#[track_caller]
421	#[inline(always)]
422	/// see [`RowMut::get_mut`]
423	pub fn get_mut<ColRange>(
424		&mut self,
425		col: ColRange,
426	) -> <RowMut<'_, T, Cols> as RowIndex<ColRange>>::Target
427	where
428		for<'a> RowMut<'a, T, Cols>: RowIndex<ColRange>,
429	{
430		<RowMut<'_, T, Cols> as RowIndex<ColRange>>::get(self.rb_mut(), col)
431	}
432
433	#[track_caller]
434	#[inline(always)]
435	/// see [`RowMut::get_mut_unchecked`]
436	pub unsafe fn get_mut_unchecked<ColRange>(
437		&mut self,
438		col: ColRange,
439	) -> <RowMut<'_, T, Cols> as RowIndex<ColRange>>::Target
440	where
441		for<'a> RowMut<'a, T, Cols>: RowIndex<ColRange>,
442	{
443		unsafe {
444			<RowMut<'_, T, Cols> as RowIndex<ColRange>>::get_unchecked(
445				self.rb_mut(),
446				col,
447			)
448		}
449	}
450
451	#[inline]
452	/// see [`RowMut::reverse_cols_mut`]
453	pub fn reverse_cols_mut(&mut self) -> RowMut<'_, T, Cols> {
454		self.rb_mut().reverse_cols_mut()
455	}
456
457	#[inline]
458	/// see [`RowMut::subcols_mut`]
459	pub fn subcols_mut<V: Shape>(
460		&mut self,
461		col_start: IdxInc<Cols>,
462		ncols: V,
463	) -> RowMut<'_, T, V> {
464		self.rb_mut().subcols_mut(col_start, ncols)
465	}
466
467	#[inline]
468	/// see [`RowMut::as_col_shape_mut`]
469	pub fn as_col_shape_mut<V: Shape>(&mut self, ncols: V) -> RowMut<'_, T, V> {
470		self.rb_mut().as_col_shape_mut(ncols)
471	}
472
473	#[inline]
474	/// see [`RowMut::as_dyn_cols_mut`]
475	pub fn as_dyn_cols_mut(&mut self) -> RowMut<'_, T, usize> {
476		self.rb_mut().as_dyn_cols_mut()
477	}
478
479	#[inline]
480	/// see [`RowMut::as_dyn_stride_mut`]
481	pub fn as_dyn_stride_mut(&mut self) -> RowMut<'_, T, Cols, isize> {
482		self.rb_mut().as_dyn_stride_mut()
483	}
484
485	#[inline]
486	/// see [`RowMut::iter_mut`]
487	pub fn iter_mut(
488		&mut self,
489	) -> impl '_ + ExactSizeIterator + DoubleEndedIterator<Item = &'_ mut T> {
490		self.rb_mut().iter_mut()
491	}
492
493	#[inline]
494	#[cfg(feature = "rayon")]
495	/// see [`RowMut::par_iter_mut`]
496	pub fn par_iter_mut(
497		&mut self,
498	) -> impl '_ + rayon::iter::IndexedParallelIterator<Item = &'_ mut T>
499	where
500		T: Send,
501	{
502		self.rb_mut().par_iter_mut()
503	}
504
505	#[inline]
506	/// see [`RowMut::try_as_row_major_mut`]
507	pub fn try_as_row_major_mut(
508		&mut self,
509	) -> Option<RowMut<'_, T, Cols, ContiguousFwd>> {
510		self.rb_mut().try_as_row_major_mut()
511	}
512
513	#[inline]
514	/// see [`RowMut::as_diagonal_mut`]
515	pub fn as_diagonal_mut(&mut self) -> DiagMut<'_, T, Cols> {
516		self.rb_mut().as_diagonal_mut()
517	}
518}
519impl<'short, T, Cols: Shape> Reborrow<'short> for Own<T, Cols> {
520	type Target = Ref<'short, T, Cols>;
521
522	#[inline]
523	fn rb(&'short self) -> Self::Target {
524		Ref {
525			trans: self.trans.rb(),
526		}
527	}
528}
529impl<'short, T, Cols: Shape> ReborrowMut<'short> for Own<T, Cols> {
530	type Target = Mut<'short, T, Cols>;
531
532	#[inline]
533	fn rb_mut(&'short mut self) -> Self::Target {
534		Mut {
535			trans: self.trans.rb_mut(),
536		}
537	}
538}
539impl<T, Cols: Shape> Row<T, Cols>
540where
541	T: RealField,
542{
543	/// Returns the maximum element in the row, or `None` if the row is empty
544	pub fn max(&self) -> Option<T> {
545		self.as_dyn_cols().as_dyn_stride().internal_max()
546	}
547
548	/// Returns the minimum element in the row, or `None` if the row is empty
549	pub fn min(&self) -> Option<T> {
550		self.as_dyn_cols().as_dyn_stride().internal_min()
551	}
552}
553impl<T> FromIterator<T> for Row<T> {
554	fn from_iter<I>(iter: I) -> Self
555	where
556		I: IntoIterator<Item = T>,
557	{
558		Row {
559			0: Own {
560				trans: Col::from_iter_imp(iter.into_iter()),
561			},
562		}
563	}
564}
565#[cfg(test)]
566mod tests {
567	use crate::Row;
568	#[test]
569	fn test_row_min() {
570		let row: Row<f64> = Row::from_fn(5, |x| (x + 1) as f64);
571		assert_eq!(row.min(), Some(1.0));
572		let empty: Row<f64> = Row::from_fn(0, |_| 0.0);
573		assert_eq!(empty.min(), None);
574	}
575	#[test]
576	fn test_row_max() {
577		let row: Row<f64> = Row::from_fn(5, |x| (x + 1) as f64);
578		assert_eq!(row.max(), Some(5.0));
579		let empty: Row<f64> = Row::from_fn(0, |_| 0.0);
580		assert_eq!(empty.max(), None);
581	}
582	#[test]
583	fn test_from_iter() {
584		let row: Row<i32> = (0..10).collect();
585		assert_eq!(row.ncols(), 10);
586		assert_eq!(row[0], 0);
587		assert_eq!(row[9], 9);
588	}
589}