use std::error::Error;
use algorithms_fixtures::dense_fixtures::{heisenberg_mpo_f64, random_mps_unknown_f64};
use ariadnetor_native::NativeBackend;
use crate::dmrg::heff::dmrg_2site_step;
use crate::dmrg::{DmrgHeffError, LocalEigensolverParams};
use crate::krylov::{ArpackError, ArpackParams};
use ariadnetor_linalg::TruncSvdParams;
use ariadnetor_mps::BraketEnvs;
#[test]
fn dmrg_arpack_max_iter_one_returns_arpack_error() {
let n = 4;
let chi = 4;
let mut psi = random_mps_unknown_f64(n, 2, chi, 0xCAFEBABE);
psi.canonicalize(&NativeBackend::new(), 0);
let mpo = heisenberg_mpo_f64(n, 1.0);
let mut envs = BraketEnvs::build(&psi, &mpo, &psi).expect("envs build");
envs.advance_left(&psi, &mpo, &psi, 0)
.expect("advance_left(0)");
let bad = LocalEigensolverParams::Arpack(ArpackParams {
tol: 1e-12,
max_iter: 1,
ncv: None,
});
let trunc = TruncSvdParams {
chi_max: None,
target_trunc_err: None,
};
let result = dmrg_2site_step(&envs, &psi, &mpo, 1, &bad, &trunc);
assert!(
matches!(
result,
Err(DmrgHeffError::Arpack(ArpackError::MaxIterReached { .. }))
),
"expected DmrgHeffError::Arpack(ArpackError::MaxIterReached), got {result:?}",
);
let err = result.expect_err("error path verified above");
let inner = match &err {
DmrgHeffError::Arpack(inner) => format!("{inner}"),
_ => unreachable!(),
};
let outer = format!("{err}");
assert!(
!outer.contains(&inner),
"DmrgHeffError::Arpack Display must stay self-layer, not embed the wrapped error: \
outer = {outer:?}, inner = {inner:?}",
);
let source = err
.source()
.expect("Arpack variant must expose its child via source()");
assert_eq!(
source.to_string(),
inner,
"source() must reach the ARPACK diagnostic unchanged",
);
}