1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
use lapack::c::{ssyev, dsyev, cheev, zheev};
use super::types::{Solution, EigenError};
use impl_prelude::*;
pub trait SymEigen: Sized {
type Eigenvalue;
type Solution;
fn compute_mut<D>(mat: &mut ArrayBase<D, Ix2>,
uplo: Symmetric,
with_vectors: bool)
-> Result<Array<Self::Eigenvalue, Ix1>, EigenError>
where D: DataMut<Elem = Self>;
fn compute_into<D>(mut mat: ArrayBase<D, Ix2>,
uplo: Symmetric)
-> Result<Array<Self::Eigenvalue, Ix1>, EigenError>
where D: DataMut<Elem = Self> + DataOwned<Elem = Self> {
Self::compute_mut(&mut mat, uplo, false)
}
fn compute<D>(mat: &ArrayBase<D, Ix2>,
uplo: Symmetric,
with_vectors: bool)
-> Result<Self::Solution, EigenError>
where D: Data<Elem = Self>;
}
macro_rules! impl_sym_eigen {
($impl_type:ident, $eigen_type:ident, $func:ident) => (
impl SymEigen for $impl_type {
type Eigenvalue = $eigen_type;
type Solution = Solution<Self, Self::Eigenvalue>;
fn compute_mut<D>(mat: &mut ArrayBase<D, Ix2>, uplo: Symmetric, with_vectors: bool) ->
Result<Array<Self::Eigenvalue, Ix1>, EigenError>
where D: DataMut<Elem=Self>
{
let dim = mat.dim();
if dim.0 != dim.1 {
return Err(EigenError::NotSquare);
}
let n = dim.0 as i32;
let (mut data_slice, layout, ld) = match slice_and_layout_mut(mat) {
Some(x) => x,
None => return Err(EigenError::BadLayout)
};
let mut values = Array::default(n as Ix);
let job = if with_vectors { b'V' } else { b'N' };
let info = $func(layout, job, uplo as u8, n, data_slice,
ld as i32, values.as_slice_mut().unwrap());
if info == 0 {
Ok(values)
} else if info < 0 {
Err(EigenError::IllegalParameter(-info))
} else {
Err(EigenError::Failed)
}
}
fn compute<D>(mat: &ArrayBase<D, Ix2>,
uplo: Symmetric,
with_vectors: bool) -> Result<Self::Solution, EigenError>
where D: Data<Elem=Self> {
let vec: Vec<Self> = mat.iter().cloned().collect();
let mut new_mat = Array::from_shape_vec(mat.dim(), vec).unwrap();
let r = Self::compute_mut(&mut new_mat, uplo, with_vectors);
r.map(|values| {
Solution {
values: values,
left_vectors: None,
right_vectors: if with_vectors { Some(new_mat) } else { None }
}
})
}
}
)
}
impl_sym_eigen!(f32, f32, ssyev);
impl_sym_eigen!(c32, f32, cheev);
impl_sym_eigen!(f64, f64, dsyev);
impl_sym_eigen!(c64, f64, zheev);
#[cfg(test)]
mod tests {}