Skip to main content

use_eigen/
eigenspace.rs

1use crate::{EigenError, Eigenvalue, Eigenvector};
2
3/// The eigenspace associated with one eigenvalue.
4#[derive(Debug, Clone, PartialEq, Eq)]
5pub struct EigenSpace<T> {
6    value: Eigenvalue<T>,
7    basis: Vec<Eigenvector<T>>,
8}
9
10impl<T> EigenSpace<T> {
11    /// Creates a new eigenspace from an eigenvalue and basis vectors.
12    ///
13    /// # Errors
14    ///
15    /// Returns [`EigenError::EmptyEigenspace`] when `basis` is empty.
16    pub fn new(value: Eigenvalue<T>, basis: Vec<Eigenvector<T>>) -> Result<Self, EigenError> {
17        Self::try_new(value, basis)
18    }
19
20    /// Creates a new eigenspace from an eigenvalue and basis vectors.
21    ///
22    /// # Errors
23    ///
24    /// Returns [`EigenError::EmptyEigenspace`] when `basis` is empty.
25    pub fn try_new(value: Eigenvalue<T>, basis: Vec<Eigenvector<T>>) -> Result<Self, EigenError> {
26        if basis.is_empty() {
27            Err(EigenError::EmptyEigenspace)
28        } else {
29            Ok(Self { value, basis })
30        }
31    }
32
33    /// Returns the associated eigenvalue.
34    #[must_use]
35    pub const fn value(&self) -> &Eigenvalue<T> {
36        &self.value
37    }
38
39    /// Returns the basis vectors.
40    #[must_use]
41    pub fn basis(&self) -> &[Eigenvector<T>] {
42        &self.basis
43    }
44
45    /// Returns the stored eigenvalue and basis vectors.
46    #[must_use]
47    pub fn into_inner(self) -> (Eigenvalue<T>, Vec<Eigenvector<T>>) {
48        (self.value, self.basis)
49    }
50
51    /// Returns the number of basis vectors.
52    #[must_use]
53    pub const fn dimension(&self) -> usize {
54        self.basis.len()
55    }
56}
57
58#[cfg(test)]
59mod tests {
60    use super::EigenSpace;
61    use crate::{EigenError, Eigenvalue, Eigenvector};
62
63    #[test]
64    fn stores_an_eigenspace_basis() {
65        let space = EigenSpace::new(
66            Eigenvalue::new(4_i32),
67            vec![Eigenvector::new(vec![1_i32, 1]).expect("valid eigenvector")],
68        )
69        .expect("valid eigenspace");
70
71        assert_eq!(*space.value().as_ref(), 4);
72        assert_eq!(space.dimension(), 1);
73        assert_eq!(space.basis()[0].coordinates(), &[1, 1]);
74    }
75
76    #[test]
77    fn rejects_an_empty_basis() {
78        assert_eq!(
79            EigenSpace::<i32>::new(Eigenvalue::new(1_i32), vec![]),
80            Err(EigenError::EmptyEigenspace)
81        );
82    }
83}