Skip to main content

faer/diag/
diagref.rs

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