faer/diag/
diagref.rs

1use super::*;
2
3/// see [`super::DiagRef`]
4pub struct Ref<'a, T, Dim = usize, Stride = isize> {
5	pub(crate) inner: ColRef<'a, T, Dim, Stride>,
6}
7
8impl<T: core::fmt::Debug, Dim: Shape, S: Stride> core::fmt::Debug for Ref<'_, T, Dim, S> {
9	fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
10		self.inner.fmt(f)
11	}
12}
13
14impl<T, Dim: Copy, Stride: Copy> Copy for Ref<'_, T, Dim, Stride> {}
15impl<T, Dim: Copy, Stride: Copy> Clone for Ref<'_, T, Dim, Stride> {
16	#[inline]
17	fn clone(&self) -> Self {
18		*self
19	}
20}
21
22impl<'short, T, Dim: Copy, Stride: Copy> Reborrow<'short> for Ref<'_, T, Dim, Stride> {
23	type Target = Ref<'short, T, Dim, Stride>;
24
25	#[inline]
26	fn rb(&'short self) -> Self::Target {
27		*self
28	}
29}
30impl<'short, T, Dim: Copy, Stride: Copy> ReborrowMut<'short> for Ref<'_, T, Dim, Stride> {
31	type Target = Ref<'short, T, Dim, Stride>;
32
33	#[inline]
34	fn rb_mut(&'short mut self) -> Self::Target {
35		*self
36	}
37}
38impl<'a, T, Dim: Copy, Stride: Copy> IntoConst for Ref<'a, T, Dim, Stride> {
39	type Target = Ref<'a, T, Dim, Stride>;
40
41	#[inline]
42	fn into_const(self) -> Self::Target {
43		self
44	}
45}
46
47impl<'a, T> DiagRef<'a, T> {
48	/// creates a diagonal matrix view over the given element
49	#[inline]
50	pub fn from_ref(value: &'a T) -> Self {
51		unsafe { DiagRef::from_raw_parts(value as *const T, 1, 1) }
52	}
53
54	/// creates a `DiagRef` from slice views over the diagonal data, the result has the same
55	/// dimension as the length of the input slice
56	#[inline]
57	pub fn from_slice(slice: &'a [T]) -> Self {
58		let len = slice.len();
59		unsafe { Self::from_raw_parts(slice.as_ptr(), len, 1) }
60	}
61}
62
63impl<'a, T, Dim: Shape, Stride: crate::Stride> DiagRef<'a, T, Dim, Stride> {
64	/// creates a `DiagRef` from pointers to the diagonal data, dimension, and stride
65	///
66	/// # safety
67	/// this function has the same safety requirements as
68	/// [`MatRef::from_raw_parts(ptr, dim, 1, stride, 0)`]
69	#[inline(always)]
70	#[track_caller]
71	pub const unsafe fn from_raw_parts(ptr: *const T, dim: Dim, stride: Stride) -> Self {
72		Self {
73			0: Ref {
74				inner: ColRef::from_raw_parts(ptr, dim, stride),
75			},
76		}
77	}
78
79	/// returns the diagonal as a column vector view.
80	#[inline(always)]
81	pub fn column_vector(self) -> ColRef<'a, T, Dim, Stride> {
82		self.inner
83	}
84
85	/// returns a view over `self`
86	#[inline]
87	pub fn as_ref(&self) -> DiagRef<'_, T, Dim, Stride> {
88		*self
89	}
90
91	/// returns the input matrix with the given shape after checking that it matches the
92	/// current shape
93	#[inline]
94	#[track_caller]
95	pub fn as_shape<D: Shape>(self, len: D) -> DiagRef<'a, T, D, Stride> {
96		DiagRef {
97			0: Ref {
98				inner: self.inner.as_row_shape(len),
99			},
100		}
101	}
102
103	/// returns the input matrix with dynamic shape
104	#[inline]
105	pub fn as_dyn(self) -> DiagRef<'a, T, usize, Stride> {
106		DiagRef {
107			0: Ref {
108				inner: self.inner.as_dyn_rows(),
109			},
110		}
111	}
112
113	/// returns the input matrix with dynamic stride
114	#[inline]
115	pub fn as_dyn_stride(self) -> DiagRef<'a, T, Dim> {
116		DiagRef {
117			0: Ref {
118				inner: self.inner.as_dyn_stride(),
119			},
120		}
121	}
122
123	/// returns a view over the conjugate of `self`
124	#[inline]
125	pub fn conjugate(self) -> DiagRef<'a, T::Conj, Dim, Stride>
126	where
127		T: Conjugate,
128	{
129		DiagRef {
130			0: Ref {
131				inner: self.inner.conjugate(),
132			},
133		}
134	}
135
136	/// returns an unconjugated view over `self`
137	#[inline]
138	pub fn canonical(self) -> DiagRef<'a, T::Canonical, Dim, Stride>
139	where
140		T: Conjugate,
141	{
142		DiagRef {
143			0: Ref {
144				inner: self.inner.canonical(),
145			},
146		}
147	}
148
149	/// returns the dimension of `self`
150	#[inline]
151	pub fn dim(&self) -> Dim {
152		self.inner.nrows()
153	}
154}
155
156impl<T, Dim: Shape, Stride: crate::Stride, Inner: for<'short> Reborrow<'short, Target = Ref<'short, T, Dim, Stride>>> generic::Diag<Inner> {
157	/// returns `true` if all of the elements of `self` are finite.
158	/// otherwise returns `false`.
159	#[inline]
160	pub fn is_all_finite(&self) -> bool
161	where
162		T: Conjugate,
163	{
164		self.rb().column_vector().is_all_finite()
165	}
166
167	/// returns `true` if any of the elements of `self` is `NaN`.
168	/// otherwise returns `false`.
169	#[inline]
170	pub fn has_nan(&self) -> bool
171	where
172		T: Conjugate,
173	{
174		self.rb().column_vector().has_nan()
175	}
176}