Skip to main content

faer/col/
colown.rs

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