use mdarray::{Array, Dense, Dim, Layout, Slice};
use thiserror::Error;
#[derive(Debug, Error)]
pub enum EigError {
#[error("Backend error code: {0}")]
BackendError(i32),
#[error("Backend failed to converge: {iterations} iterations exceeded")]
BackendDidNotConverge { iterations: i32 },
#[error("Matrix must be square for eigenvalue decomposition")]
NotSquareMatrix,
}
pub struct EigDecomp<S, D0: Dim, D1: Dim> {
pub eigenvalues: Array<S, (D0,)>,
pub left_eigenvectors: Option<Array<S, (D0, D1)>>,
pub right_eigenvectors: Option<Array<S, (D0, D1)>>,
}
pub struct EighDecomp<T, R, D0: Dim, D1: Dim> {
pub eigenvalues: Array<R, (D0,)>,
pub eigenvectors: Array<T, (D0, D1)>,
}
#[derive(Debug, Error)]
pub enum SchurError {
#[error("Backend error code: {0}")]
BackendError(i32),
#[error("Backend failed to converge: {iterations} iterations exceeded")]
BackendDidNotConverge { iterations: i32 },
#[error("Matrix must be square for Schur decomposition")]
NotSquareMatrix,
}
pub struct SchurDecomp<T, D0: Dim, D1: Dim> {
pub t: Array<T, (D0, D1)>,
pub z: Array<T, (D0, D1)>,
}
pub trait Eig<T, D0: Dim, D1: Dim> {
type SpectralScalar;
type RealScalar;
fn eig<L: Layout>(
&self,
a: &mut Slice<T, (D0, D1), L>,
) -> Result<EigDecomp<Self::SpectralScalar, D0, D1>, EigError>;
fn eig_full<L: Layout>(
&self,
a: &mut Slice<T, (D0, D1), L>,
) -> Result<EigDecomp<Self::SpectralScalar, D0, D1>, EigError>;
fn eig_values<L: Layout>(
&self,
a: &mut Slice<T, (D0, D1), L>,
) -> Result<Array<Self::SpectralScalar, (D0,)>, EigError>;
fn eigh<L: Layout>(
&self,
a: &mut Slice<T, (D0, D1), L>,
) -> Result<EighDecomp<T, Self::RealScalar, D0, D1>, EigError>;
fn schur<L: Layout>(
&self,
a: &mut Slice<T, (D0, D1), L>,
) -> Result<SchurDecomp<T, D0, D1>, SchurError>;
fn schur_write<L: Layout>(
&self,
a: &mut Slice<T, (D0, D1), L>,
t: &mut Slice<T, (D0, D1), Dense>,
z: &mut Slice<T, (D0, D1), Dense>,
) -> Result<(), SchurError>;
fn schur_complex<L: Layout>(
&self,
a: &mut Slice<T, (D0, D1), L>,
) -> Result<SchurDecomp<Self::SpectralScalar, D0, D1>, SchurError>;
fn schur_complex_write<L: Layout>(
&self,
a: &mut Slice<T, (D0, D1), L>,
t: &mut Slice<Self::SpectralScalar, (D0, D1), Dense>,
z: &mut Slice<Self::SpectralScalar, (D0, D1), Dense>,
) -> Result<(), SchurError>;
}