|
| 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 | +
|
1 | 10 | use super::*; |
2 | 11 | use crate::{error::*, layout::MatrixLayout}; |
3 | 12 | use cauchy::*; |
4 | 13 | use num_traits::{ToPrimitive, Zero}; |
5 | 14 |
|
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 | | - |
26 | 15 | pub struct EighWork<T: Scalar> { |
27 | 16 | pub n: i32, |
28 | 17 | pub jobz: JobEv, |
@@ -199,78 +188,3 @@ macro_rules! impl_eigh_work_r { |
199 | 188 | } |
200 | 189 | impl_eigh_work_r!(f64, lapack_sys::dsyev_); |
201 | 190 | 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_); |
0 commit comments