faer/row/
rowown.rs

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