Skip to content

Commit 7b8ee70

Browse files
committed
Eig, EigRef
1 parent 85d4f60 commit 7b8ee70

File tree

1 file changed

+34
-28
lines changed

1 file changed

+34
-28
lines changed

lax/src/eig.rs

Lines changed: 34 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -57,26 +57,28 @@ pub struct EigWork<T: Scalar> {
5757
pub rwork: Option<Vec<MaybeUninit<T::Real>>>,
5858
}
5959

60+
#[derive(Debug, Clone, PartialEq)]
61+
pub struct Eig<T: Scalar> {
62+
pub eigs: Vec<T::Complex>,
63+
pub vr: Option<Vec<T::Complex>>,
64+
pub vl: Option<Vec<T::Complex>>,
65+
}
66+
67+
#[derive(Debug, Clone, PartialEq)]
68+
pub struct EigRef<'work, T: Scalar> {
69+
pub eigs: &'work [T::Complex],
70+
pub vr: Option<&'work [T::Complex]>,
71+
pub vl: Option<&'work [T::Complex]>,
72+
}
73+
6074
pub trait EigWorkImpl: Sized {
6175
type Elem: Scalar;
6276
/// Create new working memory for eigenvalues compution.
6377
fn new(calc_v: bool, l: MatrixLayout) -> Result<Self>;
6478
/// Compute eigenvalues and vectors on this working memory.
65-
fn calc<'work>(
66-
&'work mut self,
67-
a: &mut [Self::Elem],
68-
) -> Result<(
69-
&'work [<Self::Elem as Scalar>::Complex],
70-
Option<&'work [<Self::Elem as Scalar>::Complex]>,
71-
)>;
79+
fn calc<'work>(&'work mut self, a: &mut [Self::Elem]) -> Result<EigRef<'work, Self::Elem>>;
7280
/// Compute eigenvalues and vectors by consuming this working memory.
73-
fn eval(
74-
self,
75-
a: &mut [Self::Elem],
76-
) -> Result<(
77-
Vec<<Self::Elem as Scalar>::Complex>,
78-
Option<Vec<<Self::Elem as Scalar>::Complex>>,
79-
)>;
81+
fn eval(self, a: &mut [Self::Elem]) -> Result<Eig<Self::Elem>>;
8082
}
8183

8284
impl EigWorkImpl for EigWork<c64> {
@@ -137,7 +139,7 @@ impl EigWorkImpl for EigWork<c64> {
137139
})
138140
}
139141

140-
fn calc<'work>(&'work mut self, a: &mut [c64]) -> Result<(&'work [c64], Option<&'work [c64]>)> {
142+
fn calc<'work>(&'work mut self, a: &mut [c64]) -> Result<EigRef<'work, c64>> {
141143
let lwork = self.work.len().to_i32().unwrap();
142144
let mut info = 0;
143145
unsafe {
@@ -173,15 +175,20 @@ impl EigWorkImpl for EigWork<c64> {
173175
value.im = -value.im;
174176
}
175177
}
176-
let v = match (self.vl.as_ref(), self.vr.as_ref()) {
177-
(Some(v), None) | (None, Some(v)) => Some(unsafe { v.slice_assume_init_ref() }),
178-
(None, None) => None,
179-
_ => unreachable!(),
180-
};
181-
Ok((eigs, v))
178+
Ok(EigRef {
179+
eigs,
180+
vl: self
181+
.vl
182+
.as_ref()
183+
.map(|v| unsafe { v.slice_assume_init_ref() }),
184+
vr: self
185+
.vr
186+
.as_ref()
187+
.map(|v| unsafe { v.slice_assume_init_ref() }),
188+
})
182189
}
183190

184-
fn eval(mut self, a: &mut [c64]) -> Result<(Vec<c64>, Option<Vec<c64>>)> {
191+
fn eval(mut self, a: &mut [c64]) -> Result<Eig<c64>> {
185192
let lwork = self.work.len().to_i32().unwrap();
186193
let mut info = 0;
187194
unsafe {
@@ -212,12 +219,11 @@ impl EigWorkImpl for EigWork<c64> {
212219
value.im = -value.im;
213220
}
214221
}
215-
let v = match (self.vl, self.vr) {
216-
(Some(v), None) | (None, Some(v)) => Some(unsafe { v.assume_init() }),
217-
(None, None) => None,
218-
_ => unreachable!(),
219-
};
220-
Ok((eigs, v))
222+
Ok(Eig {
223+
eigs,
224+
vl: self.vl.map(|v| unsafe { v.assume_init() }),
225+
vr: self.vr.map(|v| unsafe { v.assume_init() }),
226+
})
221227
}
222228
}
223229

0 commit comments

Comments
 (0)