use ariadnetor_linalg::LinalgError;
#[cfg(feature = "arpack")]
use crate::krylov::ArpackError;
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum DmrgHeffError {
#[error("two-site index {site} (with {site}+1) out of range for chain of length {n_sites}")]
InvalidSite {
site: usize,
n_sites: usize,
},
#[error(
"{side} env at index {index} is stale (None); build / advance envs into the right \
state before stepping"
)]
StaleEnv {
side: &'static str,
index: usize,
},
#[error("chain length mismatch: mps = {mps}, mpo = {mpo}, envs = {envs}")]
LengthMismatch {
mps: usize,
mpo: usize,
envs: usize,
},
#[error("invalid local-eigensolver params: {detail}")]
InvalidEigensolverParams {
detail: &'static str,
},
#[error("shape mismatch at site {site}, {field}: expected {expected}, got {actual}")]
ShapeMismatch {
site: usize,
field: &'static str,
expected: usize,
actual: usize,
},
#[error("QN mismatch at site {site}, {field}: {detail}")]
QnMismatch {
site: usize,
field: &'static str,
detail: String,
},
#[error("BlockSparse heff operand `{operand}` has layout order mismatch: {detail}")]
OrderMismatch {
operand: &'static str,
detail: String,
},
#[error("linalg failure during two-site DMRG step")]
Contract(#[from] LinalgError),
#[error("Lanczos failure during two-site DMRG step")]
Lanczos(#[from] crate::krylov::LanczosError),
#[cfg(feature = "arpack")]
#[error("ARPACK failure during two-site DMRG step")]
Arpack(#[from] ArpackError),
}
#[cfg(test)]
mod tests {
use super::*;
use crate::krylov::LanczosError;
#[test]
fn from_lanczos_error_preserves_payload_in_lanczos_variant() {
let err: DmrgHeffError = LanczosError::NonFinite {
iters: 7,
eigenvalue: f64::NAN,
residual: f64::INFINITY,
}
.into();
match err {
DmrgHeffError::Lanczos(LanczosError::NonFinite {
iters,
eigenvalue,
residual,
}) => {
assert_eq!(iters, 7);
assert!(eigenvalue.is_nan());
assert_eq!(residual, f64::INFINITY);
}
other => panic!("expected DmrgHeffError::Lanczos(NonFinite), got {other:?}"),
}
}
}