1use crate::{EigenError, Eigenpair};
2
3#[derive(Debug, Clone, PartialEq, Eq)]
5pub struct Eigensystem<T> {
6 pairs: Vec<Eigenpair<T>>,
7}
8
9impl<T> Eigensystem<T> {
10 pub fn new(pairs: Vec<Eigenpair<T>>) -> Result<Self, EigenError> {
16 Self::try_new(pairs)
17 }
18
19 pub fn try_new(pairs: Vec<Eigenpair<T>>) -> Result<Self, EigenError> {
25 if pairs.is_empty() {
26 Err(EigenError::EmptyEigensystem)
27 } else {
28 Ok(Self { pairs })
29 }
30 }
31
32 pub fn from_pairs(pairs: Vec<Eigenpair<T>>) -> Result<Self, EigenError> {
38 Self::try_new(pairs)
39 }
40
41 #[must_use]
43 pub fn pairs(&self) -> &[Eigenpair<T>] {
44 &self.pairs
45 }
46
47 #[must_use]
49 pub fn into_inner(self) -> Vec<Eigenpair<T>> {
50 self.pairs
51 }
52
53 #[must_use]
55 pub const fn len(&self) -> usize {
56 self.pairs.len()
57 }
58
59 #[must_use]
61 pub const fn is_empty(&self) -> bool {
62 self.pairs.is_empty()
63 }
64}
65
66impl<T> AsRef<[Eigenpair<T>]> for Eigensystem<T> {
67 fn as_ref(&self) -> &[Eigenpair<T>] {
68 self.pairs()
69 }
70}
71
72#[cfg(test)]
73mod tests {
74 use super::Eigensystem;
75 use crate::{EigenError, Eigenpair, Eigenvalue, Eigenvector};
76
77 #[test]
78 fn stores_multiple_eigenpairs() {
79 let pairs = vec![
80 Eigenpair::new(
81 Eigenvalue::new(2_i32),
82 Eigenvector::new(vec![1_i32, 0]).expect("valid eigenvector"),
83 ),
84 Eigenpair::new(
85 Eigenvalue::new(5_i32),
86 Eigenvector::new(vec![0_i32, 1]).expect("valid eigenvector"),
87 ),
88 ];
89
90 let system = Eigensystem::new(pairs).expect("valid eigensystem");
91
92 assert_eq!(system.len(), 2);
93 assert_eq!(*system.pairs()[0].value().as_ref(), 2);
94 assert_eq!(system.pairs()[1].vector().coordinates(), &[0, 1]);
95 }
96
97 #[test]
98 fn rejects_an_empty_eigensystem() {
99 assert_eq!(
100 Eigensystem::<i32>::new(vec![]),
101 Err(EigenError::EmptyEigensystem)
102 );
103 }
104}