Skip to content

Commit 370c7d2

Browse files
committed
Merge Eigh_ into Lapack trait
1 parent 5d07538 commit 370c7d2

File tree

2 files changed

+29
-98
lines changed

2 files changed

+29
-98
lines changed

lax/src/eigh.rs

Lines changed: 9 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,17 @@
1+
//! Eigenvalue problem for symmetric/Hermite matricies
2+
//!
3+
//! LAPACK correspondance
4+
//! ----------------------
5+
//!
6+
//! | f32 | f64 | c32 | c64 |
7+
//! |:------|:------|:------|:------|
8+
//! | ssyev | dsyev | cheev | zheev |
9+
110
use super::*;
211
use crate::{error::*, layout::MatrixLayout};
312
use cauchy::*;
413
use num_traits::{ToPrimitive, Zero};
514

6-
#[cfg_attr(doc, katexit::katexit)]
7-
/// Eigenvalue problem for symmetric/hermite matrix
8-
pub trait Eigh_: Scalar {
9-
/// Compute right eigenvalue and eigenvectors $Ax = \lambda x$
10-
///
11-
/// LAPACK correspondance
12-
/// ----------------------
13-
///
14-
/// | f32 | f64 | c32 | c64 |
15-
/// |:------|:------|:------|:------|
16-
/// | ssyev | dsyev | cheev | zheev |
17-
///
18-
fn eigh(
19-
calc_eigenvec: bool,
20-
layout: MatrixLayout,
21-
uplo: UPLO,
22-
a: &mut [Self],
23-
) -> Result<Vec<Self::Real>>;
24-
}
25-
2615
pub struct EighWork<T: Scalar> {
2716
pub n: i32,
2817
pub jobz: JobEv,
@@ -199,78 +188,3 @@ macro_rules! impl_eigh_work_r {
199188
}
200189
impl_eigh_work_r!(f64, lapack_sys::dsyev_);
201190
impl_eigh_work_r!(f32, lapack_sys::ssyev_);
202-
203-
macro_rules! impl_eigh {
204-
(@real, $scalar:ty, $ev:path) => {
205-
impl_eigh!(@body, $scalar, $ev, );
206-
};
207-
(@complex, $scalar:ty, $ev:path) => {
208-
impl_eigh!(@body, $scalar, $ev, rwork);
209-
};
210-
(@body, $scalar:ty, $ev:path, $($rwork_ident:ident),*) => {
211-
impl Eigh_ for $scalar {
212-
fn eigh(
213-
calc_v: bool,
214-
layout: MatrixLayout,
215-
uplo: UPLO,
216-
a: &mut [Self],
217-
) -> Result<Vec<Self::Real>> {
218-
assert_eq!(layout.len(), layout.lda());
219-
let n = layout.len();
220-
let jobz = if calc_v { JobEv::All } else { JobEv::None };
221-
let mut eigs: Vec<MaybeUninit<Self::Real>> = vec_uninit(n as usize);
222-
223-
$(
224-
let mut $rwork_ident: Vec<MaybeUninit<Self::Real>> = vec_uninit(3 * n as usize - 2 as usize);
225-
)*
226-
227-
// calc work size
228-
let mut info = 0;
229-
let mut work_size = [Self::zero()];
230-
unsafe {
231-
$ev(
232-
jobz.as_ptr() ,
233-
uplo.as_ptr(),
234-
&n,
235-
AsPtr::as_mut_ptr(a),
236-
&n,
237-
AsPtr::as_mut_ptr(&mut eigs),
238-
AsPtr::as_mut_ptr(&mut work_size),
239-
&(-1),
240-
$(AsPtr::as_mut_ptr(&mut $rwork_ident),)*
241-
&mut info,
242-
);
243-
}
244-
info.as_lapack_result()?;
245-
246-
// actual ev
247-
let lwork = work_size[0].to_usize().unwrap();
248-
let mut work: Vec<MaybeUninit<Self>> = vec_uninit(lwork);
249-
let lwork = lwork as i32;
250-
unsafe {
251-
$ev(
252-
jobz.as_ptr(),
253-
uplo.as_ptr(),
254-
&n,
255-
AsPtr::as_mut_ptr(a),
256-
&n,
257-
AsPtr::as_mut_ptr(&mut eigs),
258-
AsPtr::as_mut_ptr(&mut work),
259-
&lwork,
260-
$(AsPtr::as_mut_ptr(&mut $rwork_ident),)*
261-
&mut info,
262-
);
263-
}
264-
info.as_lapack_result()?;
265-
266-
let eigs = unsafe { eigs.assume_init() };
267-
Ok(eigs)
268-
}
269-
}
270-
};
271-
} // impl_eigh!
272-
273-
impl_eigh!(@real, f64, lapack_sys::dsyev_);
274-
impl_eigh!(@real, f32, lapack_sys::ssyev_);
275-
impl_eigh!(@complex, c64, lapack_sys::zheev_);
276-
impl_eigh!(@complex, c32, lapack_sys::cheev_);

lax/src/lib.rs

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -131,25 +131,31 @@ pub trait Lapack:
131131
+ Solve_
132132
+ Solveh_
133133
+ Cholesky_
134-
+ Eigh_
135134
+ EighGeneralized_
136135
+ Triangular_
137136
+ Tridiagonal_
138137
+ Rcond_
139138
+ LeastSquaresSvdDivideConquer_
140139
{
141-
/// Compute right eigenvalue and eigenvectors
140+
/// Compute right eigenvalue and eigenvectors for a general matrix
142141
fn eig(
143142
calc_v: bool,
144143
l: MatrixLayout,
145144
a: &mut [Self],
146145
) -> Result<(Vec<Self::Complex>, Vec<Self::Complex>)>;
146+
147+
/// Compute right eigenvalue and eigenvectors for a symmetric or hermite matrix
148+
fn eigh(
149+
calc_eigenvec: bool,
150+
layout: MatrixLayout,
151+
uplo: UPLO,
152+
a: &mut [Self],
153+
) -> Result<Vec<Self::Real>>;
147154
}
148155

149156
macro_rules! impl_lapack {
150157
($s:ty) => {
151158
impl Lapack for $s {
152-
/// Compute right eigenvalue and eigenvectors
153159
fn eig(
154160
calc_v: bool,
155161
l: MatrixLayout,
@@ -160,6 +166,17 @@ macro_rules! impl_lapack {
160166
let EigOwned { eigs, vr, vl } = work.eval(a)?;
161167
Ok((eigs, vr.or(vl).unwrap_or_default()))
162168
}
169+
170+
fn eigh(
171+
calc_eigenvec: bool,
172+
layout: MatrixLayout,
173+
uplo: UPLO,
174+
a: &mut [Self],
175+
) -> Result<Vec<Self::Real>> {
176+
use eigh::*;
177+
let work = EighWork::<$s>::new(calc_eigenvec, layout)?;
178+
work.eval(uplo, a)
179+
}
163180
}
164181
};
165182
}

0 commit comments

Comments
 (0)