Source code for psc_sim.compare_metrics

"""Metrics for comparing Python vs LTspice I–V curves."""

from __future__ import annotations

import numpy as np


[docs] def interpolate_current_at( v_grid: np.ndarray, v_samples: np.ndarray, i_samples: np.ndarray, ) -> np.ndarray: """Linear interpolation of I(V) onto v_grid; NaN outside sample range.""" v_grid = np.asarray(v_grid, dtype=float) v_samples = np.asarray(v_samples, dtype=float) i_samples = np.asarray(i_samples, dtype=float) ok = np.isfinite(v_samples) & np.isfinite(i_samples) if ok.sum() < 2: return np.full_like(v_grid, np.nan, dtype=float) order = np.argsort(v_samples[ok]) vs = v_samples[ok][order] is_ = i_samples[ok][order] return np.interp(v_grid, vs, is_, left=np.nan, right=np.nan)
[docs] def iv_curve_rmse( v_ref: np.ndarray, i_ref: np.ndarray, v_other: np.ndarray, i_other: np.ndarray, ) -> tuple[float, float]: """Return (rmse_A, max_abs_error_A) of i_other interpolated onto v_ref.""" i_interp = interpolate_current_at(v_ref, v_other, i_other) ok = np.isfinite(v_ref) & np.isfinite(i_ref) & np.isfinite(i_interp) if ok.sum() == 0: return float("nan"), float("nan") diff = i_ref[ok] - i_interp[ok] rmse = float(np.sqrt(np.mean(diff**2))) max_err = float(np.max(np.abs(diff))) return rmse, max_err
[docs] def eis_z_rmse( zre_a: np.ndarray, zim_a: np.ndarray, zre_b: np.ndarray, zim_b: np.ndarray, ) -> float: """RMSE on Re/Im components (same-length arrays).""" d = (zre_a - zre_b) ** 2 + (zim_a - zim_b) ** 2 return float(np.sqrt(np.mean(d)))
[docs] def eis_impedance_rmse( freq_ref: np.ndarray, zre_ref: np.ndarray, zim_ref: np.ndarray, freq_other: np.ndarray, zre_other: np.ndarray, zim_other: np.ndarray, ) -> float: """RMSE of complex impedance (Re/Im) with other interpolated onto freq_ref.""" zre_i = interpolate_current_at(freq_ref, freq_other, zre_other) zim_i = interpolate_current_at(freq_ref, freq_other, zim_other) ok = ( np.isfinite(freq_ref) & np.isfinite(zre_ref) & np.isfinite(zim_ref) & np.isfinite(zre_i) & np.isfinite(zim_i) ) if ok.sum() == 0: return float("nan") diff = np.hypot(zre_ref[ok] - zre_i[ok], zim_ref[ok] - zim_i[ok]) return float(np.sqrt(np.mean(diff**2)))