lapack_traits/lapack/
heevx.rs

1use crate::Scalar;
2use lapacke::{Layout, ssyevx_work, dsyevx_work, zheevx_work, cheevx_work};
3use num_complex::Complex32 as c32;
4use num_complex::Complex64 as c64;
5
6pub trait Theevx: Scalar
7{
8    /// Symmetric/Hermitian eigenvalue problem - Expert drivers with work arrays
9    /// Binds to syevx for real scalars and to heevx for complex scalars
10    /// rwork is not used for syevx and may refer to an empty array
11    unsafe fn heevx(layout: Layout,
12                    jobz: u8,
13                    range: u8,
14                    uplo: u8,
15                    n: i32,
16                    a: &mut [Self],
17                    lda: i32,
18                    vl: Self::Real,
19                    vu: Self::Real,
20                    il: i32,
21                    iu: i32,
22                    abstol: Self::Real,
23                    m: &mut i32,
24                    w: &mut [Self::Real],
25                    z: &mut [Self],
26                    ldz: i32,
27                    work: &mut [Self],
28                    lwork: i32,
29                    rwork: &mut [Self::Real],
30                    iwork: &mut [i32],
31                    ifail: &mut [i32]) -> i32;
32
33    fn rwork_const() -> isize;
34}
35
36macro_rules! impl_he_evx (
37    ($N: ty, $heevx: path) => (
38        impl Theevx for $N {
39            #[inline]
40            unsafe fn heevx(layout: Layout, jobz: u8, range: u8, uplo: u8, n: i32, a: &mut [Self], lda: i32,
41                 vl: Self::Real, vu: Self::Real, il: i32, iu: i32,  abstol: Self::Real,
42                 m: &mut i32, w: &mut [Self::Real], z: &mut [Self], ldz: i32,
43                 work: &mut [Self], lwork: i32, rwork: &mut [Self::Real],  //Not used for real-symmetric routines
44                 iwork: &mut [i32], ifail: &mut [i32]) -> i32 {
45                    let info: i32 =
46                                $heevx( layout,
47                                        jobz, range, uplo, n, a, lda,
48                                        vl, vu, il, iu, abstol,
49                                        m, w, z, ldz,
50                                        work, lwork, rwork, iwork, ifail)
51                        ;
52                    info
53            }
54
55            fn rwork_const() -> isize {
56                7
57            }
58        }
59    )
60);
61
62macro_rules! impl_sy_evx (
63    ($N: ty, $syevx: path) => (
64        impl Theevx for $N {
65            #[inline]
66            unsafe fn heevx(layout: Layout, jobz: u8, range: u8, uplo: u8, n: i32, a: &mut [Self], lda: i32,
67                 vl: Self::Real, vu: Self::Real, il: i32, iu: i32,  abstol: Self::Real,
68                 m: &mut i32, w: &mut [Self::Real], z: &mut [Self], ldz: i32,
69                 work: &mut [Self], lwork: i32, _rwork: &mut [Self::Real],  //Not used for real-symmetric routines
70                 iwork: &mut [i32], ifail: &mut [i32]) -> i32 {
71                    let info: i32 =
72                                $syevx( layout,
73                                        jobz, range, uplo, n, a, lda,
74                                        vl, vu, il, iu, abstol,
75                                        m, w, z, ldz,
76                                        work, lwork, iwork, ifail)
77                        ;
78                    info
79            }
80            fn rwork_const() -> isize {
81                -1
82            }
83        }
84    )
85);
86
87impl_sy_evx!(f32, ssyevx_work);
88impl_sy_evx!(f64, dsyevx_work);
89impl_he_evx!(c32, cheevx_work);
90impl_he_evx!(c64, zheevx_work);