faer/col/
colown.rs

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