use mdarray::{Array, Dim, Layout, Slice};
use thiserror::Error;
#[derive(Debug, Error)]
pub enum SVDError {
#[error("Backend error code: {0}")]
BackendError(i32),
#[error("Inconsistent U and VT: must be both Some or both None")]
InconsistentUV,
#[error("Backend failed to converge: {superdiagonals} superdiagonals did not converge to zero")]
BackendDidNotConverge { superdiagonals: i32 },
}
pub struct SVDDecomp<T, S, D: Dim> {
pub s: Array<S, (D,)>,
pub u: Array<T, (D, D)>,
pub vt: Array<T, (D, D)>,
}
pub trait SVD<T, D: Dim> {
type SingularValue;
fn svd<L: Layout>(
&self,
a: &mut Slice<T, (D, D), L>,
) -> Result<SVDDecomp<T, Self::SingularValue, D>, SVDError>;
fn svd_thin<L: Layout>(
&self,
a: &mut Slice<T, (D, D), L>,
) -> Result<SVDDecomp<T, Self::SingularValue, D>, SVDError>;
fn svd_s<L: Layout>(
&self,
a: &mut Slice<T, (D, D), L>,
) -> Result<Array<Self::SingularValue, (D,)>, SVDError>;
fn svd_write<L: Layout, Ls: Layout, Lu: Layout, Lvt: Layout>(
&self,
a: &mut Slice<T, (D, D), L>,
s: &mut Slice<Self::SingularValue, (D,), Ls>,
u: &mut Slice<T, (D, D), Lu>,
vt: &mut Slice<T, (D, D), Lvt>,
) -> Result<(), SVDError>;
fn svd_write_s<L: Layout, Ls: Layout>(
&self,
a: &mut Slice<T, (D, D), L>,
s: &mut Slice<Self::SingularValue, (D,), Ls>,
) -> Result<(), SVDError>;
}